2 function actionAddEntity(way) {
3 return function(graph) {
4 return graph.replace(way);
8 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
10 function commonjsRequire () {
11 throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
16 function createCommonjsModule(fn, module) {
17 return module = { exports: {} }, fn(module, module.exports), module.exports;
20 var lodash = createCommonjsModule(function (module, exports) {
23 * Lodash <https://lodash.com/>
24 * Copyright JS Foundation and other contributors <https://js.foundation/>
25 * Released under MIT license <https://lodash.com/license>
26 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
27 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
31 /** Used as a safe reference for `undefined` in pre-ES5 environments. */
34 /** Used as the semantic version number. */
35 var VERSION = '4.17.2';
37 /** Used as the size to enable large array optimizations. */
38 var LARGE_ARRAY_SIZE = 200;
40 /** Error message constants. */
41 var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
42 FUNC_ERROR_TEXT = 'Expected a function';
44 /** Used to stand-in for `undefined` hash values. */
45 var HASH_UNDEFINED = '__lodash_hash_undefined__';
47 /** Used as the maximum memoize cache size. */
48 var MAX_MEMOIZE_SIZE = 500;
50 /** Used as the internal argument placeholder. */
51 var PLACEHOLDER = '__lodash_placeholder__';
53 /** Used to compose bitmasks for cloning. */
54 var CLONE_DEEP_FLAG = 1,
56 CLONE_SYMBOLS_FLAG = 4;
58 /** Used to compose bitmasks for value comparisons. */
59 var COMPARE_PARTIAL_FLAG = 1,
60 COMPARE_UNORDERED_FLAG = 2;
62 /** Used to compose bitmasks for function metadata. */
63 var WRAP_BIND_FLAG = 1,
64 WRAP_BIND_KEY_FLAG = 2,
65 WRAP_CURRY_BOUND_FLAG = 4,
67 WRAP_CURRY_RIGHT_FLAG = 16,
68 WRAP_PARTIAL_FLAG = 32,
69 WRAP_PARTIAL_RIGHT_FLAG = 64,
71 WRAP_REARG_FLAG = 256,
74 /** Used as default options for `_.truncate`. */
75 var DEFAULT_TRUNC_LENGTH = 30,
76 DEFAULT_TRUNC_OMISSION = '...';
78 /** Used to detect hot functions by number of calls within a span of milliseconds. */
82 /** Used to indicate the type of lazy iteratees. */
83 var LAZY_FILTER_FLAG = 1,
87 /** Used as references for various `Number` constants. */
89 MAX_SAFE_INTEGER = 9007199254740991,
90 MAX_INTEGER = 1.7976931348623157e+308,
93 /** Used as references for the maximum length and index of an array. */
94 var MAX_ARRAY_LENGTH = 4294967295,
95 MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
96 HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
98 /** Used to associate wrap methods with their bit flags. */
100 ['ary', WRAP_ARY_FLAG],
101 ['bind', WRAP_BIND_FLAG],
102 ['bindKey', WRAP_BIND_KEY_FLAG],
103 ['curry', WRAP_CURRY_FLAG],
104 ['curryRight', WRAP_CURRY_RIGHT_FLAG],
105 ['flip', WRAP_FLIP_FLAG],
106 ['partial', WRAP_PARTIAL_FLAG],
107 ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
108 ['rearg', WRAP_REARG_FLAG]
111 /** `Object#toString` result references. */
112 var argsTag = '[object Arguments]',
113 arrayTag = '[object Array]',
114 asyncTag = '[object AsyncFunction]',
115 boolTag = '[object Boolean]',
116 dateTag = '[object Date]',
117 domExcTag = '[object DOMException]',
118 errorTag = '[object Error]',
119 funcTag = '[object Function]',
120 genTag = '[object GeneratorFunction]',
121 mapTag = '[object Map]',
122 numberTag = '[object Number]',
123 nullTag = '[object Null]',
124 objectTag = '[object Object]',
125 promiseTag = '[object Promise]',
126 proxyTag = '[object Proxy]',
127 regexpTag = '[object RegExp]',
128 setTag = '[object Set]',
129 stringTag = '[object String]',
130 symbolTag = '[object Symbol]',
131 undefinedTag = '[object Undefined]',
132 weakMapTag = '[object WeakMap]',
133 weakSetTag = '[object WeakSet]';
135 var arrayBufferTag = '[object ArrayBuffer]',
136 dataViewTag = '[object DataView]',
137 float32Tag = '[object Float32Array]',
138 float64Tag = '[object Float64Array]',
139 int8Tag = '[object Int8Array]',
140 int16Tag = '[object Int16Array]',
141 int32Tag = '[object Int32Array]',
142 uint8Tag = '[object Uint8Array]',
143 uint8ClampedTag = '[object Uint8ClampedArray]',
144 uint16Tag = '[object Uint16Array]',
145 uint32Tag = '[object Uint32Array]';
147 /** Used to match empty string literals in compiled template source. */
148 var reEmptyStringLeading = /\b__p \+= '';/g,
149 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
150 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
152 /** Used to match HTML entities and HTML characters. */
153 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
154 reUnescapedHtml = /[&<>"']/g,
155 reHasEscapedHtml = RegExp(reEscapedHtml.source),
156 reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
158 /** Used to match template delimiters. */
159 var reEscape = /<%-([\s\S]+?)%>/g,
160 reEvaluate = /<%([\s\S]+?)%>/g,
161 reInterpolate = /<%=([\s\S]+?)%>/g;
163 /** Used to match property names within property paths. */
164 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
165 reIsPlainProp = /^\w*$/,
166 reLeadingDot = /^\./,
167 rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
170 * Used to match `RegExp`
171 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
173 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
174 reHasRegExpChar = RegExp(reRegExpChar.source);
176 /** Used to match leading and trailing whitespace. */
177 var reTrim = /^\s+|\s+$/g,
178 reTrimStart = /^\s+/,
181 /** Used to match wrap detail comments. */
182 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
183 reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
184 reSplitDetails = /,? & /;
186 /** Used to match words composed of alphanumeric characters. */
187 var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
189 /** Used to match backslashes in property paths. */
190 var reEscapeChar = /\\(\\)?/g;
194 * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
196 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
198 /** Used to match `RegExp` flags from their coerced string values. */
199 var reFlags = /\w*$/;
201 /** Used to detect bad signed hexadecimal string values. */
202 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
204 /** Used to detect binary string values. */
205 var reIsBinary = /^0b[01]+$/i;
207 /** Used to detect host constructors (Safari). */
208 var reIsHostCtor = /^\[object .+?Constructor\]$/;
210 /** Used to detect octal string values. */
211 var reIsOctal = /^0o[0-7]+$/i;
213 /** Used to detect unsigned integer values. */
214 var reIsUint = /^(?:0|[1-9]\d*)$/;
216 /** Used to match Latin Unicode letters (excluding mathematical operators). */
217 var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
219 /** Used to ensure capturing order of template delimiters. */
220 var reNoMatch = /($^)/;
222 /** Used to match unescaped characters in compiled string literals. */
223 var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
225 /** Used to compose unicode character classes. */
226 var rsAstralRange = '\\ud800-\\udfff',
227 rsComboMarksRange = '\\u0300-\\u036f',
228 reComboHalfMarksRange = '\\ufe20-\\ufe2f',
229 rsComboSymbolsRange = '\\u20d0-\\u20ff',
230 rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
231 rsDingbatRange = '\\u2700-\\u27bf',
232 rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
233 rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
234 rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
235 rsPunctuationRange = '\\u2000-\\u206f',
236 rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
237 rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
238 rsVarRange = '\\ufe0e\\ufe0f',
239 rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
241 /** Used to compose unicode capture groups. */
242 var rsApos = "['\u2019]",
243 rsAstral = '[' + rsAstralRange + ']',
244 rsBreak = '[' + rsBreakRange + ']',
245 rsCombo = '[' + rsComboRange + ']',
247 rsDingbat = '[' + rsDingbatRange + ']',
248 rsLower = '[' + rsLowerRange + ']',
249 rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
250 rsFitz = '\\ud83c[\\udffb-\\udfff]',
251 rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
252 rsNonAstral = '[^' + rsAstralRange + ']',
253 rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
254 rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
255 rsUpper = '[' + rsUpperRange + ']',
258 /** Used to compose unicode regexes. */
259 var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
260 rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
261 rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
262 rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
263 reOptMod = rsModifier + '?',
264 rsOptVar = '[' + rsVarRange + ']?',
265 rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
266 rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
267 rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
268 rsSeq = rsOptVar + reOptMod + rsOptJoin,
269 rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
270 rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
272 /** Used to match apostrophes. */
273 var reApos = RegExp(rsApos, 'g');
276 * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
277 * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
279 var reComboMark = RegExp(rsCombo, 'g');
281 /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
282 var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
284 /** Used to match complex or compound words. */
285 var reUnicodeWord = RegExp([
286 rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
287 rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
288 rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
289 rsUpper + '+' + rsOptContrUpper,
296 /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
297 var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
299 /** Used to detect strings that need a more robust regexp to match words. */
300 var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
302 /** Used to assign default `context` object properties. */
304 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
305 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
306 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
307 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
308 '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
311 /** Used to make template sourceURLs easier to identify. */
312 var templateCounter = -1;
314 /** Used to identify `toStringTag` values of typed arrays. */
315 var typedArrayTags = {};
316 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
317 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
318 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
319 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
320 typedArrayTags[uint32Tag] = true;
321 typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
322 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
323 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
324 typedArrayTags[errorTag] = typedArrayTags[funcTag] =
325 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
326 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
327 typedArrayTags[setTag] = typedArrayTags[stringTag] =
328 typedArrayTags[weakMapTag] = false;
330 /** Used to identify `toStringTag` values supported by `_.clone`. */
331 var cloneableTags = {};
332 cloneableTags[argsTag] = cloneableTags[arrayTag] =
333 cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
334 cloneableTags[boolTag] = cloneableTags[dateTag] =
335 cloneableTags[float32Tag] = cloneableTags[float64Tag] =
336 cloneableTags[int8Tag] = cloneableTags[int16Tag] =
337 cloneableTags[int32Tag] = cloneableTags[mapTag] =
338 cloneableTags[numberTag] = cloneableTags[objectTag] =
339 cloneableTags[regexpTag] = cloneableTags[setTag] =
340 cloneableTags[stringTag] = cloneableTags[symbolTag] =
341 cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
342 cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
343 cloneableTags[errorTag] = cloneableTags[funcTag] =
344 cloneableTags[weakMapTag] = false;
346 /** Used to map Latin Unicode letters to basic Latin letters. */
347 var deburredLetters = {
348 // Latin-1 Supplement block.
349 '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
350 '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
351 '\xc7': 'C', '\xe7': 'c',
352 '\xd0': 'D', '\xf0': 'd',
353 '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
354 '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
355 '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
356 '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
357 '\xd1': 'N', '\xf1': 'n',
358 '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
359 '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
360 '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
361 '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
362 '\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
363 '\xc6': 'Ae', '\xe6': 'ae',
364 '\xde': 'Th', '\xfe': 'th',
366 // Latin Extended-A block.
367 '\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
368 '\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
369 '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
370 '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
371 '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
372 '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
373 '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
374 '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
375 '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
376 '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
377 '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
378 '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
379 '\u0134': 'J', '\u0135': 'j',
380 '\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
381 '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
382 '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
383 '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
384 '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
385 '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
386 '\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
387 '\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
388 '\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
389 '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
390 '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
391 '\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
392 '\u0163': 't', '\u0165': 't', '\u0167': 't',
393 '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
394 '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
395 '\u0174': 'W', '\u0175': 'w',
396 '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
397 '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
398 '\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
399 '\u0132': 'IJ', '\u0133': 'ij',
400 '\u0152': 'Oe', '\u0153': 'oe',
401 '\u0149': "'n", '\u017f': 's'
404 /** Used to map characters to HTML entities. */
413 /** Used to map HTML entities to characters. */
414 var htmlUnescapes = {
422 /** Used to escape characters for inclusion in compiled string literals. */
423 var stringEscapes = {
432 /** Built-in method references without a dependency on `root`. */
433 var freeParseFloat = parseFloat,
434 freeParseInt = parseInt;
436 /** Detect free variable `global` from Node.js. */
437 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
439 /** Detect free variable `self`. */
440 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
442 /** Used as a reference to the global object. */
443 var root = freeGlobal || freeSelf || Function('return this')();
445 /** Detect free variable `exports`. */
446 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
448 /** Detect free variable `module`. */
449 var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
451 /** Detect the popular CommonJS extension `module.exports`. */
452 var moduleExports = freeModule && freeModule.exports === freeExports;
454 /** Detect free variable `process` from Node.js. */
455 var freeProcess = moduleExports && freeGlobal.process;
457 /** Used to access faster Node.js helpers. */
458 var nodeUtil = (function() {
460 return freeProcess && freeProcess.binding && freeProcess.binding('util');
464 /* Node.js helper references. */
465 var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
466 nodeIsDate = nodeUtil && nodeUtil.isDate,
467 nodeIsMap = nodeUtil && nodeUtil.isMap,
468 nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
469 nodeIsSet = nodeUtil && nodeUtil.isSet,
470 nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
472 /*--------------------------------------------------------------------------*/
475 * Adds the key-value `pair` to `map`.
478 * @param {Object} map The map to modify.
479 * @param {Array} pair The key-value pair to add.
480 * @returns {Object} Returns `map`.
482 function addMapEntry(map, pair) {
483 // Don't return `map.set` because it's not chainable in IE 11.
484 map.set(pair[0], pair[1]);
489 * Adds `value` to `set`.
492 * @param {Object} set The set to modify.
493 * @param {*} value The value to add.
494 * @returns {Object} Returns `set`.
496 function addSetEntry(set, value) {
497 // Don't return `set.add` because it's not chainable in IE 11.
503 * A faster alternative to `Function#apply`, this function invokes `func`
504 * with the `this` binding of `thisArg` and the arguments of `args`.
507 * @param {Function} func The function to invoke.
508 * @param {*} thisArg The `this` binding of `func`.
509 * @param {Array} args The arguments to invoke `func` with.
510 * @returns {*} Returns the result of `func`.
512 function apply(func, thisArg, args) {
513 switch (args.length) {
514 case 0: return func.call(thisArg);
515 case 1: return func.call(thisArg, args[0]);
516 case 2: return func.call(thisArg, args[0], args[1]);
517 case 3: return func.call(thisArg, args[0], args[1], args[2]);
519 return func.apply(thisArg, args);
523 * A specialized version of `baseAggregator` for arrays.
526 * @param {Array} [array] The array to iterate over.
527 * @param {Function} setter The function to set `accumulator` values.
528 * @param {Function} iteratee The iteratee to transform keys.
529 * @param {Object} accumulator The initial aggregated object.
530 * @returns {Function} Returns `accumulator`.
532 function arrayAggregator(array, setter, iteratee, accumulator) {
534 length = array == null ? 0 : array.length;
536 while (++index < length) {
537 var value = array[index];
538 setter(accumulator, value, iteratee(value), array);
544 * A specialized version of `_.forEach` for arrays without support for
545 * iteratee shorthands.
548 * @param {Array} [array] The array to iterate over.
549 * @param {Function} iteratee The function invoked per iteration.
550 * @returns {Array} Returns `array`.
552 function arrayEach(array, iteratee) {
554 length = array == null ? 0 : array.length;
556 while (++index < length) {
557 if (iteratee(array[index], index, array) === false) {
565 * A specialized version of `_.forEachRight` for arrays without support for
566 * iteratee shorthands.
569 * @param {Array} [array] The array to iterate over.
570 * @param {Function} iteratee The function invoked per iteration.
571 * @returns {Array} Returns `array`.
573 function arrayEachRight(array, iteratee) {
574 var length = array == null ? 0 : array.length;
577 if (iteratee(array[length], length, array) === false) {
585 * A specialized version of `_.every` for arrays without support for
586 * iteratee shorthands.
589 * @param {Array} [array] The array to iterate over.
590 * @param {Function} predicate The function invoked per iteration.
591 * @returns {boolean} Returns `true` if all elements pass the predicate check,
594 function arrayEvery(array, predicate) {
596 length = array == null ? 0 : array.length;
598 while (++index < length) {
599 if (!predicate(array[index], index, array)) {
607 * A specialized version of `_.filter` for arrays without support for
608 * iteratee shorthands.
611 * @param {Array} [array] The array to iterate over.
612 * @param {Function} predicate The function invoked per iteration.
613 * @returns {Array} Returns the new filtered array.
615 function arrayFilter(array, predicate) {
617 length = array == null ? 0 : array.length,
621 while (++index < length) {
622 var value = array[index];
623 if (predicate(value, index, array)) {
624 result[resIndex++] = value;
631 * A specialized version of `_.includes` for arrays without support for
632 * specifying an index to search from.
635 * @param {Array} [array] The array to inspect.
636 * @param {*} target The value to search for.
637 * @returns {boolean} Returns `true` if `target` is found, else `false`.
639 function arrayIncludes(array, value) {
640 var length = array == null ? 0 : array.length;
641 return !!length && baseIndexOf(array, value, 0) > -1;
645 * This function is like `arrayIncludes` except that it accepts a comparator.
648 * @param {Array} [array] The array to inspect.
649 * @param {*} target The value to search for.
650 * @param {Function} comparator The comparator invoked per element.
651 * @returns {boolean} Returns `true` if `target` is found, else `false`.
653 function arrayIncludesWith(array, value, comparator) {
655 length = array == null ? 0 : array.length;
657 while (++index < length) {
658 if (comparator(value, array[index])) {
666 * A specialized version of `_.map` for arrays without support for iteratee
670 * @param {Array} [array] The array to iterate over.
671 * @param {Function} iteratee The function invoked per iteration.
672 * @returns {Array} Returns the new mapped array.
674 function arrayMap(array, iteratee) {
676 length = array == null ? 0 : array.length,
677 result = Array(length);
679 while (++index < length) {
680 result[index] = iteratee(array[index], index, array);
686 * Appends the elements of `values` to `array`.
689 * @param {Array} array The array to modify.
690 * @param {Array} values The values to append.
691 * @returns {Array} Returns `array`.
693 function arrayPush(array, values) {
695 length = values.length,
696 offset = array.length;
698 while (++index < length) {
699 array[offset + index] = values[index];
705 * A specialized version of `_.reduce` for arrays without support for
706 * iteratee shorthands.
709 * @param {Array} [array] The array to iterate over.
710 * @param {Function} iteratee The function invoked per iteration.
711 * @param {*} [accumulator] The initial value.
712 * @param {boolean} [initAccum] Specify using the first element of `array` as
714 * @returns {*} Returns the accumulated value.
716 function arrayReduce(array, iteratee, accumulator, initAccum) {
718 length = array == null ? 0 : array.length;
720 if (initAccum && length) {
721 accumulator = array[++index];
723 while (++index < length) {
724 accumulator = iteratee(accumulator, array[index], index, array);
730 * A specialized version of `_.reduceRight` for arrays without support for
731 * iteratee shorthands.
734 * @param {Array} [array] The array to iterate over.
735 * @param {Function} iteratee The function invoked per iteration.
736 * @param {*} [accumulator] The initial value.
737 * @param {boolean} [initAccum] Specify using the last element of `array` as
739 * @returns {*} Returns the accumulated value.
741 function arrayReduceRight(array, iteratee, accumulator, initAccum) {
742 var length = array == null ? 0 : array.length;
743 if (initAccum && length) {
744 accumulator = array[--length];
747 accumulator = iteratee(accumulator, array[length], length, array);
753 * A specialized version of `_.some` for arrays without support for iteratee
757 * @param {Array} [array] The array to iterate over.
758 * @param {Function} predicate The function invoked per iteration.
759 * @returns {boolean} Returns `true` if any element passes the predicate check,
762 function arraySome(array, predicate) {
764 length = array == null ? 0 : array.length;
766 while (++index < length) {
767 if (predicate(array[index], index, array)) {
775 * Gets the size of an ASCII `string`.
778 * @param {string} string The string inspect.
779 * @returns {number} Returns the string size.
781 var asciiSize = baseProperty('length');
784 * Converts an ASCII `string` to an array.
787 * @param {string} string The string to convert.
788 * @returns {Array} Returns the converted array.
790 function asciiToArray(string) {
791 return string.split('');
795 * Splits an ASCII `string` into an array of its words.
798 * @param {string} The string to inspect.
799 * @returns {Array} Returns the words of `string`.
801 function asciiWords(string) {
802 return string.match(reAsciiWord) || [];
806 * The base implementation of methods like `_.findKey` and `_.findLastKey`,
807 * without support for iteratee shorthands, which iterates over `collection`
811 * @param {Array|Object} collection The collection to inspect.
812 * @param {Function} predicate The function invoked per iteration.
813 * @param {Function} eachFunc The function to iterate over `collection`.
814 * @returns {*} Returns the found element or its key, else `undefined`.
816 function baseFindKey(collection, predicate, eachFunc) {
818 eachFunc(collection, function(value, key, collection) {
819 if (predicate(value, key, collection)) {
828 * The base implementation of `_.findIndex` and `_.findLastIndex` without
829 * support for iteratee shorthands.
832 * @param {Array} array The array to inspect.
833 * @param {Function} predicate The function invoked per iteration.
834 * @param {number} fromIndex The index to search from.
835 * @param {boolean} [fromRight] Specify iterating from right to left.
836 * @returns {number} Returns the index of the matched value, else `-1`.
838 function baseFindIndex(array, predicate, fromIndex, fromRight) {
839 var length = array.length,
840 index = fromIndex + (fromRight ? 1 : -1);
842 while ((fromRight ? index-- : ++index < length)) {
843 if (predicate(array[index], index, array)) {
851 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
854 * @param {Array} array The array to inspect.
855 * @param {*} value The value to search for.
856 * @param {number} fromIndex The index to search from.
857 * @returns {number} Returns the index of the matched value, else `-1`.
859 function baseIndexOf(array, value, fromIndex) {
860 return value === value
861 ? strictIndexOf(array, value, fromIndex)
862 : baseFindIndex(array, baseIsNaN, fromIndex);
866 * This function is like `baseIndexOf` except that it accepts a comparator.
869 * @param {Array} array The array to inspect.
870 * @param {*} value The value to search for.
871 * @param {number} fromIndex The index to search from.
872 * @param {Function} comparator The comparator invoked per element.
873 * @returns {number} Returns the index of the matched value, else `-1`.
875 function baseIndexOfWith(array, value, fromIndex, comparator) {
876 var index = fromIndex - 1,
877 length = array.length;
879 while (++index < length) {
880 if (comparator(array[index], value)) {
888 * The base implementation of `_.isNaN` without support for number objects.
891 * @param {*} value The value to check.
892 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
894 function baseIsNaN(value) {
895 return value !== value;
899 * The base implementation of `_.mean` and `_.meanBy` without support for
900 * iteratee shorthands.
903 * @param {Array} array The array to iterate over.
904 * @param {Function} iteratee The function invoked per iteration.
905 * @returns {number} Returns the mean.
907 function baseMean(array, iteratee) {
908 var length = array == null ? 0 : array.length;
909 return length ? (baseSum(array, iteratee) / length) : NAN;
913 * The base implementation of `_.property` without support for deep paths.
916 * @param {string} key The key of the property to get.
917 * @returns {Function} Returns the new accessor function.
919 function baseProperty(key) {
920 return function(object) {
921 return object == null ? undefined : object[key];
926 * The base implementation of `_.propertyOf` without support for deep paths.
929 * @param {Object} object The object to query.
930 * @returns {Function} Returns the new accessor function.
932 function basePropertyOf(object) {
933 return function(key) {
934 return object == null ? undefined : object[key];
939 * The base implementation of `_.reduce` and `_.reduceRight`, without support
940 * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
943 * @param {Array|Object} collection The collection to iterate over.
944 * @param {Function} iteratee The function invoked per iteration.
945 * @param {*} accumulator The initial value.
946 * @param {boolean} initAccum Specify using the first or last element of
947 * `collection` as the initial value.
948 * @param {Function} eachFunc The function to iterate over `collection`.
949 * @returns {*} Returns the accumulated value.
951 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
952 eachFunc(collection, function(value, index, collection) {
953 accumulator = initAccum
954 ? (initAccum = false, value)
955 : iteratee(accumulator, value, index, collection);
961 * The base implementation of `_.sortBy` which uses `comparer` to define the
962 * sort order of `array` and replaces criteria objects with their corresponding
966 * @param {Array} array The array to sort.
967 * @param {Function} comparer The function to define sort order.
968 * @returns {Array} Returns `array`.
970 function baseSortBy(array, comparer) {
971 var length = array.length;
973 array.sort(comparer);
975 array[length] = array[length].value;
981 * The base implementation of `_.sum` and `_.sumBy` without support for
982 * iteratee shorthands.
985 * @param {Array} array The array to iterate over.
986 * @param {Function} iteratee The function invoked per iteration.
987 * @returns {number} Returns the sum.
989 function baseSum(array, iteratee) {
992 length = array.length;
994 while (++index < length) {
995 var current = iteratee(array[index]);
996 if (current !== undefined) {
997 result = result === undefined ? current : (result + current);
1004 * The base implementation of `_.times` without support for iteratee shorthands
1005 * or max array length checks.
1008 * @param {number} n The number of times to invoke `iteratee`.
1009 * @param {Function} iteratee The function invoked per iteration.
1010 * @returns {Array} Returns the array of results.
1012 function baseTimes(n, iteratee) {
1016 while (++index < n) {
1017 result[index] = iteratee(index);
1023 * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
1024 * of key-value pairs for `object` corresponding to the property names of `props`.
1027 * @param {Object} object The object to query.
1028 * @param {Array} props The property names to get values for.
1029 * @returns {Object} Returns the key-value pairs.
1031 function baseToPairs(object, props) {
1032 return arrayMap(props, function(key) {
1033 return [key, object[key]];
1038 * The base implementation of `_.unary` without support for storing metadata.
1041 * @param {Function} func The function to cap arguments for.
1042 * @returns {Function} Returns the new capped function.
1044 function baseUnary(func) {
1045 return function(value) {
1051 * The base implementation of `_.values` and `_.valuesIn` which creates an
1052 * array of `object` property values corresponding to the property names
1056 * @param {Object} object The object to query.
1057 * @param {Array} props The property names to get values for.
1058 * @returns {Object} Returns the array of property values.
1060 function baseValues(object, props) {
1061 return arrayMap(props, function(key) {
1067 * Checks if a `cache` value for `key` exists.
1070 * @param {Object} cache The cache to query.
1071 * @param {string} key The key of the entry to check.
1072 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1074 function cacheHas(cache, key) {
1075 return cache.has(key);
1079 * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
1080 * that is not found in the character symbols.
1083 * @param {Array} strSymbols The string symbols to inspect.
1084 * @param {Array} chrSymbols The character symbols to find.
1085 * @returns {number} Returns the index of the first unmatched string symbol.
1087 function charsStartIndex(strSymbols, chrSymbols) {
1089 length = strSymbols.length;
1091 while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1096 * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
1097 * that is not found in the character symbols.
1100 * @param {Array} strSymbols The string symbols to inspect.
1101 * @param {Array} chrSymbols The character symbols to find.
1102 * @returns {number} Returns the index of the last unmatched string symbol.
1104 function charsEndIndex(strSymbols, chrSymbols) {
1105 var index = strSymbols.length;
1107 while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1112 * Gets the number of `placeholder` occurrences in `array`.
1115 * @param {Array} array The array to inspect.
1116 * @param {*} placeholder The placeholder to search for.
1117 * @returns {number} Returns the placeholder count.
1119 function countHolders(array, placeholder) {
1120 var length = array.length,
1124 if (array[length] === placeholder) {
1132 * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
1133 * letters to basic Latin letters.
1136 * @param {string} letter The matched letter to deburr.
1137 * @returns {string} Returns the deburred letter.
1139 var deburrLetter = basePropertyOf(deburredLetters);
1142 * Used by `_.escape` to convert characters to HTML entities.
1145 * @param {string} chr The matched character to escape.
1146 * @returns {string} Returns the escaped character.
1148 var escapeHtmlChar = basePropertyOf(htmlEscapes);
1151 * Used by `_.template` to escape characters for inclusion in compiled string literals.
1154 * @param {string} chr The matched character to escape.
1155 * @returns {string} Returns the escaped character.
1157 function escapeStringChar(chr) {
1158 return '\\' + stringEscapes[chr];
1162 * Gets the value at `key` of `object`.
1165 * @param {Object} [object] The object to query.
1166 * @param {string} key The key of the property to get.
1167 * @returns {*} Returns the property value.
1169 function getValue(object, key) {
1170 return object == null ? undefined : object[key];
1174 * Checks if `string` contains Unicode symbols.
1177 * @param {string} string The string to inspect.
1178 * @returns {boolean} Returns `true` if a symbol is found, else `false`.
1180 function hasUnicode(string) {
1181 return reHasUnicode.test(string);
1185 * Checks if `string` contains a word composed of Unicode symbols.
1188 * @param {string} string The string to inspect.
1189 * @returns {boolean} Returns `true` if a word is found, else `false`.
1191 function hasUnicodeWord(string) {
1192 return reHasUnicodeWord.test(string);
1196 * Converts `iterator` to an array.
1199 * @param {Object} iterator The iterator to convert.
1200 * @returns {Array} Returns the converted array.
1202 function iteratorToArray(iterator) {
1206 while (!(data = iterator.next()).done) {
1207 result.push(data.value);
1213 * Converts `map` to its key-value pairs.
1216 * @param {Object} map The map to convert.
1217 * @returns {Array} Returns the key-value pairs.
1219 function mapToArray(map) {
1221 result = Array(map.size);
1223 map.forEach(function(value, key) {
1224 result[++index] = [key, value];
1230 * Creates a unary function that invokes `func` with its argument transformed.
1233 * @param {Function} func The function to wrap.
1234 * @param {Function} transform The argument transform.
1235 * @returns {Function} Returns the new function.
1237 function overArg(func, transform) {
1238 return function(arg) {
1239 return func(transform(arg));
1244 * Replaces all `placeholder` elements in `array` with an internal placeholder
1245 * and returns an array of their indexes.
1248 * @param {Array} array The array to modify.
1249 * @param {*} placeholder The placeholder to replace.
1250 * @returns {Array} Returns the new array of placeholder indexes.
1252 function replaceHolders(array, placeholder) {
1254 length = array.length,
1258 while (++index < length) {
1259 var value = array[index];
1260 if (value === placeholder || value === PLACEHOLDER) {
1261 array[index] = PLACEHOLDER;
1262 result[resIndex++] = index;
1269 * Converts `set` to an array of its values.
1272 * @param {Object} set The set to convert.
1273 * @returns {Array} Returns the values.
1275 function setToArray(set) {
1277 result = Array(set.size);
1279 set.forEach(function(value) {
1280 result[++index] = value;
1286 * Converts `set` to its value-value pairs.
1289 * @param {Object} set The set to convert.
1290 * @returns {Array} Returns the value-value pairs.
1292 function setToPairs(set) {
1294 result = Array(set.size);
1296 set.forEach(function(value) {
1297 result[++index] = [value, value];
1303 * A specialized version of `_.indexOf` which performs strict equality
1304 * comparisons of values, i.e. `===`.
1307 * @param {Array} array The array to inspect.
1308 * @param {*} value The value to search for.
1309 * @param {number} fromIndex The index to search from.
1310 * @returns {number} Returns the index of the matched value, else `-1`.
1312 function strictIndexOf(array, value, fromIndex) {
1313 var index = fromIndex - 1,
1314 length = array.length;
1316 while (++index < length) {
1317 if (array[index] === value) {
1325 * A specialized version of `_.lastIndexOf` which performs strict equality
1326 * comparisons of values, i.e. `===`.
1329 * @param {Array} array The array to inspect.
1330 * @param {*} value The value to search for.
1331 * @param {number} fromIndex The index to search from.
1332 * @returns {number} Returns the index of the matched value, else `-1`.
1334 function strictLastIndexOf(array, value, fromIndex) {
1335 var index = fromIndex + 1;
1337 if (array[index] === value) {
1345 * Gets the number of symbols in `string`.
1348 * @param {string} string The string to inspect.
1349 * @returns {number} Returns the string size.
1351 function stringSize(string) {
1352 return hasUnicode(string)
1353 ? unicodeSize(string)
1354 : asciiSize(string);
1358 * Converts `string` to an array.
1361 * @param {string} string The string to convert.
1362 * @returns {Array} Returns the converted array.
1364 function stringToArray(string) {
1365 return hasUnicode(string)
1366 ? unicodeToArray(string)
1367 : asciiToArray(string);
1371 * Used by `_.unescape` to convert HTML entities to characters.
1374 * @param {string} chr The matched character to unescape.
1375 * @returns {string} Returns the unescaped character.
1377 var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
1380 * Gets the size of a Unicode `string`.
1383 * @param {string} string The string inspect.
1384 * @returns {number} Returns the string size.
1386 function unicodeSize(string) {
1387 var result = reUnicode.lastIndex = 0;
1388 while (reUnicode.test(string)) {
1395 * Converts a Unicode `string` to an array.
1398 * @param {string} string The string to convert.
1399 * @returns {Array} Returns the converted array.
1401 function unicodeToArray(string) {
1402 return string.match(reUnicode) || [];
1406 * Splits a Unicode `string` into an array of its words.
1409 * @param {string} The string to inspect.
1410 * @returns {Array} Returns the words of `string`.
1412 function unicodeWords(string) {
1413 return string.match(reUnicodeWord) || [];
1416 /*--------------------------------------------------------------------------*/
1419 * Create a new pristine `lodash` function using the `context` object.
1425 * @param {Object} [context=root] The context object.
1426 * @returns {Function} Returns a new `lodash` function.
1429 * _.mixin({ 'foo': _.constant('foo') });
1431 * var lodash = _.runInContext();
1432 * lodash.mixin({ 'bar': lodash.constant('bar') });
1434 * _.isFunction(_.foo);
1436 * _.isFunction(_.bar);
1439 * lodash.isFunction(lodash.foo);
1441 * lodash.isFunction(lodash.bar);
1444 * // Create a suped-up `defer` in Node.js.
1445 * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1447 var runInContext = (function runInContext(context) {
1448 context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
1450 /** Built-in constructor references. */
1451 var Array = context.Array,
1452 Date = context.Date,
1453 Error = context.Error,
1454 Function = context.Function,
1455 Math = context.Math,
1456 Object = context.Object,
1457 RegExp = context.RegExp,
1458 String = context.String,
1459 TypeError = context.TypeError;
1461 /** Used for built-in method references. */
1462 var arrayProto = Array.prototype,
1463 funcProto = Function.prototype,
1464 objectProto = Object.prototype;
1466 /** Used to detect overreaching core-js shims. */
1467 var coreJsData = context['__core-js_shared__'];
1469 /** Used to resolve the decompiled source of functions. */
1470 var funcToString = funcProto.toString;
1472 /** Used to check objects for own properties. */
1473 var hasOwnProperty = objectProto.hasOwnProperty;
1475 /** Used to generate unique IDs. */
1478 /** Used to detect methods masquerading as native. */
1479 var maskSrcKey = (function() {
1480 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1481 return uid ? ('Symbol(src)_1.' + uid) : '';
1485 * Used to resolve the
1486 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
1489 var nativeObjectToString = objectProto.toString;
1491 /** Used to infer the `Object` constructor. */
1492 var objectCtorString = funcToString.call(Object);
1494 /** Used to restore the original `_` reference in `_.noConflict`. */
1495 var oldDash = root._;
1497 /** Used to detect if a method is native. */
1498 var reIsNative = RegExp('^' +
1499 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1500 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1503 /** Built-in value references. */
1504 var Buffer = moduleExports ? context.Buffer : undefined,
1505 Symbol = context.Symbol,
1506 Uint8Array = context.Uint8Array,
1507 allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
1508 getPrototype = overArg(Object.getPrototypeOf, Object),
1509 objectCreate = Object.create,
1510 propertyIsEnumerable = objectProto.propertyIsEnumerable,
1511 splice = arrayProto.splice,
1512 spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
1513 symIterator = Symbol ? Symbol.iterator : undefined,
1514 symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1516 var defineProperty = (function() {
1518 var func = getNative(Object, 'defineProperty');
1524 /** Mocked built-ins. */
1525 var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
1526 ctxNow = Date && Date.now !== root.Date.now && Date.now,
1527 ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
1529 /* Built-in method references for those with the same name as other `lodash` methods. */
1530 var nativeCeil = Math.ceil,
1531 nativeFloor = Math.floor,
1532 nativeGetSymbols = Object.getOwnPropertySymbols,
1533 nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
1534 nativeIsFinite = context.isFinite,
1535 nativeJoin = arrayProto.join,
1536 nativeKeys = overArg(Object.keys, Object),
1537 nativeMax = Math.max,
1538 nativeMin = Math.min,
1539 nativeNow = Date.now,
1540 nativeParseInt = context.parseInt,
1541 nativeRandom = Math.random,
1542 nativeReverse = arrayProto.reverse;
1544 /* Built-in method references that are verified to be native. */
1545 var DataView = getNative(context, 'DataView'),
1546 Map = getNative(context, 'Map'),
1547 Promise = getNative(context, 'Promise'),
1548 Set = getNative(context, 'Set'),
1549 WeakMap = getNative(context, 'WeakMap'),
1550 nativeCreate = getNative(Object, 'create');
1552 /** Used to store function metadata. */
1553 var metaMap = WeakMap && new WeakMap;
1555 /** Used to lookup unminified function names. */
1558 /** Used to detect maps, sets, and weakmaps. */
1559 var dataViewCtorString = toSource(DataView),
1560 mapCtorString = toSource(Map),
1561 promiseCtorString = toSource(Promise),
1562 setCtorString = toSource(Set),
1563 weakMapCtorString = toSource(WeakMap);
1565 /** Used to convert symbols to primitives and strings. */
1566 var symbolProto = Symbol ? Symbol.prototype : undefined,
1567 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1568 symbolToString = symbolProto ? symbolProto.toString : undefined;
1570 /*------------------------------------------------------------------------*/
1573 * Creates a `lodash` object which wraps `value` to enable implicit method
1574 * chain sequences. Methods that operate on and return arrays, collections,
1575 * and functions can be chained together. Methods that retrieve a single value
1576 * or may return a primitive value will automatically end the chain sequence
1577 * and return the unwrapped value. Otherwise, the value must be unwrapped
1580 * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1581 * enabled using `_.chain`.
1583 * The execution of chained methods is lazy, that is, it's deferred until
1584 * `_#value` is implicitly or explicitly called.
1586 * Lazy evaluation allows several methods to support shortcut fusion.
1587 * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1588 * the creation of intermediate arrays and can greatly reduce the number of
1589 * iteratee executions. Sections of a chain sequence qualify for shortcut
1590 * fusion if the section is applied to an array of at least `200` elements
1591 * and any iteratees accept only one argument. The heuristic for whether a
1592 * section qualifies for shortcut fusion is subject to change.
1594 * Chaining is supported in custom builds as long as the `_#value` method is
1595 * directly or indirectly included in the build.
1597 * In addition to lodash methods, wrappers have `Array` and `String` methods.
1599 * The wrapper `Array` methods are:
1600 * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1602 * The wrapper `String` methods are:
1603 * `replace` and `split`
1605 * The wrapper methods that support shortcut fusion are:
1606 * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1607 * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1608 * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1610 * The chainable wrapper methods are:
1611 * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1612 * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1613 * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1614 * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1615 * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1616 * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1617 * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1618 * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1619 * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1620 * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1621 * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1622 * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1623 * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1624 * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1625 * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1626 * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1627 * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1628 * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1629 * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1630 * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1631 * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1632 * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1633 * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1634 * `zipObject`, `zipObjectDeep`, and `zipWith`
1636 * The wrapper methods that are **not** chainable by default are:
1637 * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1638 * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
1639 * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
1640 * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1641 * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
1642 * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1643 * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1644 * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
1645 * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
1646 * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
1647 * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
1648 * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
1649 * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
1650 * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
1651 * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
1652 * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
1653 * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
1654 * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
1655 * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
1656 * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
1657 * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
1658 * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
1659 * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
1660 * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
1661 * `upperFirst`, `value`, and `words`
1666 * @param {*} value The value to wrap in a `lodash` instance.
1667 * @returns {Object} Returns the new `lodash` wrapper instance.
1670 * function square(n) {
1674 * var wrapped = _([1, 2, 3]);
1676 * // Returns an unwrapped value.
1677 * wrapped.reduce(_.add);
1680 * // Returns a wrapped value.
1681 * var squares = wrapped.map(square);
1683 * _.isArray(squares);
1686 * _.isArray(squares.value());
1689 function lodash(value) {
1690 if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1691 if (value instanceof LodashWrapper) {
1694 if (hasOwnProperty.call(value, '__wrapped__')) {
1695 return wrapperClone(value);
1698 return new LodashWrapper(value);
1702 * The base implementation of `_.create` without support for assigning
1703 * properties to the created object.
1706 * @param {Object} proto The object to inherit from.
1707 * @returns {Object} Returns the new object.
1709 var baseCreate = (function() {
1710 function object() {}
1711 return function(proto) {
1712 if (!isObject(proto)) {
1716 return objectCreate(proto);
1718 object.prototype = proto;
1719 var result = new object;
1720 object.prototype = undefined;
1726 * The function whose prototype chain sequence wrappers inherit from.
1730 function baseLodash() {
1731 // No operation performed.
1735 * The base constructor for creating `lodash` wrapper objects.
1738 * @param {*} value The value to wrap.
1739 * @param {boolean} [chainAll] Enable explicit method chain sequences.
1741 function LodashWrapper(value, chainAll) {
1742 this.__wrapped__ = value;
1743 this.__actions__ = [];
1744 this.__chain__ = !!chainAll;
1746 this.__values__ = undefined;
1750 * By default, the template delimiters used by lodash are like those in
1751 * embedded Ruby (ERB). Change the following template settings to use
1752 * alternative delimiters.
1758 lodash.templateSettings = {
1761 * Used to detect `data` property values to be HTML-escaped.
1763 * @memberOf _.templateSettings
1769 * Used to detect code to be evaluated.
1771 * @memberOf _.templateSettings
1774 'evaluate': reEvaluate,
1777 * Used to detect `data` property values to inject.
1779 * @memberOf _.templateSettings
1782 'interpolate': reInterpolate,
1785 * Used to reference the data object in the template text.
1787 * @memberOf _.templateSettings
1793 * Used to import variables into the compiled template.
1795 * @memberOf _.templateSettings
1801 * A reference to the `lodash` function.
1803 * @memberOf _.templateSettings.imports
1810 // Ensure wrappers are instances of `baseLodash`.
1811 lodash.prototype = baseLodash.prototype;
1812 lodash.prototype.constructor = lodash;
1814 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1815 LodashWrapper.prototype.constructor = LodashWrapper;
1817 /*------------------------------------------------------------------------*/
1820 * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1824 * @param {*} value The value to wrap.
1826 function LazyWrapper(value) {
1827 this.__wrapped__ = value;
1828 this.__actions__ = [];
1830 this.__filtered__ = false;
1831 this.__iteratees__ = [];
1832 this.__takeCount__ = MAX_ARRAY_LENGTH;
1833 this.__views__ = [];
1837 * Creates a clone of the lazy wrapper object.
1841 * @memberOf LazyWrapper
1842 * @returns {Object} Returns the cloned `LazyWrapper` object.
1844 function lazyClone() {
1845 var result = new LazyWrapper(this.__wrapped__);
1846 result.__actions__ = copyArray(this.__actions__);
1847 result.__dir__ = this.__dir__;
1848 result.__filtered__ = this.__filtered__;
1849 result.__iteratees__ = copyArray(this.__iteratees__);
1850 result.__takeCount__ = this.__takeCount__;
1851 result.__views__ = copyArray(this.__views__);
1856 * Reverses the direction of lazy iteration.
1860 * @memberOf LazyWrapper
1861 * @returns {Object} Returns the new reversed `LazyWrapper` object.
1863 function lazyReverse() {
1864 if (this.__filtered__) {
1865 var result = new LazyWrapper(this);
1866 result.__dir__ = -1;
1867 result.__filtered__ = true;
1869 result = this.clone();
1870 result.__dir__ *= -1;
1876 * Extracts the unwrapped value from its lazy wrapper.
1880 * @memberOf LazyWrapper
1881 * @returns {*} Returns the unwrapped value.
1883 function lazyValue() {
1884 var array = this.__wrapped__.value(),
1886 isArr = isArray(array),
1888 arrLength = isArr ? array.length : 0,
1889 view = getView(0, arrLength, this.__views__),
1892 length = end - start,
1893 index = isRight ? end : (start - 1),
1894 iteratees = this.__iteratees__,
1895 iterLength = iteratees.length,
1897 takeCount = nativeMin(length, this.__takeCount__);
1899 if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
1900 (arrLength == length && takeCount == length)) {
1901 return baseWrapperValue(array, this.__actions__);
1906 while (length-- && resIndex < takeCount) {
1910 value = array[index];
1912 while (++iterIndex < iterLength) {
1913 var data = iteratees[iterIndex],
1914 iteratee = data.iteratee,
1916 computed = iteratee(value);
1918 if (type == LAZY_MAP_FLAG) {
1920 } else if (!computed) {
1921 if (type == LAZY_FILTER_FLAG) {
1928 result[resIndex++] = value;
1933 // Ensure `LazyWrapper` is an instance of `baseLodash`.
1934 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1935 LazyWrapper.prototype.constructor = LazyWrapper;
1937 /*------------------------------------------------------------------------*/
1940 * Creates a hash object.
1944 * @param {Array} [entries] The key-value pairs to cache.
1946 function Hash(entries) {
1948 length = entries == null ? 0 : entries.length;
1951 while (++index < length) {
1952 var entry = entries[index];
1953 this.set(entry[0], entry[1]);
1958 * Removes all key-value entries from the hash.
1964 function hashClear() {
1965 this.__data__ = nativeCreate ? nativeCreate(null) : {};
1970 * Removes `key` and its value from the hash.
1975 * @param {Object} hash The hash to modify.
1976 * @param {string} key The key of the value to remove.
1977 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1979 function hashDelete(key) {
1980 var result = this.has(key) && delete this.__data__[key];
1981 this.size -= result ? 1 : 0;
1986 * Gets the hash value for `key`.
1991 * @param {string} key The key of the value to get.
1992 * @returns {*} Returns the entry value.
1994 function hashGet(key) {
1995 var data = this.__data__;
1997 var result = data[key];
1998 return result === HASH_UNDEFINED ? undefined : result;
2000 return hasOwnProperty.call(data, key) ? data[key] : undefined;
2004 * Checks if a hash value for `key` exists.
2009 * @param {string} key The key of the entry to check.
2010 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2012 function hashHas(key) {
2013 var data = this.__data__;
2014 return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
2018 * Sets the hash `key` to `value`.
2023 * @param {string} key The key of the value to set.
2024 * @param {*} value The value to set.
2025 * @returns {Object} Returns the hash instance.
2027 function hashSet(key, value) {
2028 var data = this.__data__;
2029 this.size += this.has(key) ? 0 : 1;
2030 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
2034 // Add methods to `Hash`.
2035 Hash.prototype.clear = hashClear;
2036 Hash.prototype['delete'] = hashDelete;
2037 Hash.prototype.get = hashGet;
2038 Hash.prototype.has = hashHas;
2039 Hash.prototype.set = hashSet;
2041 /*------------------------------------------------------------------------*/
2044 * Creates an list cache object.
2048 * @param {Array} [entries] The key-value pairs to cache.
2050 function ListCache(entries) {
2052 length = entries == null ? 0 : entries.length;
2055 while (++index < length) {
2056 var entry = entries[index];
2057 this.set(entry[0], entry[1]);
2062 * Removes all key-value entries from the list cache.
2066 * @memberOf ListCache
2068 function listCacheClear() {
2074 * Removes `key` and its value from the list cache.
2078 * @memberOf ListCache
2079 * @param {string} key The key of the value to remove.
2080 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2082 function listCacheDelete(key) {
2083 var data = this.__data__,
2084 index = assocIndexOf(data, key);
2089 var lastIndex = data.length - 1;
2090 if (index == lastIndex) {
2093 splice.call(data, index, 1);
2100 * Gets the list cache value for `key`.
2104 * @memberOf ListCache
2105 * @param {string} key The key of the value to get.
2106 * @returns {*} Returns the entry value.
2108 function listCacheGet(key) {
2109 var data = this.__data__,
2110 index = assocIndexOf(data, key);
2112 return index < 0 ? undefined : data[index][1];
2116 * Checks if a list cache value for `key` exists.
2120 * @memberOf ListCache
2121 * @param {string} key The key of the entry to check.
2122 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2124 function listCacheHas(key) {
2125 return assocIndexOf(this.__data__, key) > -1;
2129 * Sets the list cache `key` to `value`.
2133 * @memberOf ListCache
2134 * @param {string} key The key of the value to set.
2135 * @param {*} value The value to set.
2136 * @returns {Object} Returns the list cache instance.
2138 function listCacheSet(key, value) {
2139 var data = this.__data__,
2140 index = assocIndexOf(data, key);
2144 data.push([key, value]);
2146 data[index][1] = value;
2151 // Add methods to `ListCache`.
2152 ListCache.prototype.clear = listCacheClear;
2153 ListCache.prototype['delete'] = listCacheDelete;
2154 ListCache.prototype.get = listCacheGet;
2155 ListCache.prototype.has = listCacheHas;
2156 ListCache.prototype.set = listCacheSet;
2158 /*------------------------------------------------------------------------*/
2161 * Creates a map cache object to store key-value pairs.
2165 * @param {Array} [entries] The key-value pairs to cache.
2167 function MapCache(entries) {
2169 length = entries == null ? 0 : entries.length;
2172 while (++index < length) {
2173 var entry = entries[index];
2174 this.set(entry[0], entry[1]);
2179 * Removes all key-value entries from the map.
2183 * @memberOf MapCache
2185 function mapCacheClear() {
2189 'map': new (Map || ListCache),
2195 * Removes `key` and its value from the map.
2199 * @memberOf MapCache
2200 * @param {string} key The key of the value to remove.
2201 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2203 function mapCacheDelete(key) {
2204 var result = getMapData(this, key)['delete'](key);
2205 this.size -= result ? 1 : 0;
2210 * Gets the map value for `key`.
2214 * @memberOf MapCache
2215 * @param {string} key The key of the value to get.
2216 * @returns {*} Returns the entry value.
2218 function mapCacheGet(key) {
2219 return getMapData(this, key).get(key);
2223 * Checks if a map value for `key` exists.
2227 * @memberOf MapCache
2228 * @param {string} key The key of the entry to check.
2229 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2231 function mapCacheHas(key) {
2232 return getMapData(this, key).has(key);
2236 * Sets the map `key` to `value`.
2240 * @memberOf MapCache
2241 * @param {string} key The key of the value to set.
2242 * @param {*} value The value to set.
2243 * @returns {Object} Returns the map cache instance.
2245 function mapCacheSet(key, value) {
2246 var data = getMapData(this, key),
2249 data.set(key, value);
2250 this.size += data.size == size ? 0 : 1;
2254 // Add methods to `MapCache`.
2255 MapCache.prototype.clear = mapCacheClear;
2256 MapCache.prototype['delete'] = mapCacheDelete;
2257 MapCache.prototype.get = mapCacheGet;
2258 MapCache.prototype.has = mapCacheHas;
2259 MapCache.prototype.set = mapCacheSet;
2261 /*------------------------------------------------------------------------*/
2265 * Creates an array cache object to store unique values.
2269 * @param {Array} [values] The values to cache.
2271 function SetCache(values) {
2273 length = values == null ? 0 : values.length;
2275 this.__data__ = new MapCache;
2276 while (++index < length) {
2277 this.add(values[index]);
2282 * Adds `value` to the array cache.
2286 * @memberOf SetCache
2288 * @param {*} value The value to cache.
2289 * @returns {Object} Returns the cache instance.
2291 function setCacheAdd(value) {
2292 this.__data__.set(value, HASH_UNDEFINED);
2297 * Checks if `value` is in the array cache.
2301 * @memberOf SetCache
2302 * @param {*} value The value to search for.
2303 * @returns {number} Returns `true` if `value` is found, else `false`.
2305 function setCacheHas(value) {
2306 return this.__data__.has(value);
2309 // Add methods to `SetCache`.
2310 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2311 SetCache.prototype.has = setCacheHas;
2313 /*------------------------------------------------------------------------*/
2316 * Creates a stack cache object to store key-value pairs.
2320 * @param {Array} [entries] The key-value pairs to cache.
2322 function Stack(entries) {
2323 var data = this.__data__ = new ListCache(entries);
2324 this.size = data.size;
2328 * Removes all key-value entries from the stack.
2334 function stackClear() {
2335 this.__data__ = new ListCache;
2340 * Removes `key` and its value from the stack.
2345 * @param {string} key The key of the value to remove.
2346 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2348 function stackDelete(key) {
2349 var data = this.__data__,
2350 result = data['delete'](key);
2352 this.size = data.size;
2357 * Gets the stack value for `key`.
2362 * @param {string} key The key of the value to get.
2363 * @returns {*} Returns the entry value.
2365 function stackGet(key) {
2366 return this.__data__.get(key);
2370 * Checks if a stack value for `key` exists.
2375 * @param {string} key The key of the entry to check.
2376 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2378 function stackHas(key) {
2379 return this.__data__.has(key);
2383 * Sets the stack `key` to `value`.
2388 * @param {string} key The key of the value to set.
2389 * @param {*} value The value to set.
2390 * @returns {Object} Returns the stack cache instance.
2392 function stackSet(key, value) {
2393 var data = this.__data__;
2394 if (data instanceof ListCache) {
2395 var pairs = data.__data__;
2396 if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2397 pairs.push([key, value]);
2398 this.size = ++data.size;
2401 data = this.__data__ = new MapCache(pairs);
2403 data.set(key, value);
2404 this.size = data.size;
2408 // Add methods to `Stack`.
2409 Stack.prototype.clear = stackClear;
2410 Stack.prototype['delete'] = stackDelete;
2411 Stack.prototype.get = stackGet;
2412 Stack.prototype.has = stackHas;
2413 Stack.prototype.set = stackSet;
2415 /*------------------------------------------------------------------------*/
2418 * Creates an array of the enumerable property names of the array-like `value`.
2421 * @param {*} value The value to query.
2422 * @param {boolean} inherited Specify returning inherited property names.
2423 * @returns {Array} Returns the array of property names.
2425 function arrayLikeKeys(value, inherited) {
2426 var isArr = isArray(value),
2427 isArg = !isArr && isArguments(value),
2428 isBuff = !isArr && !isArg && isBuffer(value),
2429 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2430 skipIndexes = isArr || isArg || isBuff || isType,
2431 result = skipIndexes ? baseTimes(value.length, String) : [],
2432 length = result.length;
2434 for (var key in value) {
2435 if ((inherited || hasOwnProperty.call(value, key)) &&
2437 // Safari 9 has enumerable `arguments.length` in strict mode.
2439 // Node.js 0.10 has enumerable non-index properties on buffers.
2440 (isBuff && (key == 'offset' || key == 'parent')) ||
2441 // PhantomJS 2 has enumerable non-index properties on typed arrays.
2442 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2443 // Skip index properties.
2444 isIndex(key, length)
2453 * A specialized version of `_.sample` for arrays.
2456 * @param {Array} array The array to sample.
2457 * @returns {*} Returns the random element.
2459 function arraySample(array) {
2460 var length = array.length;
2461 return length ? array[baseRandom(0, length - 1)] : undefined;
2465 * A specialized version of `_.sampleSize` for arrays.
2468 * @param {Array} array The array to sample.
2469 * @param {number} n The number of elements to sample.
2470 * @returns {Array} Returns the random elements.
2472 function arraySampleSize(array, n) {
2473 return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
2477 * A specialized version of `_.shuffle` for arrays.
2480 * @param {Array} array The array to shuffle.
2481 * @returns {Array} Returns the new shuffled array.
2483 function arrayShuffle(array) {
2484 return shuffleSelf(copyArray(array));
2488 * Used by `_.defaults` to customize its `_.assignIn` use.
2491 * @param {*} objValue The destination value.
2492 * @param {*} srcValue The source value.
2493 * @param {string} key The key of the property to assign.
2494 * @param {Object} object The parent object of `objValue`.
2495 * @returns {*} Returns the value to assign.
2497 function assignInDefaults(objValue, srcValue, key, object) {
2498 if (objValue === undefined ||
2499 (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2506 * This function is like `assignValue` except that it doesn't assign
2507 * `undefined` values.
2510 * @param {Object} object The object to modify.
2511 * @param {string} key The key of the property to assign.
2512 * @param {*} value The value to assign.
2514 function assignMergeValue(object, key, value) {
2515 if ((value !== undefined && !eq(object[key], value)) ||
2516 (value === undefined && !(key in object))) {
2517 baseAssignValue(object, key, value);
2522 * Assigns `value` to `key` of `object` if the existing value is not equivalent
2523 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
2524 * for equality comparisons.
2527 * @param {Object} object The object to modify.
2528 * @param {string} key The key of the property to assign.
2529 * @param {*} value The value to assign.
2531 function assignValue(object, key, value) {
2532 var objValue = object[key];
2533 if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2534 (value === undefined && !(key in object))) {
2535 baseAssignValue(object, key, value);
2540 * Gets the index at which the `key` is found in `array` of key-value pairs.
2543 * @param {Array} array The array to inspect.
2544 * @param {*} key The key to search for.
2545 * @returns {number} Returns the index of the matched value, else `-1`.
2547 function assocIndexOf(array, key) {
2548 var length = array.length;
2550 if (eq(array[length][0], key)) {
2558 * Aggregates elements of `collection` on `accumulator` with keys transformed
2559 * by `iteratee` and values set by `setter`.
2562 * @param {Array|Object} collection The collection to iterate over.
2563 * @param {Function} setter The function to set `accumulator` values.
2564 * @param {Function} iteratee The iteratee to transform keys.
2565 * @param {Object} accumulator The initial aggregated object.
2566 * @returns {Function} Returns `accumulator`.
2568 function baseAggregator(collection, setter, iteratee, accumulator) {
2569 baseEach(collection, function(value, key, collection) {
2570 setter(accumulator, value, iteratee(value), collection);
2576 * The base implementation of `_.assign` without support for multiple sources
2577 * or `customizer` functions.
2580 * @param {Object} object The destination object.
2581 * @param {Object} source The source object.
2582 * @returns {Object} Returns `object`.
2584 function baseAssign(object, source) {
2585 return object && copyObject(source, keys(source), object);
2589 * The base implementation of `_.assignIn` without support for multiple sources
2590 * or `customizer` functions.
2593 * @param {Object} object The destination object.
2594 * @param {Object} source The source object.
2595 * @returns {Object} Returns `object`.
2597 function baseAssignIn(object, source) {
2598 return object && copyObject(source, keysIn(source), object);
2602 * The base implementation of `assignValue` and `assignMergeValue` without
2606 * @param {Object} object The object to modify.
2607 * @param {string} key The key of the property to assign.
2608 * @param {*} value The value to assign.
2610 function baseAssignValue(object, key, value) {
2611 if (key == '__proto__' && defineProperty) {
2612 defineProperty(object, key, {
2613 'configurable': true,
2619 object[key] = value;
2624 * The base implementation of `_.at` without support for individual paths.
2627 * @param {Object} object The object to iterate over.
2628 * @param {string[]} paths The property paths to pick.
2629 * @returns {Array} Returns the picked elements.
2631 function baseAt(object, paths) {
2633 length = paths.length,
2634 result = Array(length),
2635 skip = object == null;
2637 while (++index < length) {
2638 result[index] = skip ? undefined : get(object, paths[index]);
2644 * The base implementation of `_.clamp` which doesn't coerce arguments.
2647 * @param {number} number The number to clamp.
2648 * @param {number} [lower] The lower bound.
2649 * @param {number} upper The upper bound.
2650 * @returns {number} Returns the clamped number.
2652 function baseClamp(number, lower, upper) {
2653 if (number === number) {
2654 if (upper !== undefined) {
2655 number = number <= upper ? number : upper;
2657 if (lower !== undefined) {
2658 number = number >= lower ? number : lower;
2665 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2666 * traversed objects.
2669 * @param {*} value The value to clone.
2670 * @param {boolean} bitmask The bitmask flags.
2672 * 2 - Flatten inherited properties
2674 * @param {Function} [customizer] The function to customize cloning.
2675 * @param {string} [key] The key of `value`.
2676 * @param {Object} [object] The parent object of `value`.
2677 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2678 * @returns {*} Returns the cloned value.
2680 function baseClone(value, bitmask, customizer, key, object, stack) {
2682 isDeep = bitmask & CLONE_DEEP_FLAG,
2683 isFlat = bitmask & CLONE_FLAT_FLAG,
2684 isFull = bitmask & CLONE_SYMBOLS_FLAG;
2687 result = object ? customizer(value, key, object, stack) : customizer(value);
2689 if (result !== undefined) {
2692 if (!isObject(value)) {
2695 var isArr = isArray(value);
2697 result = initCloneArray(value);
2699 return copyArray(value, result);
2702 var tag = getTag(value),
2703 isFunc = tag == funcTag || tag == genTag;
2705 if (isBuffer(value)) {
2706 return cloneBuffer(value, isDeep);
2708 if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2709 result = (isFlat || isFunc) ? {} : initCloneObject(value);
2712 ? copySymbolsIn(value, baseAssignIn(result, value))
2713 : copySymbols(value, baseAssign(result, value));
2716 if (!cloneableTags[tag]) {
2717 return object ? value : {};
2719 result = initCloneByTag(value, tag, baseClone, isDeep);
2722 // Check for circular references and return its corresponding clone.
2723 stack || (stack = new Stack);
2724 var stacked = stack.get(value);
2728 stack.set(value, result);
2730 var keysFunc = isFull
2731 ? (isFlat ? getAllKeysIn : getAllKeys)
2732 : (isFlat ? keysIn : keys);
2734 var props = isArr ? undefined : keysFunc(value);
2735 arrayEach(props || value, function(subValue, key) {
2738 subValue = value[key];
2740 // Recursively populate clone (susceptible to call stack limits).
2741 assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
2747 * The base implementation of `_.conforms` which doesn't clone `source`.
2750 * @param {Object} source The object of property predicates to conform to.
2751 * @returns {Function} Returns the new spec function.
2753 function baseConforms(source) {
2754 var props = keys(source);
2755 return function(object) {
2756 return baseConformsTo(object, source, props);
2761 * The base implementation of `_.conformsTo` which accepts `props` to check.
2764 * @param {Object} object The object to inspect.
2765 * @param {Object} source The object of property predicates to conform to.
2766 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
2768 function baseConformsTo(object, source, props) {
2769 var length = props.length;
2770 if (object == null) {
2773 object = Object(object);
2775 var key = props[length],
2776 predicate = source[key],
2777 value = object[key];
2779 if ((value === undefined && !(key in object)) || !predicate(value)) {
2787 * The base implementation of `_.delay` and `_.defer` which accepts `args`
2788 * to provide to `func`.
2791 * @param {Function} func The function to delay.
2792 * @param {number} wait The number of milliseconds to delay invocation.
2793 * @param {Array} args The arguments to provide to `func`.
2794 * @returns {number|Object} Returns the timer id or timeout object.
2796 function baseDelay(func, wait, args) {
2797 if (typeof func != 'function') {
2798 throw new TypeError(FUNC_ERROR_TEXT);
2800 return setTimeout(function() { func.apply(undefined, args); }, wait);
2804 * The base implementation of methods like `_.difference` without support
2805 * for excluding multiple arrays or iteratee shorthands.
2808 * @param {Array} array The array to inspect.
2809 * @param {Array} values The values to exclude.
2810 * @param {Function} [iteratee] The iteratee invoked per element.
2811 * @param {Function} [comparator] The comparator invoked per element.
2812 * @returns {Array} Returns the new array of filtered values.
2814 function baseDifference(array, values, iteratee, comparator) {
2816 includes = arrayIncludes,
2818 length = array.length,
2820 valuesLength = values.length;
2826 values = arrayMap(values, baseUnary(iteratee));
2829 includes = arrayIncludesWith;
2832 else if (values.length >= LARGE_ARRAY_SIZE) {
2833 includes = cacheHas;
2835 values = new SetCache(values);
2838 while (++index < length) {
2839 var value = array[index],
2840 computed = iteratee == null ? value : iteratee(value);
2842 value = (comparator || value !== 0) ? value : 0;
2843 if (isCommon && computed === computed) {
2844 var valuesIndex = valuesLength;
2845 while (valuesIndex--) {
2846 if (values[valuesIndex] === computed) {
2852 else if (!includes(values, computed, comparator)) {
2860 * The base implementation of `_.forEach` without support for iteratee shorthands.
2863 * @param {Array|Object} collection The collection to iterate over.
2864 * @param {Function} iteratee The function invoked per iteration.
2865 * @returns {Array|Object} Returns `collection`.
2867 var baseEach = createBaseEach(baseForOwn);
2870 * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2873 * @param {Array|Object} collection The collection to iterate over.
2874 * @param {Function} iteratee The function invoked per iteration.
2875 * @returns {Array|Object} Returns `collection`.
2877 var baseEachRight = createBaseEach(baseForOwnRight, true);
2880 * The base implementation of `_.every` without support for iteratee shorthands.
2883 * @param {Array|Object} collection The collection to iterate over.
2884 * @param {Function} predicate The function invoked per iteration.
2885 * @returns {boolean} Returns `true` if all elements pass the predicate check,
2888 function baseEvery(collection, predicate) {
2890 baseEach(collection, function(value, index, collection) {
2891 result = !!predicate(value, index, collection);
2898 * The base implementation of methods like `_.max` and `_.min` which accepts a
2899 * `comparator` to determine the extremum value.
2902 * @param {Array} array The array to iterate over.
2903 * @param {Function} iteratee The iteratee invoked per iteration.
2904 * @param {Function} comparator The comparator used to compare values.
2905 * @returns {*} Returns the extremum value.
2907 function baseExtremum(array, iteratee, comparator) {
2909 length = array.length;
2911 while (++index < length) {
2912 var value = array[index],
2913 current = iteratee(value);
2915 if (current != null && (computed === undefined
2916 ? (current === current && !isSymbol(current))
2917 : comparator(current, computed)
2919 var computed = current,
2927 * The base implementation of `_.fill` without an iteratee call guard.
2930 * @param {Array} array The array to fill.
2931 * @param {*} value The value to fill `array` with.
2932 * @param {number} [start=0] The start position.
2933 * @param {number} [end=array.length] The end position.
2934 * @returns {Array} Returns `array`.
2936 function baseFill(array, value, start, end) {
2937 var length = array.length;
2939 start = toInteger(start);
2941 start = -start > length ? 0 : (length + start);
2943 end = (end === undefined || end > length) ? length : toInteger(end);
2947 end = start > end ? 0 : toLength(end);
2948 while (start < end) {
2949 array[start++] = value;
2955 * The base implementation of `_.filter` without support for iteratee shorthands.
2958 * @param {Array|Object} collection The collection to iterate over.
2959 * @param {Function} predicate The function invoked per iteration.
2960 * @returns {Array} Returns the new filtered array.
2962 function baseFilter(collection, predicate) {
2964 baseEach(collection, function(value, index, collection) {
2965 if (predicate(value, index, collection)) {
2973 * The base implementation of `_.flatten` with support for restricting flattening.
2976 * @param {Array} array The array to flatten.
2977 * @param {number} depth The maximum recursion depth.
2978 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2979 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2980 * @param {Array} [result=[]] The initial result value.
2981 * @returns {Array} Returns the new flattened array.
2983 function baseFlatten(array, depth, predicate, isStrict, result) {
2985 length = array.length;
2987 predicate || (predicate = isFlattenable);
2988 result || (result = []);
2990 while (++index < length) {
2991 var value = array[index];
2992 if (depth > 0 && predicate(value)) {
2994 // Recursively flatten arrays (susceptible to call stack limits).
2995 baseFlatten(value, depth - 1, predicate, isStrict, result);
2997 arrayPush(result, value);
2999 } else if (!isStrict) {
3000 result[result.length] = value;
3007 * The base implementation of `baseForOwn` which iterates over `object`
3008 * properties returned by `keysFunc` and invokes `iteratee` for each property.
3009 * Iteratee functions may exit iteration early by explicitly returning `false`.
3012 * @param {Object} object The object to iterate over.
3013 * @param {Function} iteratee The function invoked per iteration.
3014 * @param {Function} keysFunc The function to get the keys of `object`.
3015 * @returns {Object} Returns `object`.
3017 var baseFor = createBaseFor();
3020 * This function is like `baseFor` except that it iterates over properties
3021 * in the opposite order.
3024 * @param {Object} object The object to iterate over.
3025 * @param {Function} iteratee The function invoked per iteration.
3026 * @param {Function} keysFunc The function to get the keys of `object`.
3027 * @returns {Object} Returns `object`.
3029 var baseForRight = createBaseFor(true);
3032 * The base implementation of `_.forOwn` without support for iteratee shorthands.
3035 * @param {Object} object The object to iterate over.
3036 * @param {Function} iteratee The function invoked per iteration.
3037 * @returns {Object} Returns `object`.
3039 function baseForOwn(object, iteratee) {
3040 return object && baseFor(object, iteratee, keys);
3044 * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
3047 * @param {Object} object The object to iterate over.
3048 * @param {Function} iteratee The function invoked per iteration.
3049 * @returns {Object} Returns `object`.
3051 function baseForOwnRight(object, iteratee) {
3052 return object && baseForRight(object, iteratee, keys);
3056 * The base implementation of `_.functions` which creates an array of
3057 * `object` function property names filtered from `props`.
3060 * @param {Object} object The object to inspect.
3061 * @param {Array} props The property names to filter.
3062 * @returns {Array} Returns the function names.
3064 function baseFunctions(object, props) {
3065 return arrayFilter(props, function(key) {
3066 return isFunction(object[key]);
3071 * The base implementation of `_.get` without support for default values.
3074 * @param {Object} object The object to query.
3075 * @param {Array|string} path The path of the property to get.
3076 * @returns {*} Returns the resolved value.
3078 function baseGet(object, path) {
3079 path = castPath(path, object);
3082 length = path.length;
3084 while (object != null && index < length) {
3085 object = object[toKey(path[index++])];
3087 return (index && index == length) ? object : undefined;
3091 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
3092 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
3093 * symbols of `object`.
3096 * @param {Object} object The object to query.
3097 * @param {Function} keysFunc The function to get the keys of `object`.
3098 * @param {Function} symbolsFunc The function to get the symbols of `object`.
3099 * @returns {Array} Returns the array of property names and symbols.
3101 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
3102 var result = keysFunc(object);
3103 return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
3107 * The base implementation of `getTag` without fallbacks for buggy environments.
3110 * @param {*} value The value to query.
3111 * @returns {string} Returns the `toStringTag`.
3113 function baseGetTag(value) {
3114 if (value == null) {
3115 return value === undefined ? undefinedTag : nullTag;
3117 value = Object(value);
3118 return (symToStringTag && symToStringTag in value)
3120 : objectToString(value);
3124 * The base implementation of `_.gt` which doesn't coerce arguments.
3127 * @param {*} value The value to compare.
3128 * @param {*} other The other value to compare.
3129 * @returns {boolean} Returns `true` if `value` is greater than `other`,
3132 function baseGt(value, other) {
3133 return value > other;
3137 * The base implementation of `_.has` without support for deep paths.
3140 * @param {Object} [object] The object to query.
3141 * @param {Array|string} key The key to check.
3142 * @returns {boolean} Returns `true` if `key` exists, else `false`.
3144 function baseHas(object, key) {
3145 return object != null && hasOwnProperty.call(object, key);
3149 * The base implementation of `_.hasIn` without support for deep paths.
3152 * @param {Object} [object] The object to query.
3153 * @param {Array|string} key The key to check.
3154 * @returns {boolean} Returns `true` if `key` exists, else `false`.
3156 function baseHasIn(object, key) {
3157 return object != null && key in Object(object);
3161 * The base implementation of `_.inRange` which doesn't coerce arguments.
3164 * @param {number} number The number to check.
3165 * @param {number} start The start of the range.
3166 * @param {number} end The end of the range.
3167 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
3169 function baseInRange(number, start, end) {
3170 return number >= nativeMin(start, end) && number < nativeMax(start, end);
3174 * The base implementation of methods like `_.intersection`, without support
3175 * for iteratee shorthands, that accepts an array of arrays to inspect.
3178 * @param {Array} arrays The arrays to inspect.
3179 * @param {Function} [iteratee] The iteratee invoked per element.
3180 * @param {Function} [comparator] The comparator invoked per element.
3181 * @returns {Array} Returns the new array of shared values.
3183 function baseIntersection(arrays, iteratee, comparator) {
3184 var includes = comparator ? arrayIncludesWith : arrayIncludes,
3185 length = arrays[0].length,
3186 othLength = arrays.length,
3187 othIndex = othLength,
3188 caches = Array(othLength),
3189 maxLength = Infinity,
3192 while (othIndex--) {
3193 var array = arrays[othIndex];
3194 if (othIndex && iteratee) {
3195 array = arrayMap(array, baseUnary(iteratee));
3197 maxLength = nativeMin(array.length, maxLength);
3198 caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
3199 ? new SetCache(othIndex && array)
3208 while (++index < length && result.length < maxLength) {
3209 var value = array[index],
3210 computed = iteratee ? iteratee(value) : value;
3212 value = (comparator || value !== 0) ? value : 0;
3214 ? cacheHas(seen, computed)
3215 : includes(result, computed, comparator)
3217 othIndex = othLength;
3218 while (--othIndex) {
3219 var cache = caches[othIndex];
3221 ? cacheHas(cache, computed)
3222 : includes(arrays[othIndex], computed, comparator))
3228 seen.push(computed);
3237 * The base implementation of `_.invert` and `_.invertBy` which inverts
3238 * `object` with values transformed by `iteratee` and set by `setter`.
3241 * @param {Object} object The object to iterate over.
3242 * @param {Function} setter The function to set `accumulator` values.
3243 * @param {Function} iteratee The iteratee to transform values.
3244 * @param {Object} accumulator The initial inverted object.
3245 * @returns {Function} Returns `accumulator`.
3247 function baseInverter(object, setter, iteratee, accumulator) {
3248 baseForOwn(object, function(value, key, object) {
3249 setter(accumulator, iteratee(value), key, object);
3255 * The base implementation of `_.invoke` without support for individual
3259 * @param {Object} object The object to query.
3260 * @param {Array|string} path The path of the method to invoke.
3261 * @param {Array} args The arguments to invoke the method with.
3262 * @returns {*} Returns the result of the invoked method.
3264 function baseInvoke(object, path, args) {
3265 path = castPath(path, object);
3266 object = parent(object, path);
3267 var func = object == null ? object : object[toKey(last(path))];
3268 return func == null ? undefined : apply(func, object, args);
3272 * The base implementation of `_.isArguments`.
3275 * @param {*} value The value to check.
3276 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3278 function baseIsArguments(value) {
3279 return isObjectLike(value) && baseGetTag(value) == argsTag;
3283 * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
3286 * @param {*} value The value to check.
3287 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
3289 function baseIsArrayBuffer(value) {
3290 return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
3294 * The base implementation of `_.isDate` without Node.js optimizations.
3297 * @param {*} value The value to check.
3298 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
3300 function baseIsDate(value) {
3301 return isObjectLike(value) && baseGetTag(value) == dateTag;
3305 * The base implementation of `_.isEqual` which supports partial comparisons
3306 * and tracks traversed objects.
3309 * @param {*} value The value to compare.
3310 * @param {*} other The other value to compare.
3311 * @param {boolean} bitmask The bitmask flags.
3312 * 1 - Unordered comparison
3313 * 2 - Partial comparison
3314 * @param {Function} [customizer] The function to customize comparisons.
3315 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
3316 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3318 function baseIsEqual(value, other, bitmask, customizer, stack) {
3319 if (value === other) {
3322 if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
3323 return value !== value && other !== other;
3325 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
3329 * A specialized version of `baseIsEqual` for arrays and objects which performs
3330 * deep comparisons and tracks traversed objects enabling objects with circular
3331 * references to be compared.
3334 * @param {Object} object The object to compare.
3335 * @param {Object} other The other object to compare.
3336 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
3337 * @param {Function} customizer The function to customize comparisons.
3338 * @param {Function} equalFunc The function to determine equivalents of values.
3339 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
3340 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
3342 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
3343 var objIsArr = isArray(object),
3344 othIsArr = isArray(other),
3349 objTag = getTag(object);
3350 objTag = objTag == argsTag ? objectTag : objTag;
3353 othTag = getTag(other);
3354 othTag = othTag == argsTag ? objectTag : othTag;
3356 var objIsObj = objTag == objectTag,
3357 othIsObj = othTag == objectTag,
3358 isSameTag = objTag == othTag;
3360 if (isSameTag && isBuffer(object)) {
3361 if (!isBuffer(other)) {
3367 if (isSameTag && !objIsObj) {
3368 stack || (stack = new Stack);
3369 return (objIsArr || isTypedArray(object))
3370 ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
3371 : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
3373 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
3374 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
3375 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
3377 if (objIsWrapped || othIsWrapped) {
3378 var objUnwrapped = objIsWrapped ? object.value() : object,
3379 othUnwrapped = othIsWrapped ? other.value() : other;
3381 stack || (stack = new Stack);
3382 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
3388 stack || (stack = new Stack);
3389 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
3393 * The base implementation of `_.isMap` without Node.js optimizations.
3396 * @param {*} value The value to check.
3397 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
3399 function baseIsMap(value) {
3400 return isObjectLike(value) && getTag(value) == mapTag;
3404 * The base implementation of `_.isMatch` without support for iteratee shorthands.
3407 * @param {Object} object The object to inspect.
3408 * @param {Object} source The object of property values to match.
3409 * @param {Array} matchData The property names, values, and compare flags to match.
3410 * @param {Function} [customizer] The function to customize comparisons.
3411 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
3413 function baseIsMatch(object, source, matchData, customizer) {
3414 var index = matchData.length,
3416 noCustomizer = !customizer;
3418 if (object == null) {
3421 object = Object(object);
3423 var data = matchData[index];
3424 if ((noCustomizer && data[2])
3425 ? data[1] !== object[data[0]]
3426 : !(data[0] in object)
3431 while (++index < length) {
3432 data = matchData[index];
3434 objValue = object[key],
3437 if (noCustomizer && data[2]) {
3438 if (objValue === undefined && !(key in object)) {
3442 var stack = new Stack;
3444 var result = customizer(objValue, srcValue, key, object, source, stack);
3446 if (!(result === undefined
3447 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
3458 * The base implementation of `_.isNative` without bad shim checks.
3461 * @param {*} value The value to check.
3462 * @returns {boolean} Returns `true` if `value` is a native function,
3465 function baseIsNative(value) {
3466 if (!isObject(value) || isMasked(value)) {
3469 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3470 return pattern.test(toSource(value));
3474 * The base implementation of `_.isRegExp` without Node.js optimizations.
3477 * @param {*} value The value to check.
3478 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
3480 function baseIsRegExp(value) {
3481 return isObjectLike(value) && baseGetTag(value) == regexpTag;
3485 * The base implementation of `_.isSet` without Node.js optimizations.
3488 * @param {*} value The value to check.
3489 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
3491 function baseIsSet(value) {
3492 return isObjectLike(value) && getTag(value) == setTag;
3496 * The base implementation of `_.isTypedArray` without Node.js optimizations.
3499 * @param {*} value The value to check.
3500 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3502 function baseIsTypedArray(value) {
3503 return isObjectLike(value) &&
3504 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
3508 * The base implementation of `_.iteratee`.
3511 * @param {*} [value=_.identity] The value to convert to an iteratee.
3512 * @returns {Function} Returns the iteratee.
3514 function baseIteratee(value) {
3515 // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3516 // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3517 if (typeof value == 'function') {
3520 if (value == null) {
3523 if (typeof value == 'object') {
3524 return isArray(value)
3525 ? baseMatchesProperty(value[0], value[1])
3526 : baseMatches(value);
3528 return property(value);
3532 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
3535 * @param {Object} object The object to query.
3536 * @returns {Array} Returns the array of property names.
3538 function baseKeys(object) {
3539 if (!isPrototype(object)) {
3540 return nativeKeys(object);
3543 for (var key in Object(object)) {
3544 if (hasOwnProperty.call(object, key) && key != 'constructor') {
3552 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
3555 * @param {Object} object The object to query.
3556 * @returns {Array} Returns the array of property names.
3558 function baseKeysIn(object) {
3559 if (!isObject(object)) {
3560 return nativeKeysIn(object);
3562 var isProto = isPrototype(object),
3565 for (var key in object) {
3566 if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3574 * The base implementation of `_.lt` which doesn't coerce arguments.
3577 * @param {*} value The value to compare.
3578 * @param {*} other The other value to compare.
3579 * @returns {boolean} Returns `true` if `value` is less than `other`,
3582 function baseLt(value, other) {
3583 return value < other;
3587 * The base implementation of `_.map` without support for iteratee shorthands.
3590 * @param {Array|Object} collection The collection to iterate over.
3591 * @param {Function} iteratee The function invoked per iteration.
3592 * @returns {Array} Returns the new mapped array.
3594 function baseMap(collection, iteratee) {
3596 result = isArrayLike(collection) ? Array(collection.length) : [];
3598 baseEach(collection, function(value, key, collection) {
3599 result[++index] = iteratee(value, key, collection);
3605 * The base implementation of `_.matches` which doesn't clone `source`.
3608 * @param {Object} source The object of property values to match.
3609 * @returns {Function} Returns the new spec function.
3611 function baseMatches(source) {
3612 var matchData = getMatchData(source);
3613 if (matchData.length == 1 && matchData[0][2]) {
3614 return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3616 return function(object) {
3617 return object === source || baseIsMatch(object, source, matchData);
3622 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3625 * @param {string} path The path of the property to get.
3626 * @param {*} srcValue The value to match.
3627 * @returns {Function} Returns the new spec function.
3629 function baseMatchesProperty(path, srcValue) {
3630 if (isKey(path) && isStrictComparable(srcValue)) {
3631 return matchesStrictComparable(toKey(path), srcValue);
3633 return function(object) {
3634 var objValue = get(object, path);
3635 return (objValue === undefined && objValue === srcValue)
3636 ? hasIn(object, path)
3637 : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
3642 * The base implementation of `_.merge` without support for multiple sources.
3645 * @param {Object} object The destination object.
3646 * @param {Object} source The source object.
3647 * @param {number} srcIndex The index of `source`.
3648 * @param {Function} [customizer] The function to customize merged values.
3649 * @param {Object} [stack] Tracks traversed source values and their merged
3652 function baseMerge(object, source, srcIndex, customizer, stack) {
3653 if (object === source) {
3656 baseFor(source, function(srcValue, key) {
3657 if (isObject(srcValue)) {
3658 stack || (stack = new Stack);
3659 baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3662 var newValue = customizer
3663 ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3666 if (newValue === undefined) {
3667 newValue = srcValue;
3669 assignMergeValue(object, key, newValue);
3675 * A specialized version of `baseMerge` for arrays and objects which performs
3676 * deep merges and tracks traversed objects enabling objects with circular
3677 * references to be merged.
3680 * @param {Object} object The destination object.
3681 * @param {Object} source The source object.
3682 * @param {string} key The key of the value to merge.
3683 * @param {number} srcIndex The index of `source`.
3684 * @param {Function} mergeFunc The function to merge values.
3685 * @param {Function} [customizer] The function to customize assigned values.
3686 * @param {Object} [stack] Tracks traversed source values and their merged
3689 function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3690 var objValue = object[key],
3691 srcValue = source[key],
3692 stacked = stack.get(srcValue);
3695 assignMergeValue(object, key, stacked);
3698 var newValue = customizer
3699 ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3702 var isCommon = newValue === undefined;
3705 var isArr = isArray(srcValue),
3706 isBuff = !isArr && isBuffer(srcValue),
3707 isTyped = !isArr && !isBuff && isTypedArray(srcValue);
3709 newValue = srcValue;
3710 if (isArr || isBuff || isTyped) {
3711 if (isArray(objValue)) {
3712 newValue = objValue;
3714 else if (isArrayLikeObject(objValue)) {
3715 newValue = copyArray(objValue);
3719 newValue = cloneBuffer(srcValue, true);
3723 newValue = cloneTypedArray(srcValue, true);
3729 else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3730 newValue = objValue;
3731 if (isArguments(objValue)) {
3732 newValue = toPlainObject(objValue);
3734 else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3735 newValue = initCloneObject(srcValue);
3743 // Recursively merge objects and arrays (susceptible to call stack limits).
3744 stack.set(srcValue, newValue);
3745 mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3746 stack['delete'](srcValue);
3748 assignMergeValue(object, key, newValue);
3752 * The base implementation of `_.nth` which doesn't coerce arguments.
3755 * @param {Array} array The array to query.
3756 * @param {number} n The index of the element to return.
3757 * @returns {*} Returns the nth element of `array`.
3759 function baseNth(array, n) {
3760 var length = array.length;
3764 n += n < 0 ? length : 0;
3765 return isIndex(n, length) ? array[n] : undefined;
3769 * The base implementation of `_.orderBy` without param guards.
3772 * @param {Array|Object} collection The collection to iterate over.
3773 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3774 * @param {string[]} orders The sort orders of `iteratees`.
3775 * @returns {Array} Returns the new sorted array.
3777 function baseOrderBy(collection, iteratees, orders) {
3779 iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
3781 var result = baseMap(collection, function(value, key, collection) {
3782 var criteria = arrayMap(iteratees, function(iteratee) {
3783 return iteratee(value);
3785 return { 'criteria': criteria, 'index': ++index, 'value': value };
3788 return baseSortBy(result, function(object, other) {
3789 return compareMultiple(object, other, orders);
3794 * The base implementation of `_.pick` without support for individual
3795 * property identifiers.
3798 * @param {Object} object The source object.
3799 * @param {string[]} paths The property paths to pick.
3800 * @returns {Object} Returns the new object.
3802 function basePick(object, paths) {
3803 object = Object(object);
3804 return basePickBy(object, paths, function(value, path) {
3805 return hasIn(object, path);
3810 * The base implementation of `_.pickBy` without support for iteratee shorthands.
3813 * @param {Object} object The source object.
3814 * @param {string[]} paths The property paths to pick.
3815 * @param {Function} predicate The function invoked per property.
3816 * @returns {Object} Returns the new object.
3818 function basePickBy(object, paths, predicate) {
3820 length = paths.length,
3823 while (++index < length) {
3824 var path = paths[index],
3825 value = baseGet(object, path);
3827 if (predicate(value, path)) {
3828 baseSet(result, castPath(path, object), value);
3835 * A specialized version of `baseProperty` which supports deep paths.
3838 * @param {Array|string} path The path of the property to get.
3839 * @returns {Function} Returns the new accessor function.
3841 function basePropertyDeep(path) {
3842 return function(object) {
3843 return baseGet(object, path);
3848 * The base implementation of `_.pullAllBy` without support for iteratee
3852 * @param {Array} array The array to modify.
3853 * @param {Array} values The values to remove.
3854 * @param {Function} [iteratee] The iteratee invoked per element.
3855 * @param {Function} [comparator] The comparator invoked per element.
3856 * @returns {Array} Returns `array`.
3858 function basePullAll(array, values, iteratee, comparator) {
3859 var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3861 length = values.length,
3864 if (array === values) {
3865 values = copyArray(values);
3868 seen = arrayMap(array, baseUnary(iteratee));
3870 while (++index < length) {
3872 value = values[index],
3873 computed = iteratee ? iteratee(value) : value;
3875 while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3876 if (seen !== array) {
3877 splice.call(seen, fromIndex, 1);
3879 splice.call(array, fromIndex, 1);
3886 * The base implementation of `_.pullAt` without support for individual
3887 * indexes or capturing the removed elements.
3890 * @param {Array} array The array to modify.
3891 * @param {number[]} indexes The indexes of elements to remove.
3892 * @returns {Array} Returns `array`.
3894 function basePullAt(array, indexes) {
3895 var length = array ? indexes.length : 0,
3896 lastIndex = length - 1;
3899 var index = indexes[length];
3900 if (length == lastIndex || index !== previous) {
3901 var previous = index;
3902 if (isIndex(index)) {
3903 splice.call(array, index, 1);
3905 baseUnset(array, index);
3913 * The base implementation of `_.random` without support for returning
3914 * floating-point numbers.
3917 * @param {number} lower The lower bound.
3918 * @param {number} upper The upper bound.
3919 * @returns {number} Returns the random number.
3921 function baseRandom(lower, upper) {
3922 return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3926 * The base implementation of `_.range` and `_.rangeRight` which doesn't
3930 * @param {number} start The start of the range.
3931 * @param {number} end The end of the range.
3932 * @param {number} step The value to increment or decrement by.
3933 * @param {boolean} [fromRight] Specify iterating from right to left.
3934 * @returns {Array} Returns the range of numbers.
3936 function baseRange(start, end, step, fromRight) {
3938 length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3939 result = Array(length);
3942 result[fromRight ? length : ++index] = start;
3949 * The base implementation of `_.repeat` which doesn't coerce arguments.
3952 * @param {string} string The string to repeat.
3953 * @param {number} n The number of times to repeat the string.
3954 * @returns {string} Returns the repeated string.
3956 function baseRepeat(string, n) {
3958 if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3961 // Leverage the exponentiation by squaring algorithm for a faster repeat.
3962 // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3967 n = nativeFloor(n / 2);
3977 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
3980 * @param {Function} func The function to apply a rest parameter to.
3981 * @param {number} [start=func.length-1] The start position of the rest parameter.
3982 * @returns {Function} Returns the new function.
3984 function baseRest(func, start) {
3985 return setToString(overRest(func, start, identity), func + '');
3989 * The base implementation of `_.sample`.
3992 * @param {Array|Object} collection The collection to sample.
3993 * @returns {*} Returns the random element.
3995 function baseSample(collection) {
3996 return arraySample(values(collection));
4000 * The base implementation of `_.sampleSize` without param guards.
4003 * @param {Array|Object} collection The collection to sample.
4004 * @param {number} n The number of elements to sample.
4005 * @returns {Array} Returns the random elements.
4007 function baseSampleSize(collection, n) {
4008 var array = values(collection);
4009 return shuffleSelf(array, baseClamp(n, 0, array.length));
4013 * The base implementation of `_.set`.
4016 * @param {Object} object The object to modify.
4017 * @param {Array|string} path The path of the property to set.
4018 * @param {*} value The value to set.
4019 * @param {Function} [customizer] The function to customize path creation.
4020 * @returns {Object} Returns `object`.
4022 function baseSet(object, path, value, customizer) {
4023 if (!isObject(object)) {
4026 path = castPath(path, object);
4029 length = path.length,
4030 lastIndex = length - 1,
4033 while (nested != null && ++index < length) {
4034 var key = toKey(path[index]),
4037 if (index != lastIndex) {
4038 var objValue = nested[key];
4039 newValue = customizer ? customizer(objValue, key, nested) : undefined;
4040 if (newValue === undefined) {
4041 newValue = isObject(objValue)
4043 : (isIndex(path[index + 1]) ? [] : {});
4046 assignValue(nested, key, newValue);
4047 nested = nested[key];
4053 * The base implementation of `setData` without support for hot loop shorting.
4056 * @param {Function} func The function to associate metadata with.
4057 * @param {*} data The metadata.
4058 * @returns {Function} Returns `func`.
4060 var baseSetData = !metaMap ? identity : function(func, data) {
4061 metaMap.set(func, data);
4066 * The base implementation of `setToString` without support for hot loop shorting.
4069 * @param {Function} func The function to modify.
4070 * @param {Function} string The `toString` result.
4071 * @returns {Function} Returns `func`.
4073 var baseSetToString = !defineProperty ? identity : function(func, string) {
4074 return defineProperty(func, 'toString', {
4075 'configurable': true,
4076 'enumerable': false,
4077 'value': constant(string),
4083 * The base implementation of `_.shuffle`.
4086 * @param {Array|Object} collection The collection to shuffle.
4087 * @returns {Array} Returns the new shuffled array.
4089 function baseShuffle(collection) {
4090 return shuffleSelf(values(collection));
4094 * The base implementation of `_.slice` without an iteratee call guard.
4097 * @param {Array} array The array to slice.
4098 * @param {number} [start=0] The start position.
4099 * @param {number} [end=array.length] The end position.
4100 * @returns {Array} Returns the slice of `array`.
4102 function baseSlice(array, start, end) {
4104 length = array.length;
4107 start = -start > length ? 0 : (length + start);
4109 end = end > length ? length : end;
4113 length = start > end ? 0 : ((end - start) >>> 0);
4116 var result = Array(length);
4117 while (++index < length) {
4118 result[index] = array[index + start];
4124 * The base implementation of `_.some` without support for iteratee shorthands.
4127 * @param {Array|Object} collection The collection to iterate over.
4128 * @param {Function} predicate The function invoked per iteration.
4129 * @returns {boolean} Returns `true` if any element passes the predicate check,
4132 function baseSome(collection, predicate) {
4135 baseEach(collection, function(value, index, collection) {
4136 result = predicate(value, index, collection);
4143 * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
4144 * performs a binary search of `array` to determine the index at which `value`
4145 * should be inserted into `array` in order to maintain its sort order.
4148 * @param {Array} array The sorted array to inspect.
4149 * @param {*} value The value to evaluate.
4150 * @param {boolean} [retHighest] Specify returning the highest qualified index.
4151 * @returns {number} Returns the index at which `value` should be inserted
4154 function baseSortedIndex(array, value, retHighest) {
4156 high = array == null ? low : array.length;
4158 if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
4159 while (low < high) {
4160 var mid = (low + high) >>> 1,
4161 computed = array[mid];
4163 if (computed !== null && !isSymbol(computed) &&
4164 (retHighest ? (computed <= value) : (computed < value))) {
4172 return baseSortedIndexBy(array, value, identity, retHighest);
4176 * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
4177 * which invokes `iteratee` for `value` and each element of `array` to compute
4178 * their sort ranking. The iteratee is invoked with one argument; (value).
4181 * @param {Array} array The sorted array to inspect.
4182 * @param {*} value The value to evaluate.
4183 * @param {Function} iteratee The iteratee invoked per element.
4184 * @param {boolean} [retHighest] Specify returning the highest qualified index.
4185 * @returns {number} Returns the index at which `value` should be inserted
4188 function baseSortedIndexBy(array, value, iteratee, retHighest) {
4189 value = iteratee(value);
4192 high = array == null ? 0 : array.length,
4193 valIsNaN = value !== value,
4194 valIsNull = value === null,
4195 valIsSymbol = isSymbol(value),
4196 valIsUndefined = value === undefined;
4198 while (low < high) {
4199 var mid = nativeFloor((low + high) / 2),
4200 computed = iteratee(array[mid]),
4201 othIsDefined = computed !== undefined,
4202 othIsNull = computed === null,
4203 othIsReflexive = computed === computed,
4204 othIsSymbol = isSymbol(computed);
4207 var setLow = retHighest || othIsReflexive;
4208 } else if (valIsUndefined) {
4209 setLow = othIsReflexive && (retHighest || othIsDefined);
4210 } else if (valIsNull) {
4211 setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
4212 } else if (valIsSymbol) {
4213 setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
4214 } else if (othIsNull || othIsSymbol) {
4217 setLow = retHighest ? (computed <= value) : (computed < value);
4225 return nativeMin(high, MAX_ARRAY_INDEX);
4229 * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
4230 * support for iteratee shorthands.
4233 * @param {Array} array The array to inspect.
4234 * @param {Function} [iteratee] The iteratee invoked per element.
4235 * @returns {Array} Returns the new duplicate free array.
4237 function baseSortedUniq(array, iteratee) {
4239 length = array.length,
4243 while (++index < length) {
4244 var value = array[index],
4245 computed = iteratee ? iteratee(value) : value;
4247 if (!index || !eq(computed, seen)) {
4248 var seen = computed;
4249 result[resIndex++] = value === 0 ? 0 : value;
4256 * The base implementation of `_.toNumber` which doesn't ensure correct
4257 * conversions of binary, hexadecimal, or octal string values.
4260 * @param {*} value The value to process.
4261 * @returns {number} Returns the number.
4263 function baseToNumber(value) {
4264 if (typeof value == 'number') {
4267 if (isSymbol(value)) {
4274 * The base implementation of `_.toString` which doesn't convert nullish
4275 * values to empty strings.
4278 * @param {*} value The value to process.
4279 * @returns {string} Returns the string.
4281 function baseToString(value) {
4282 // Exit early for strings to avoid a performance hit in some environments.
4283 if (typeof value == 'string') {
4286 if (isArray(value)) {
4287 // Recursively convert values (susceptible to call stack limits).
4288 return arrayMap(value, baseToString) + '';
4290 if (isSymbol(value)) {
4291 return symbolToString ? symbolToString.call(value) : '';
4293 var result = (value + '');
4294 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
4298 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
4301 * @param {Array} array The array to inspect.
4302 * @param {Function} [iteratee] The iteratee invoked per element.
4303 * @param {Function} [comparator] The comparator invoked per element.
4304 * @returns {Array} Returns the new duplicate free array.
4306 function baseUniq(array, iteratee, comparator) {
4308 includes = arrayIncludes,
4309 length = array.length,
4316 includes = arrayIncludesWith;
4318 else if (length >= LARGE_ARRAY_SIZE) {
4319 var set = iteratee ? null : createSet(array);
4321 return setToArray(set);
4324 includes = cacheHas;
4325 seen = new SetCache;
4328 seen = iteratee ? [] : result;
4331 while (++index < length) {
4332 var value = array[index],
4333 computed = iteratee ? iteratee(value) : value;
4335 value = (comparator || value !== 0) ? value : 0;
4336 if (isCommon && computed === computed) {
4337 var seenIndex = seen.length;
4338 while (seenIndex--) {
4339 if (seen[seenIndex] === computed) {
4344 seen.push(computed);
4348 else if (!includes(seen, computed, comparator)) {
4349 if (seen !== result) {
4350 seen.push(computed);
4359 * The base implementation of `_.unset`.
4362 * @param {Object} object The object to modify.
4363 * @param {Array|string} path The property path to unset.
4364 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
4366 function baseUnset(object, path) {
4367 path = castPath(path, object);
4368 object = parent(object, path);
4369 return object == null || delete object[toKey(last(path))];
4373 * The base implementation of `_.update`.
4376 * @param {Object} object The object to modify.
4377 * @param {Array|string} path The path of the property to update.
4378 * @param {Function} updater The function to produce the updated value.
4379 * @param {Function} [customizer] The function to customize path creation.
4380 * @returns {Object} Returns `object`.
4382 function baseUpdate(object, path, updater, customizer) {
4383 return baseSet(object, path, updater(baseGet(object, path)), customizer);
4387 * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
4388 * without support for iteratee shorthands.
4391 * @param {Array} array The array to query.
4392 * @param {Function} predicate The function invoked per iteration.
4393 * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
4394 * @param {boolean} [fromRight] Specify iterating from right to left.
4395 * @returns {Array} Returns the slice of `array`.
4397 function baseWhile(array, predicate, isDrop, fromRight) {
4398 var length = array.length,
4399 index = fromRight ? length : -1;
4401 while ((fromRight ? index-- : ++index < length) &&
4402 predicate(array[index], index, array)) {}
4405 ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
4406 : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
4410 * The base implementation of `wrapperValue` which returns the result of
4411 * performing a sequence of actions on the unwrapped `value`, where each
4412 * successive action is supplied the return value of the previous.
4415 * @param {*} value The unwrapped value.
4416 * @param {Array} actions Actions to perform to resolve the unwrapped value.
4417 * @returns {*} Returns the resolved value.
4419 function baseWrapperValue(value, actions) {
4421 if (result instanceof LazyWrapper) {
4422 result = result.value();
4424 return arrayReduce(actions, function(result, action) {
4425 return action.func.apply(action.thisArg, arrayPush([result], action.args));
4430 * The base implementation of methods like `_.xor`, without support for
4431 * iteratee shorthands, that accepts an array of arrays to inspect.
4434 * @param {Array} arrays The arrays to inspect.
4435 * @param {Function} [iteratee] The iteratee invoked per element.
4436 * @param {Function} [comparator] The comparator invoked per element.
4437 * @returns {Array} Returns the new array of values.
4439 function baseXor(arrays, iteratee, comparator) {
4440 var length = arrays.length;
4442 return length ? baseUniq(arrays[0]) : [];
4445 result = Array(length);
4447 while (++index < length) {
4448 var array = arrays[index],
4451 while (++othIndex < length) {
4452 if (othIndex != index) {
4453 result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
4457 return baseUniq(baseFlatten(result, 1), iteratee, comparator);
4461 * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
4464 * @param {Array} props The property identifiers.
4465 * @param {Array} values The property values.
4466 * @param {Function} assignFunc The function to assign values.
4467 * @returns {Object} Returns the new object.
4469 function baseZipObject(props, values, assignFunc) {
4471 length = props.length,
4472 valsLength = values.length,
4475 while (++index < length) {
4476 var value = index < valsLength ? values[index] : undefined;
4477 assignFunc(result, props[index], value);
4483 * Casts `value` to an empty array if it's not an array like object.
4486 * @param {*} value The value to inspect.
4487 * @returns {Array|Object} Returns the cast array-like object.
4489 function castArrayLikeObject(value) {
4490 return isArrayLikeObject(value) ? value : [];
4494 * Casts `value` to `identity` if it's not a function.
4497 * @param {*} value The value to inspect.
4498 * @returns {Function} Returns cast function.
4500 function castFunction(value) {
4501 return typeof value == 'function' ? value : identity;
4505 * Casts `value` to a path array if it's not one.
4508 * @param {*} value The value to inspect.
4509 * @param {Object} [object] The object to query keys on.
4510 * @returns {Array} Returns the cast property path array.
4512 function castPath(value, object) {
4513 if (isArray(value)) {
4516 return isKey(value, object) ? [value] : stringToPath(toString(value));
4520 * A `baseRest` alias which can be replaced with `identity` by module
4521 * replacement plugins.
4525 * @param {Function} func The function to apply a rest parameter to.
4526 * @returns {Function} Returns the new function.
4528 var castRest = baseRest;
4531 * Casts `array` to a slice if it's needed.
4534 * @param {Array} array The array to inspect.
4535 * @param {number} start The start position.
4536 * @param {number} [end=array.length] The end position.
4537 * @returns {Array} Returns the cast slice.
4539 function castSlice(array, start, end) {
4540 var length = array.length;
4541 end = end === undefined ? length : end;
4542 return (!start && end >= length) ? array : baseSlice(array, start, end);
4546 * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
4549 * @param {number|Object} id The timer id or timeout object of the timer to clear.
4551 var clearTimeout = ctxClearTimeout || function(id) {
4552 return root.clearTimeout(id);
4556 * Creates a clone of `buffer`.
4559 * @param {Buffer} buffer The buffer to clone.
4560 * @param {boolean} [isDeep] Specify a deep clone.
4561 * @returns {Buffer} Returns the cloned buffer.
4563 function cloneBuffer(buffer, isDeep) {
4565 return buffer.slice();
4567 var length = buffer.length,
4568 result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
4570 buffer.copy(result);
4575 * Creates a clone of `arrayBuffer`.
4578 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4579 * @returns {ArrayBuffer} Returns the cloned array buffer.
4581 function cloneArrayBuffer(arrayBuffer) {
4582 var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4583 new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4588 * Creates a clone of `dataView`.
4591 * @param {Object} dataView The data view to clone.
4592 * @param {boolean} [isDeep] Specify a deep clone.
4593 * @returns {Object} Returns the cloned data view.
4595 function cloneDataView(dataView, isDeep) {
4596 var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4597 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4601 * Creates a clone of `map`.
4604 * @param {Object} map The map to clone.
4605 * @param {Function} cloneFunc The function to clone values.
4606 * @param {boolean} [isDeep] Specify a deep clone.
4607 * @returns {Object} Returns the cloned map.
4609 function cloneMap(map, isDeep, cloneFunc) {
4610 var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
4611 return arrayReduce(array, addMapEntry, new map.constructor);
4615 * Creates a clone of `regexp`.
4618 * @param {Object} regexp The regexp to clone.
4619 * @returns {Object} Returns the cloned regexp.
4621 function cloneRegExp(regexp) {
4622 var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4623 result.lastIndex = regexp.lastIndex;
4628 * Creates a clone of `set`.
4631 * @param {Object} set The set to clone.
4632 * @param {Function} cloneFunc The function to clone values.
4633 * @param {boolean} [isDeep] Specify a deep clone.
4634 * @returns {Object} Returns the cloned set.
4636 function cloneSet(set, isDeep, cloneFunc) {
4637 var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
4638 return arrayReduce(array, addSetEntry, new set.constructor);
4642 * Creates a clone of the `symbol` object.
4645 * @param {Object} symbol The symbol object to clone.
4646 * @returns {Object} Returns the cloned symbol object.
4648 function cloneSymbol(symbol) {
4649 return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4653 * Creates a clone of `typedArray`.
4656 * @param {Object} typedArray The typed array to clone.
4657 * @param {boolean} [isDeep] Specify a deep clone.
4658 * @returns {Object} Returns the cloned typed array.
4660 function cloneTypedArray(typedArray, isDeep) {
4661 var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4662 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4666 * Compares values to sort them in ascending order.
4669 * @param {*} value The value to compare.
4670 * @param {*} other The other value to compare.
4671 * @returns {number} Returns the sort order indicator for `value`.
4673 function compareAscending(value, other) {
4674 if (value !== other) {
4675 var valIsDefined = value !== undefined,
4676 valIsNull = value === null,
4677 valIsReflexive = value === value,
4678 valIsSymbol = isSymbol(value);
4680 var othIsDefined = other !== undefined,
4681 othIsNull = other === null,
4682 othIsReflexive = other === other,
4683 othIsSymbol = isSymbol(other);
4685 if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4686 (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4687 (valIsNull && othIsDefined && othIsReflexive) ||
4688 (!valIsDefined && othIsReflexive) ||
4692 if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4693 (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4694 (othIsNull && valIsDefined && valIsReflexive) ||
4695 (!othIsDefined && valIsReflexive) ||
4704 * Used by `_.orderBy` to compare multiple properties of a value to another
4705 * and stable sort them.
4707 * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4708 * specify an order of "desc" for descending or "asc" for ascending sort order
4709 * of corresponding values.
4712 * @param {Object} object The object to compare.
4713 * @param {Object} other The other object to compare.
4714 * @param {boolean[]|string[]} orders The order to sort by for each property.
4715 * @returns {number} Returns the sort order indicator for `object`.
4717 function compareMultiple(object, other, orders) {
4719 objCriteria = object.criteria,
4720 othCriteria = other.criteria,
4721 length = objCriteria.length,
4722 ordersLength = orders.length;
4724 while (++index < length) {
4725 var result = compareAscending(objCriteria[index], othCriteria[index]);
4727 if (index >= ordersLength) {
4730 var order = orders[index];
4731 return result * (order == 'desc' ? -1 : 1);
4734 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4735 // that causes it, under certain circumstances, to provide the same value for
4736 // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4737 // for more details.
4739 // This also ensures a stable sort in V8 and other engines.
4740 // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4741 return object.index - other.index;
4745 * Creates an array that is the composition of partially applied arguments,
4746 * placeholders, and provided arguments into a single array of arguments.
4749 * @param {Array} args The provided arguments.
4750 * @param {Array} partials The arguments to prepend to those provided.
4751 * @param {Array} holders The `partials` placeholder indexes.
4752 * @params {boolean} [isCurried] Specify composing for a curried function.
4753 * @returns {Array} Returns the new array of composed arguments.
4755 function composeArgs(args, partials, holders, isCurried) {
4757 argsLength = args.length,
4758 holdersLength = holders.length,
4760 leftLength = partials.length,
4761 rangeLength = nativeMax(argsLength - holdersLength, 0),
4762 result = Array(leftLength + rangeLength),
4763 isUncurried = !isCurried;
4765 while (++leftIndex < leftLength) {
4766 result[leftIndex] = partials[leftIndex];
4768 while (++argsIndex < holdersLength) {
4769 if (isUncurried || argsIndex < argsLength) {
4770 result[holders[argsIndex]] = args[argsIndex];
4773 while (rangeLength--) {
4774 result[leftIndex++] = args[argsIndex++];
4780 * This function is like `composeArgs` except that the arguments composition
4781 * is tailored for `_.partialRight`.
4784 * @param {Array} args The provided arguments.
4785 * @param {Array} partials The arguments to append to those provided.
4786 * @param {Array} holders The `partials` placeholder indexes.
4787 * @params {boolean} [isCurried] Specify composing for a curried function.
4788 * @returns {Array} Returns the new array of composed arguments.
4790 function composeArgsRight(args, partials, holders, isCurried) {
4792 argsLength = args.length,
4794 holdersLength = holders.length,
4796 rightLength = partials.length,
4797 rangeLength = nativeMax(argsLength - holdersLength, 0),
4798 result = Array(rangeLength + rightLength),
4799 isUncurried = !isCurried;
4801 while (++argsIndex < rangeLength) {
4802 result[argsIndex] = args[argsIndex];
4804 var offset = argsIndex;
4805 while (++rightIndex < rightLength) {
4806 result[offset + rightIndex] = partials[rightIndex];
4808 while (++holdersIndex < holdersLength) {
4809 if (isUncurried || argsIndex < argsLength) {
4810 result[offset + holders[holdersIndex]] = args[argsIndex++];
4817 * Copies the values of `source` to `array`.
4820 * @param {Array} source The array to copy values from.
4821 * @param {Array} [array=[]] The array to copy values to.
4822 * @returns {Array} Returns `array`.
4824 function copyArray(source, array) {
4826 length = source.length;
4828 array || (array = Array(length));
4829 while (++index < length) {
4830 array[index] = source[index];
4836 * Copies properties of `source` to `object`.
4839 * @param {Object} source The object to copy properties from.
4840 * @param {Array} props The property identifiers to copy.
4841 * @param {Object} [object={}] The object to copy properties to.
4842 * @param {Function} [customizer] The function to customize copied values.
4843 * @returns {Object} Returns `object`.
4845 function copyObject(source, props, object, customizer) {
4846 var isNew = !object;
4847 object || (object = {});
4850 length = props.length;
4852 while (++index < length) {
4853 var key = props[index];
4855 var newValue = customizer
4856 ? customizer(object[key], source[key], key, object, source)
4859 if (newValue === undefined) {
4860 newValue = source[key];
4863 baseAssignValue(object, key, newValue);
4865 assignValue(object, key, newValue);
4872 * Copies own symbols of `source` to `object`.
4875 * @param {Object} source The object to copy symbols from.
4876 * @param {Object} [object={}] The object to copy symbols to.
4877 * @returns {Object} Returns `object`.
4879 function copySymbols(source, object) {
4880 return copyObject(source, getSymbols(source), object);
4884 * Copies own and inherited symbols of `source` to `object`.
4887 * @param {Object} source The object to copy symbols from.
4888 * @param {Object} [object={}] The object to copy symbols to.
4889 * @returns {Object} Returns `object`.
4891 function copySymbolsIn(source, object) {
4892 return copyObject(source, getSymbolsIn(source), object);
4896 * Creates a function like `_.groupBy`.
4899 * @param {Function} setter The function to set accumulator values.
4900 * @param {Function} [initializer] The accumulator object initializer.
4901 * @returns {Function} Returns the new aggregator function.
4903 function createAggregator(setter, initializer) {
4904 return function(collection, iteratee) {
4905 var func = isArray(collection) ? arrayAggregator : baseAggregator,
4906 accumulator = initializer ? initializer() : {};
4908 return func(collection, setter, getIteratee(iteratee, 2), accumulator);
4913 * Creates a function like `_.assign`.
4916 * @param {Function} assigner The function to assign values.
4917 * @returns {Function} Returns the new assigner function.
4919 function createAssigner(assigner) {
4920 return baseRest(function(object, sources) {
4922 length = sources.length,
4923 customizer = length > 1 ? sources[length - 1] : undefined,
4924 guard = length > 2 ? sources[2] : undefined;
4926 customizer = (assigner.length > 3 && typeof customizer == 'function')
4927 ? (length--, customizer)
4930 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4931 customizer = length < 3 ? undefined : customizer;
4934 object = Object(object);
4935 while (++index < length) {
4936 var source = sources[index];
4938 assigner(object, source, index, customizer);
4946 * Creates a `baseEach` or `baseEachRight` function.
4949 * @param {Function} eachFunc The function to iterate over a collection.
4950 * @param {boolean} [fromRight] Specify iterating from right to left.
4951 * @returns {Function} Returns the new base function.
4953 function createBaseEach(eachFunc, fromRight) {
4954 return function(collection, iteratee) {
4955 if (collection == null) {
4958 if (!isArrayLike(collection)) {
4959 return eachFunc(collection, iteratee);
4961 var length = collection.length,
4962 index = fromRight ? length : -1,
4963 iterable = Object(collection);
4965 while ((fromRight ? index-- : ++index < length)) {
4966 if (iteratee(iterable[index], index, iterable) === false) {
4975 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4978 * @param {boolean} [fromRight] Specify iterating from right to left.
4979 * @returns {Function} Returns the new base function.
4981 function createBaseFor(fromRight) {
4982 return function(object, iteratee, keysFunc) {
4984 iterable = Object(object),
4985 props = keysFunc(object),
4986 length = props.length;
4989 var key = props[fromRight ? length : ++index];
4990 if (iteratee(iterable[key], key, iterable) === false) {
4999 * Creates a function that wraps `func` to invoke it with the optional `this`
5000 * binding of `thisArg`.
5003 * @param {Function} func The function to wrap.
5004 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5005 * @param {*} [thisArg] The `this` binding of `func`.
5006 * @returns {Function} Returns the new wrapped function.
5008 function createBind(func, bitmask, thisArg) {
5009 var isBind = bitmask & WRAP_BIND_FLAG,
5010 Ctor = createCtor(func);
5012 function wrapper() {
5013 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5014 return fn.apply(isBind ? thisArg : this, arguments);
5020 * Creates a function like `_.lowerFirst`.
5023 * @param {string} methodName The name of the `String` case method to use.
5024 * @returns {Function} Returns the new case function.
5026 function createCaseFirst(methodName) {
5027 return function(string) {
5028 string = toString(string);
5030 var strSymbols = hasUnicode(string)
5031 ? stringToArray(string)
5034 var chr = strSymbols
5038 var trailing = strSymbols
5039 ? castSlice(strSymbols, 1).join('')
5042 return chr[methodName]() + trailing;
5047 * Creates a function like `_.camelCase`.
5050 * @param {Function} callback The function to combine each word.
5051 * @returns {Function} Returns the new compounder function.
5053 function createCompounder(callback) {
5054 return function(string) {
5055 return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
5060 * Creates a function that produces an instance of `Ctor` regardless of
5061 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5064 * @param {Function} Ctor The constructor to wrap.
5065 * @returns {Function} Returns the new wrapped function.
5067 function createCtor(Ctor) {
5069 // Use a `switch` statement to work with class constructors. See
5070 // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5071 // for more details.
5072 var args = arguments;
5073 switch (args.length) {
5074 case 0: return new Ctor;
5075 case 1: return new Ctor(args[0]);
5076 case 2: return new Ctor(args[0], args[1]);
5077 case 3: return new Ctor(args[0], args[1], args[2]);
5078 case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5079 case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5080 case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5081 case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5083 var thisBinding = baseCreate(Ctor.prototype),
5084 result = Ctor.apply(thisBinding, args);
5086 // Mimic the constructor's `return` behavior.
5087 // See https://es5.github.io/#x13.2.2 for more details.
5088 return isObject(result) ? result : thisBinding;
5093 * Creates a function that wraps `func` to enable currying.
5096 * @param {Function} func The function to wrap.
5097 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5098 * @param {number} arity The arity of `func`.
5099 * @returns {Function} Returns the new wrapped function.
5101 function createCurry(func, bitmask, arity) {
5102 var Ctor = createCtor(func);
5104 function wrapper() {
5105 var length = arguments.length,
5106 args = Array(length),
5108 placeholder = getHolder(wrapper);
5111 args[index] = arguments[index];
5113 var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5115 : replaceHolders(args, placeholder);
5117 length -= holders.length;
5118 if (length < arity) {
5119 return createRecurry(
5120 func, bitmask, createHybrid, wrapper.placeholder, undefined,
5121 args, holders, undefined, undefined, arity - length);
5123 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5124 return apply(fn, this, args);
5130 * Creates a `_.find` or `_.findLast` function.
5133 * @param {Function} findIndexFunc The function to find the collection index.
5134 * @returns {Function} Returns the new find function.
5136 function createFind(findIndexFunc) {
5137 return function(collection, predicate, fromIndex) {
5138 var iterable = Object(collection);
5139 if (!isArrayLike(collection)) {
5140 var iteratee = getIteratee(predicate, 3);
5141 collection = keys(collection);
5142 predicate = function(key) { return iteratee(iterable[key], key, iterable); };
5144 var index = findIndexFunc(collection, predicate, fromIndex);
5145 return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
5150 * Creates a `_.flow` or `_.flowRight` function.
5153 * @param {boolean} [fromRight] Specify iterating from right to left.
5154 * @returns {Function} Returns the new flow function.
5156 function createFlow(fromRight) {
5157 return flatRest(function(funcs) {
5158 var length = funcs.length,
5160 prereq = LodashWrapper.prototype.thru;
5166 var func = funcs[index];
5167 if (typeof func != 'function') {
5168 throw new TypeError(FUNC_ERROR_TEXT);
5170 if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
5171 var wrapper = new LodashWrapper([], true);
5174 index = wrapper ? index : length;
5175 while (++index < length) {
5176 func = funcs[index];
5178 var funcName = getFuncName(func),
5179 data = funcName == 'wrapper' ? getData(func) : undefined;
5181 if (data && isLaziable(data[0]) &&
5182 data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
5183 !data[4].length && data[9] == 1
5185 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
5187 wrapper = (func.length == 1 && isLaziable(func))
5188 ? wrapper[funcName]()
5189 : wrapper.thru(func);
5193 var args = arguments,
5196 if (wrapper && args.length == 1 &&
5197 isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
5198 return wrapper.plant(value).value();
5201 result = length ? funcs[index].apply(this, args) : value;
5203 while (++index < length) {
5204 result = funcs[index].call(this, result);
5212 * Creates a function that wraps `func` to invoke it with optional `this`
5213 * binding of `thisArg`, partial application, and currying.
5216 * @param {Function|string} func The function or method name to wrap.
5217 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5218 * @param {*} [thisArg] The `this` binding of `func`.
5219 * @param {Array} [partials] The arguments to prepend to those provided to
5221 * @param {Array} [holders] The `partials` placeholder indexes.
5222 * @param {Array} [partialsRight] The arguments to append to those provided
5223 * to the new function.
5224 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5225 * @param {Array} [argPos] The argument positions of the new function.
5226 * @param {number} [ary] The arity cap of `func`.
5227 * @param {number} [arity] The arity of `func`.
5228 * @returns {Function} Returns the new wrapped function.
5230 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5231 var isAry = bitmask & WRAP_ARY_FLAG,
5232 isBind = bitmask & WRAP_BIND_FLAG,
5233 isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
5234 isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
5235 isFlip = bitmask & WRAP_FLIP_FLAG,
5236 Ctor = isBindKey ? undefined : createCtor(func);
5238 function wrapper() {
5239 var length = arguments.length,
5240 args = Array(length),
5244 args[index] = arguments[index];
5247 var placeholder = getHolder(wrapper),
5248 holdersCount = countHolders(args, placeholder);
5251 args = composeArgs(args, partials, holders, isCurried);
5253 if (partialsRight) {
5254 args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
5256 length -= holdersCount;
5257 if (isCurried && length < arity) {
5258 var newHolders = replaceHolders(args, placeholder);
5259 return createRecurry(
5260 func, bitmask, createHybrid, wrapper.placeholder, thisArg,
5261 args, newHolders, argPos, ary, arity - length
5264 var thisBinding = isBind ? thisArg : this,
5265 fn = isBindKey ? thisBinding[func] : func;
5267 length = args.length;
5269 args = reorder(args, argPos);
5270 } else if (isFlip && length > 1) {
5273 if (isAry && ary < length) {
5276 if (this && this !== root && this instanceof wrapper) {
5277 fn = Ctor || createCtor(fn);
5279 return fn.apply(thisBinding, args);
5285 * Creates a function like `_.invertBy`.
5288 * @param {Function} setter The function to set accumulator values.
5289 * @param {Function} toIteratee The function to resolve iteratees.
5290 * @returns {Function} Returns the new inverter function.
5292 function createInverter(setter, toIteratee) {
5293 return function(object, iteratee) {
5294 return baseInverter(object, setter, toIteratee(iteratee), {});
5299 * Creates a function that performs a mathematical operation on two values.
5302 * @param {Function} operator The function to perform the operation.
5303 * @param {number} [defaultValue] The value used for `undefined` arguments.
5304 * @returns {Function} Returns the new mathematical operation function.
5306 function createMathOperation(operator, defaultValue) {
5307 return function(value, other) {
5309 if (value === undefined && other === undefined) {
5310 return defaultValue;
5312 if (value !== undefined) {
5315 if (other !== undefined) {
5316 if (result === undefined) {
5319 if (typeof value == 'string' || typeof other == 'string') {
5320 value = baseToString(value);
5321 other = baseToString(other);
5323 value = baseToNumber(value);
5324 other = baseToNumber(other);
5326 result = operator(value, other);
5333 * Creates a function like `_.over`.
5336 * @param {Function} arrayFunc The function to iterate over iteratees.
5337 * @returns {Function} Returns the new over function.
5339 function createOver(arrayFunc) {
5340 return flatRest(function(iteratees) {
5341 iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
5342 return baseRest(function(args) {
5344 return arrayFunc(iteratees, function(iteratee) {
5345 return apply(iteratee, thisArg, args);
5352 * Creates the padding for `string` based on `length`. The `chars` string
5353 * is truncated if the number of characters exceeds `length`.
5356 * @param {number} length The padding length.
5357 * @param {string} [chars=' '] The string used as padding.
5358 * @returns {string} Returns the padding for `string`.
5360 function createPadding(length, chars) {
5361 chars = chars === undefined ? ' ' : baseToString(chars);
5363 var charsLength = chars.length;
5364 if (charsLength < 2) {
5365 return charsLength ? baseRepeat(chars, length) : chars;
5367 var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
5368 return hasUnicode(chars)
5369 ? castSlice(stringToArray(result), 0, length).join('')
5370 : result.slice(0, length);
5374 * Creates a function that wraps `func` to invoke it with the `this` binding
5375 * of `thisArg` and `partials` prepended to the arguments it receives.
5378 * @param {Function} func The function to wrap.
5379 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5380 * @param {*} thisArg The `this` binding of `func`.
5381 * @param {Array} partials The arguments to prepend to those provided to
5383 * @returns {Function} Returns the new wrapped function.
5385 function createPartial(func, bitmask, thisArg, partials) {
5386 var isBind = bitmask & WRAP_BIND_FLAG,
5387 Ctor = createCtor(func);
5389 function wrapper() {
5391 argsLength = arguments.length,
5393 leftLength = partials.length,
5394 args = Array(leftLength + argsLength),
5395 fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5397 while (++leftIndex < leftLength) {
5398 args[leftIndex] = partials[leftIndex];
5400 while (argsLength--) {
5401 args[leftIndex++] = arguments[++argsIndex];
5403 return apply(fn, isBind ? thisArg : this, args);
5409 * Creates a `_.range` or `_.rangeRight` function.
5412 * @param {boolean} [fromRight] Specify iterating from right to left.
5413 * @returns {Function} Returns the new range function.
5415 function createRange(fromRight) {
5416 return function(start, end, step) {
5417 if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
5418 end = step = undefined;
5420 // Ensure the sign of `-0` is preserved.
5421 start = toFinite(start);
5422 if (end === undefined) {
5426 end = toFinite(end);
5428 step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
5429 return baseRange(start, end, step, fromRight);
5434 * Creates a function that performs a relational operation on two values.
5437 * @param {Function} operator The function to perform the operation.
5438 * @returns {Function} Returns the new relational operation function.
5440 function createRelationalOperation(operator) {
5441 return function(value, other) {
5442 if (!(typeof value == 'string' && typeof other == 'string')) {
5443 value = toNumber(value);
5444 other = toNumber(other);
5446 return operator(value, other);
5451 * Creates a function that wraps `func` to continue currying.
5454 * @param {Function} func The function to wrap.
5455 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5456 * @param {Function} wrapFunc The function to create the `func` wrapper.
5457 * @param {*} placeholder The placeholder value.
5458 * @param {*} [thisArg] The `this` binding of `func`.
5459 * @param {Array} [partials] The arguments to prepend to those provided to
5461 * @param {Array} [holders] The `partials` placeholder indexes.
5462 * @param {Array} [argPos] The argument positions of the new function.
5463 * @param {number} [ary] The arity cap of `func`.
5464 * @param {number} [arity] The arity of `func`.
5465 * @returns {Function} Returns the new wrapped function.
5467 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5468 var isCurry = bitmask & WRAP_CURRY_FLAG,
5469 newHolders = isCurry ? holders : undefined,
5470 newHoldersRight = isCurry ? undefined : holders,
5471 newPartials = isCurry ? partials : undefined,
5472 newPartialsRight = isCurry ? undefined : partials;
5474 bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
5475 bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
5477 if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
5478 bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
5481 func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
5482 newHoldersRight, argPos, ary, arity
5485 var result = wrapFunc.apply(undefined, newData);
5486 if (isLaziable(func)) {
5487 setData(result, newData);
5489 result.placeholder = placeholder;
5490 return setWrapToString(result, func, bitmask);
5494 * Creates a function like `_.round`.
5497 * @param {string} methodName The name of the `Math` method to use when rounding.
5498 * @returns {Function} Returns the new round function.
5500 function createRound(methodName) {
5501 var func = Math[methodName];
5502 return function(number, precision) {
5503 number = toNumber(number);
5504 precision = nativeMin(toInteger(precision), 292);
5506 // Shift with exponential notation to avoid floating-point issues.
5507 // See [MDN](https://mdn.io/round#Examples) for more details.
5508 var pair = (toString(number) + 'e').split('e'),
5509 value = func(pair[0] + 'e' + (+pair[1] + precision));
5511 pair = (toString(value) + 'e').split('e');
5512 return +(pair[0] + 'e' + (+pair[1] - precision));
5514 return func(number);
5519 * Creates a set object of `values`.
5522 * @param {Array} values The values to add to the set.
5523 * @returns {Object} Returns the new set.
5525 var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
5526 return new Set(values);
5530 * Creates a `_.toPairs` or `_.toPairsIn` function.
5533 * @param {Function} keysFunc The function to get the keys of a given object.
5534 * @returns {Function} Returns the new pairs function.
5536 function createToPairs(keysFunc) {
5537 return function(object) {
5538 var tag = getTag(object);
5539 if (tag == mapTag) {
5540 return mapToArray(object);
5542 if (tag == setTag) {
5543 return setToPairs(object);
5545 return baseToPairs(object, keysFunc(object));
5550 * Creates a function that either curries or invokes `func` with optional
5551 * `this` binding and partially applied arguments.
5554 * @param {Function|string} func The function or method name to wrap.
5555 * @param {number} bitmask The bitmask flags.
5558 * 4 - `_.curry` or `_.curryRight` of a bound function
5560 * 16 - `_.curryRight`
5562 * 64 - `_.partialRight`
5566 * @param {*} [thisArg] The `this` binding of `func`.
5567 * @param {Array} [partials] The arguments to be partially applied.
5568 * @param {Array} [holders] The `partials` placeholder indexes.
5569 * @param {Array} [argPos] The argument positions of the new function.
5570 * @param {number} [ary] The arity cap of `func`.
5571 * @param {number} [arity] The arity of `func`.
5572 * @returns {Function} Returns the new wrapped function.
5574 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5575 var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
5576 if (!isBindKey && typeof func != 'function') {
5577 throw new TypeError(FUNC_ERROR_TEXT);
5579 var length = partials ? partials.length : 0;
5581 bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
5582 partials = holders = undefined;
5584 ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5585 arity = arity === undefined ? arity : toInteger(arity);
5586 length -= holders ? holders.length : 0;
5588 if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
5589 var partialsRight = partials,
5590 holdersRight = holders;
5592 partials = holders = undefined;
5594 var data = isBindKey ? undefined : getData(func);
5597 func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5602 mergeData(newData, data);
5605 bitmask = newData[1];
5606 thisArg = newData[2];
5607 partials = newData[3];
5608 holders = newData[4];
5609 arity = newData[9] = newData[9] == null
5610 ? (isBindKey ? 0 : func.length)
5611 : nativeMax(newData[9] - length, 0);
5613 if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
5614 bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
5616 if (!bitmask || bitmask == WRAP_BIND_FLAG) {
5617 var result = createBind(func, bitmask, thisArg);
5618 } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
5619 result = createCurry(func, bitmask, arity);
5620 } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
5621 result = createPartial(func, bitmask, thisArg, partials);
5623 result = createHybrid.apply(undefined, newData);
5625 var setter = data ? baseSetData : setData;
5626 return setWrapToString(setter(result, newData), func, bitmask);
5630 * A specialized version of `baseIsEqualDeep` for arrays with support for
5631 * partial deep comparisons.
5634 * @param {Array} array The array to compare.
5635 * @param {Array} other The other array to compare.
5636 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5637 * @param {Function} customizer The function to customize comparisons.
5638 * @param {Function} equalFunc The function to determine equivalents of values.
5639 * @param {Object} stack Tracks traversed `array` and `other` objects.
5640 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5642 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
5643 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5644 arrLength = array.length,
5645 othLength = other.length;
5647 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5650 // Assume cyclic values are equal.
5651 var stacked = stack.get(array);
5652 if (stacked && stack.get(other)) {
5653 return stacked == other;
5657 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
5659 stack.set(array, other);
5660 stack.set(other, array);
5662 // Ignore non-index properties.
5663 while (++index < arrLength) {
5664 var arrValue = array[index],
5665 othValue = other[index];
5668 var compared = isPartial
5669 ? customizer(othValue, arrValue, index, other, array, stack)
5670 : customizer(arrValue, othValue, index, array, other, stack);
5672 if (compared !== undefined) {
5679 // Recursively compare arrays (susceptible to call stack limits).
5681 if (!arraySome(other, function(othValue, othIndex) {
5682 if (!cacheHas(seen, othIndex) &&
5683 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
5684 return seen.push(othIndex);
5691 arrValue === othValue ||
5692 equalFunc(arrValue, othValue, bitmask, customizer, stack)
5698 stack['delete'](array);
5699 stack['delete'](other);
5704 * A specialized version of `baseIsEqualDeep` for comparing objects of
5705 * the same `toStringTag`.
5707 * **Note:** This function only supports comparing values with tags of
5708 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5711 * @param {Object} object The object to compare.
5712 * @param {Object} other The other object to compare.
5713 * @param {string} tag The `toStringTag` of the objects to compare.
5714 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5715 * @param {Function} customizer The function to customize comparisons.
5716 * @param {Function} equalFunc The function to determine equivalents of values.
5717 * @param {Object} stack Tracks traversed `object` and `other` objects.
5718 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5720 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
5723 if ((object.byteLength != other.byteLength) ||
5724 (object.byteOffset != other.byteOffset)) {
5727 object = object.buffer;
5728 other = other.buffer;
5730 case arrayBufferTag:
5731 if ((object.byteLength != other.byteLength) ||
5732 !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5740 // Coerce booleans to `1` or `0` and dates to milliseconds.
5741 // Invalid dates are coerced to `NaN`.
5742 return eq(+object, +other);
5745 return object.name == other.name && object.message == other.message;
5749 // Coerce regexes to strings and treat strings, primitives and objects,
5750 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
5751 // for more details.
5752 return object == (other + '');
5755 var convert = mapToArray;
5758 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
5759 convert || (convert = setToArray);
5761 if (object.size != other.size && !isPartial) {
5764 // Assume cyclic values are equal.
5765 var stacked = stack.get(object);
5767 return stacked == other;
5769 bitmask |= COMPARE_UNORDERED_FLAG;
5771 // Recursively compare objects (susceptible to call stack limits).
5772 stack.set(object, other);
5773 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
5774 stack['delete'](object);
5778 if (symbolValueOf) {
5779 return symbolValueOf.call(object) == symbolValueOf.call(other);
5786 * A specialized version of `baseIsEqualDeep` for objects with support for
5787 * partial deep comparisons.
5790 * @param {Object} object The object to compare.
5791 * @param {Object} other The other object to compare.
5792 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5793 * @param {Function} customizer The function to customize comparisons.
5794 * @param {Function} equalFunc The function to determine equivalents of values.
5795 * @param {Object} stack Tracks traversed `object` and `other` objects.
5796 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5798 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
5799 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5800 objProps = keys(object),
5801 objLength = objProps.length,
5802 othProps = keys(other),
5803 othLength = othProps.length;
5805 if (objLength != othLength && !isPartial) {
5808 var index = objLength;
5810 var key = objProps[index];
5811 if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
5815 // Assume cyclic values are equal.
5816 var stacked = stack.get(object);
5817 if (stacked && stack.get(other)) {
5818 return stacked == other;
5821 stack.set(object, other);
5822 stack.set(other, object);
5824 var skipCtor = isPartial;
5825 while (++index < objLength) {
5826 key = objProps[index];
5827 var objValue = object[key],
5828 othValue = other[key];
5831 var compared = isPartial
5832 ? customizer(othValue, objValue, key, other, object, stack)
5833 : customizer(objValue, othValue, key, object, other, stack);
5835 // Recursively compare objects (susceptible to call stack limits).
5836 if (!(compared === undefined
5837 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
5843 skipCtor || (skipCtor = key == 'constructor');
5845 if (result && !skipCtor) {
5846 var objCtor = object.constructor,
5847 othCtor = other.constructor;
5849 // Non `Object` object instances with different constructors are not equal.
5850 if (objCtor != othCtor &&
5851 ('constructor' in object && 'constructor' in other) &&
5852 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5853 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5857 stack['delete'](object);
5858 stack['delete'](other);
5863 * A specialized version of `baseRest` which flattens the rest array.
5866 * @param {Function} func The function to apply a rest parameter to.
5867 * @returns {Function} Returns the new function.
5869 function flatRest(func) {
5870 return setToString(overRest(func, undefined, flatten), func + '');
5874 * Creates an array of own enumerable property names and symbols of `object`.
5877 * @param {Object} object The object to query.
5878 * @returns {Array} Returns the array of property names and symbols.
5880 function getAllKeys(object) {
5881 return baseGetAllKeys(object, keys, getSymbols);
5885 * Creates an array of own and inherited enumerable property names and
5886 * symbols of `object`.
5889 * @param {Object} object The object to query.
5890 * @returns {Array} Returns the array of property names and symbols.
5892 function getAllKeysIn(object) {
5893 return baseGetAllKeys(object, keysIn, getSymbolsIn);
5897 * Gets metadata for `func`.
5900 * @param {Function} func The function to query.
5901 * @returns {*} Returns the metadata for `func`.
5903 var getData = !metaMap ? noop : function(func) {
5904 return metaMap.get(func);
5908 * Gets the name of `func`.
5911 * @param {Function} func The function to query.
5912 * @returns {string} Returns the function name.
5914 function getFuncName(func) {
5915 var result = (func.name + ''),
5916 array = realNames[result],
5917 length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5920 var data = array[length],
5921 otherFunc = data.func;
5922 if (otherFunc == null || otherFunc == func) {
5930 * Gets the argument placeholder value for `func`.
5933 * @param {Function} func The function to inspect.
5934 * @returns {*} Returns the placeholder value.
5936 function getHolder(func) {
5937 var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5938 return object.placeholder;
5942 * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5943 * this function returns the custom method, otherwise it returns `baseIteratee`.
5944 * If arguments are provided, the chosen function is invoked with them and
5945 * its result is returned.
5948 * @param {*} [value] The value to convert to an iteratee.
5949 * @param {number} [arity] The arity of the created iteratee.
5950 * @returns {Function} Returns the chosen function or its result.
5952 function getIteratee() {
5953 var result = lodash.iteratee || iteratee;
5954 result = result === iteratee ? baseIteratee : result;
5955 return arguments.length ? result(arguments[0], arguments[1]) : result;
5959 * Gets the data for `map`.
5962 * @param {Object} map The map to query.
5963 * @param {string} key The reference key.
5964 * @returns {*} Returns the map data.
5966 function getMapData(map, key) {
5967 var data = map.__data__;
5968 return isKeyable(key)
5969 ? data[typeof key == 'string' ? 'string' : 'hash']
5974 * Gets the property names, values, and compare flags of `object`.
5977 * @param {Object} object The object to query.
5978 * @returns {Array} Returns the match data of `object`.
5980 function getMatchData(object) {
5981 var result = keys(object),
5982 length = result.length;
5985 var key = result[length],
5986 value = object[key];
5988 result[length] = [key, value, isStrictComparable(value)];
5994 * Gets the native function at `key` of `object`.
5997 * @param {Object} object The object to query.
5998 * @param {string} key The key of the method to get.
5999 * @returns {*} Returns the function if it's native, else `undefined`.
6001 function getNative(object, key) {
6002 var value = getValue(object, key);
6003 return baseIsNative(value) ? value : undefined;
6007 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6010 * @param {*} value The value to query.
6011 * @returns {string} Returns the raw `toStringTag`.
6013 function getRawTag(value) {
6014 var isOwn = hasOwnProperty.call(value, symToStringTag),
6015 tag = value[symToStringTag];
6018 value[symToStringTag] = undefined;
6019 var unmasked = true;
6022 var result = nativeObjectToString.call(value);
6025 value[symToStringTag] = tag;
6027 delete value[symToStringTag];
6034 * Creates an array of the own enumerable symbols of `object`.
6037 * @param {Object} object The object to query.
6038 * @returns {Array} Returns the array of symbols.
6040 var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;
6043 * Creates an array of the own and inherited enumerable symbols of `object`.
6046 * @param {Object} object The object to query.
6047 * @returns {Array} Returns the array of symbols.
6049 var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
6052 arrayPush(result, getSymbols(object));
6053 object = getPrototype(object);
6059 * Gets the `toStringTag` of `value`.
6062 * @param {*} value The value to query.
6063 * @returns {string} Returns the `toStringTag`.
6065 var getTag = baseGetTag;
6067 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
6068 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
6069 (Map && getTag(new Map) != mapTag) ||
6070 (Promise && getTag(Promise.resolve()) != promiseTag) ||
6071 (Set && getTag(new Set) != setTag) ||
6072 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
6073 getTag = function(value) {
6074 var result = baseGetTag(value),
6075 Ctor = result == objectTag ? value.constructor : undefined,
6076 ctorString = Ctor ? toSource(Ctor) : '';
6079 switch (ctorString) {
6080 case dataViewCtorString: return dataViewTag;
6081 case mapCtorString: return mapTag;
6082 case promiseCtorString: return promiseTag;
6083 case setCtorString: return setTag;
6084 case weakMapCtorString: return weakMapTag;
6092 * Gets the view, applying any `transforms` to the `start` and `end` positions.
6095 * @param {number} start The start of the view.
6096 * @param {number} end The end of the view.
6097 * @param {Array} transforms The transformations to apply to the view.
6098 * @returns {Object} Returns an object containing the `start` and `end`
6099 * positions of the view.
6101 function getView(start, end, transforms) {
6103 length = transforms.length;
6105 while (++index < length) {
6106 var data = transforms[index],
6109 switch (data.type) {
6110 case 'drop': start += size; break;
6111 case 'dropRight': end -= size; break;
6112 case 'take': end = nativeMin(end, start + size); break;
6113 case 'takeRight': start = nativeMax(start, end - size); break;
6116 return { 'start': start, 'end': end };
6120 * Extracts wrapper details from the `source` body comment.
6123 * @param {string} source The source to inspect.
6124 * @returns {Array} Returns the wrapper details.
6126 function getWrapDetails(source) {
6127 var match = source.match(reWrapDetails);
6128 return match ? match[1].split(reSplitDetails) : [];
6132 * Checks if `path` exists on `object`.
6135 * @param {Object} object The object to query.
6136 * @param {Array|string} path The path to check.
6137 * @param {Function} hasFunc The function to check properties.
6138 * @returns {boolean} Returns `true` if `path` exists, else `false`.
6140 function hasPath(object, path, hasFunc) {
6141 path = castPath(path, object);
6144 length = path.length,
6147 while (++index < length) {
6148 var key = toKey(path[index]);
6149 if (!(result = object != null && hasFunc(object, key))) {
6152 object = object[key];
6154 if (result || ++index != length) {
6157 length = object == null ? 0 : object.length;
6158 return !!length && isLength(length) && isIndex(key, length) &&
6159 (isArray(object) || isArguments(object));
6163 * Initializes an array clone.
6166 * @param {Array} array The array to clone.
6167 * @returns {Array} Returns the initialized clone.
6169 function initCloneArray(array) {
6170 var length = array.length,
6171 result = array.constructor(length);
6173 // Add properties assigned by `RegExp#exec`.
6174 if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
6175 result.index = array.index;
6176 result.input = array.input;
6182 * Initializes an object clone.
6185 * @param {Object} object The object to clone.
6186 * @returns {Object} Returns the initialized clone.
6188 function initCloneObject(object) {
6189 return (typeof object.constructor == 'function' && !isPrototype(object))
6190 ? baseCreate(getPrototype(object))
6195 * Initializes an object clone based on its `toStringTag`.
6197 * **Note:** This function only supports cloning values with tags of
6198 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6201 * @param {Object} object The object to clone.
6202 * @param {string} tag The `toStringTag` of the object to clone.
6203 * @param {Function} cloneFunc The function to clone values.
6204 * @param {boolean} [isDeep] Specify a deep clone.
6205 * @returns {Object} Returns the initialized clone.
6207 function initCloneByTag(object, tag, cloneFunc, isDeep) {
6208 var Ctor = object.constructor;
6210 case arrayBufferTag:
6211 return cloneArrayBuffer(object);
6215 return new Ctor(+object);
6218 return cloneDataView(object, isDeep);
6220 case float32Tag: case float64Tag:
6221 case int8Tag: case int16Tag: case int32Tag:
6222 case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
6223 return cloneTypedArray(object, isDeep);
6226 return cloneMap(object, isDeep, cloneFunc);
6230 return new Ctor(object);
6233 return cloneRegExp(object);
6236 return cloneSet(object, isDeep, cloneFunc);
6239 return cloneSymbol(object);
6244 * Inserts wrapper `details` in a comment at the top of the `source` body.
6247 * @param {string} source The source to modify.
6248 * @returns {Array} details The details to insert.
6249 * @returns {string} Returns the modified source.
6251 function insertWrapDetails(source, details) {
6252 var length = details.length;
6256 var lastIndex = length - 1;
6257 details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
6258 details = details.join(length > 2 ? ', ' : ' ');
6259 return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
6263 * Checks if `value` is a flattenable `arguments` object or array.
6266 * @param {*} value The value to check.
6267 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
6269 function isFlattenable(value) {
6270 return isArray(value) || isArguments(value) ||
6271 !!(spreadableSymbol && value && value[spreadableSymbol]);
6275 * Checks if `value` is a valid array-like index.
6278 * @param {*} value The value to check.
6279 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
6280 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
6282 function isIndex(value, length) {
6283 length = length == null ? MAX_SAFE_INTEGER : length;
6285 (typeof value == 'number' || reIsUint.test(value)) &&
6286 (value > -1 && value % 1 == 0 && value < length);
6290 * Checks if the given arguments are from an iteratee call.
6293 * @param {*} value The potential iteratee value argument.
6294 * @param {*} index The potential iteratee index or key argument.
6295 * @param {*} object The potential iteratee object argument.
6296 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
6299 function isIterateeCall(value, index, object) {
6300 if (!isObject(object)) {
6303 var type = typeof index;
6304 if (type == 'number'
6305 ? (isArrayLike(object) && isIndex(index, object.length))
6306 : (type == 'string' && index in object)
6308 return eq(object[index], value);
6314 * Checks if `value` is a property name and not a property path.
6317 * @param {*} value The value to check.
6318 * @param {Object} [object] The object to query keys on.
6319 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
6321 function isKey(value, object) {
6322 if (isArray(value)) {
6325 var type = typeof value;
6326 if (type == 'number' || type == 'symbol' || type == 'boolean' ||
6327 value == null || isSymbol(value)) {
6330 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
6331 (object != null && value in Object(object));
6335 * Checks if `value` is suitable for use as unique object key.
6338 * @param {*} value The value to check.
6339 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
6341 function isKeyable(value) {
6342 var type = typeof value;
6343 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
6344 ? (value !== '__proto__')
6349 * Checks if `func` has a lazy counterpart.
6352 * @param {Function} func The function to check.
6353 * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
6356 function isLaziable(func) {
6357 var funcName = getFuncName(func),
6358 other = lodash[funcName];
6360 if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
6363 if (func === other) {
6366 var data = getData(other);
6367 return !!data && func === data[0];
6371 * Checks if `func` has its source masked.
6374 * @param {Function} func The function to check.
6375 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
6377 function isMasked(func) {
6378 return !!maskSrcKey && (maskSrcKey in func);
6382 * Checks if `func` is capable of being masked.
6385 * @param {*} value The value to check.
6386 * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
6388 var isMaskable = coreJsData ? isFunction : stubFalse;
6391 * Checks if `value` is likely a prototype object.
6394 * @param {*} value The value to check.
6395 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
6397 function isPrototype(value) {
6398 var Ctor = value && value.constructor,
6399 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
6401 return value === proto;
6405 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
6408 * @param {*} value The value to check.
6409 * @returns {boolean} Returns `true` if `value` if suitable for strict
6410 * equality comparisons, else `false`.
6412 function isStrictComparable(value) {
6413 return value === value && !isObject(value);
6417 * A specialized version of `matchesProperty` for source values suitable
6418 * for strict equality comparisons, i.e. `===`.
6421 * @param {string} key The key of the property to get.
6422 * @param {*} srcValue The value to match.
6423 * @returns {Function} Returns the new spec function.
6425 function matchesStrictComparable(key, srcValue) {
6426 return function(object) {
6427 if (object == null) {
6430 return object[key] === srcValue &&
6431 (srcValue !== undefined || (key in Object(object)));
6436 * A specialized version of `_.memoize` which clears the memoized function's
6437 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
6440 * @param {Function} func The function to have its output memoized.
6441 * @returns {Function} Returns the new memoized function.
6443 function memoizeCapped(func) {
6444 var result = memoize(func, function(key) {
6445 if (cache.size === MAX_MEMOIZE_SIZE) {
6451 var cache = result.cache;
6456 * Merges the function metadata of `source` into `data`.
6458 * Merging metadata reduces the number of wrappers used to invoke a function.
6459 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
6460 * may be applied regardless of execution order. Methods like `_.ary` and
6461 * `_.rearg` modify function arguments, making the order in which they are
6462 * executed important, preventing the merging of metadata. However, we make
6463 * an exception for a safe combined case where curried functions have `_.ary`
6464 * and or `_.rearg` applied.
6467 * @param {Array} data The destination metadata.
6468 * @param {Array} source The source metadata.
6469 * @returns {Array} Returns `data`.
6471 function mergeData(data, source) {
6472 var bitmask = data[1],
6473 srcBitmask = source[1],
6474 newBitmask = bitmask | srcBitmask,
6475 isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
6478 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
6479 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
6480 ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
6482 // Exit early if metadata can't be merged.
6483 if (!(isCommon || isCombo)) {
6486 // Use source `thisArg` if available.
6487 if (srcBitmask & WRAP_BIND_FLAG) {
6488 data[2] = source[2];
6489 // Set when currying a bound function.
6490 newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
6492 // Compose partial arguments.
6493 var value = source[3];
6495 var partials = data[3];
6496 data[3] = partials ? composeArgs(partials, value, source[4]) : value;
6497 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
6499 // Compose partial right arguments.
6503 data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
6504 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
6506 // Use source `argPos` if available.
6511 // Use source `ary` if it's smaller.
6512 if (srcBitmask & WRAP_ARY_FLAG) {
6513 data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
6515 // Use source `arity` if one is not provided.
6516 if (data[9] == null) {
6517 data[9] = source[9];
6519 // Use source `func` and merge bitmasks.
6520 data[0] = source[0];
6521 data[1] = newBitmask;
6527 * Used by `_.defaultsDeep` to customize its `_.merge` use.
6530 * @param {*} objValue The destination value.
6531 * @param {*} srcValue The source value.
6532 * @param {string} key The key of the property to merge.
6533 * @param {Object} object The parent object of `objValue`.
6534 * @param {Object} source The parent object of `srcValue`.
6535 * @param {Object} [stack] Tracks traversed source values and their merged
6537 * @returns {*} Returns the value to assign.
6539 function mergeDefaults(objValue, srcValue, key, object, source, stack) {
6540 if (isObject(objValue) && isObject(srcValue)) {
6541 // Recursively merge objects and arrays (susceptible to call stack limits).
6542 stack.set(srcValue, objValue);
6543 baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
6544 stack['delete'](srcValue);
6550 * This function is like
6551 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
6552 * except that it includes inherited enumerable properties.
6555 * @param {Object} object The object to query.
6556 * @returns {Array} Returns the array of property names.
6558 function nativeKeysIn(object) {
6560 if (object != null) {
6561 for (var key in Object(object)) {
6569 * Converts `value` to a string using `Object.prototype.toString`.
6572 * @param {*} value The value to convert.
6573 * @returns {string} Returns the converted string.
6575 function objectToString(value) {
6576 return nativeObjectToString.call(value);
6580 * A specialized version of `baseRest` which transforms the rest array.
6583 * @param {Function} func The function to apply a rest parameter to.
6584 * @param {number} [start=func.length-1] The start position of the rest parameter.
6585 * @param {Function} transform The rest array transform.
6586 * @returns {Function} Returns the new function.
6588 function overRest(func, start, transform) {
6589 start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
6591 var args = arguments,
6593 length = nativeMax(args.length - start, 0),
6594 array = Array(length);
6596 while (++index < length) {
6597 array[index] = args[start + index];
6600 var otherArgs = Array(start + 1);
6601 while (++index < start) {
6602 otherArgs[index] = args[index];
6604 otherArgs[start] = transform(array);
6605 return apply(func, this, otherArgs);
6610 * Gets the parent value at `path` of `object`.
6613 * @param {Object} object The object to query.
6614 * @param {Array} path The path to get the parent value of.
6615 * @returns {*} Returns the parent value.
6617 function parent(object, path) {
6618 return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
6622 * Reorder `array` according to the specified indexes where the element at
6623 * the first index is assigned as the first element, the element at
6624 * the second index is assigned as the second element, and so on.
6627 * @param {Array} array The array to reorder.
6628 * @param {Array} indexes The arranged array indexes.
6629 * @returns {Array} Returns `array`.
6631 function reorder(array, indexes) {
6632 var arrLength = array.length,
6633 length = nativeMin(indexes.length, arrLength),
6634 oldArray = copyArray(array);
6637 var index = indexes[length];
6638 array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
6644 * Sets metadata for `func`.
6646 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
6647 * period of time, it will trip its breaker and transition to an identity
6648 * function to avoid garbage collection pauses in V8. See
6649 * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6653 * @param {Function} func The function to associate metadata with.
6654 * @param {*} data The metadata.
6655 * @returns {Function} Returns `func`.
6657 var setData = shortOut(baseSetData);
6660 * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
6663 * @param {Function} func The function to delay.
6664 * @param {number} wait The number of milliseconds to delay invocation.
6665 * @returns {number|Object} Returns the timer id or timeout object.
6667 var setTimeout = ctxSetTimeout || function(func, wait) {
6668 return root.setTimeout(func, wait);
6672 * Sets the `toString` method of `func` to return `string`.
6675 * @param {Function} func The function to modify.
6676 * @param {Function} string The `toString` result.
6677 * @returns {Function} Returns `func`.
6679 var setToString = shortOut(baseSetToString);
6682 * Sets the `toString` method of `wrapper` to mimic the source of `reference`
6683 * with wrapper details in a comment at the top of the source body.
6686 * @param {Function} wrapper The function to modify.
6687 * @param {Function} reference The reference function.
6688 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6689 * @returns {Function} Returns `wrapper`.
6691 function setWrapToString(wrapper, reference, bitmask) {
6692 var source = (reference + '');
6693 return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
6697 * Creates a function that'll short out and invoke `identity` instead
6698 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
6702 * @param {Function} func The function to restrict.
6703 * @returns {Function} Returns the new shortable function.
6705 function shortOut(func) {
6710 var stamp = nativeNow(),
6711 remaining = HOT_SPAN - (stamp - lastCalled);
6714 if (remaining > 0) {
6715 if (++count >= HOT_COUNT) {
6716 return arguments[0];
6721 return func.apply(undefined, arguments);
6726 * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
6729 * @param {Array} array The array to shuffle.
6730 * @param {number} [size=array.length] The size of `array`.
6731 * @returns {Array} Returns `array`.
6733 function shuffleSelf(array, size) {
6735 length = array.length,
6736 lastIndex = length - 1;
6738 size = size === undefined ? length : size;
6739 while (++index < size) {
6740 var rand = baseRandom(index, lastIndex),
6741 value = array[rand];
6743 array[rand] = array[index];
6744 array[index] = value;
6746 array.length = size;
6751 * Converts `string` to a property path array.
6754 * @param {string} string The string to convert.
6755 * @returns {Array} Returns the property path array.
6757 var stringToPath = memoizeCapped(function(string) {
6759 if (reLeadingDot.test(string)) {
6762 string.replace(rePropName, function(match, number, quote, string) {
6763 result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
6769 * Converts `value` to a string key if it's not a string or symbol.
6772 * @param {*} value The value to inspect.
6773 * @returns {string|symbol} Returns the key.
6775 function toKey(value) {
6776 if (typeof value == 'string' || isSymbol(value)) {
6779 var result = (value + '');
6780 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6784 * Converts `func` to its source code.
6787 * @param {Function} func The function to convert.
6788 * @returns {string} Returns the source code.
6790 function toSource(func) {
6793 return funcToString.call(func);
6803 * Updates wrapper `details` based on `bitmask` flags.
6806 * @returns {Array} details The details to modify.
6807 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6808 * @returns {Array} Returns `details`.
6810 function updateWrapDetails(details, bitmask) {
6811 arrayEach(wrapFlags, function(pair) {
6812 var value = '_.' + pair[0];
6813 if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
6814 details.push(value);
6817 return details.sort();
6821 * Creates a clone of `wrapper`.
6824 * @param {Object} wrapper The wrapper to clone.
6825 * @returns {Object} Returns the cloned wrapper.
6827 function wrapperClone(wrapper) {
6828 if (wrapper instanceof LazyWrapper) {
6829 return wrapper.clone();
6831 var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6832 result.__actions__ = copyArray(wrapper.__actions__);
6833 result.__index__ = wrapper.__index__;
6834 result.__values__ = wrapper.__values__;
6838 /*------------------------------------------------------------------------*/
6841 * Creates an array of elements split into groups the length of `size`.
6842 * If `array` can't be split evenly, the final chunk will be the remaining
6849 * @param {Array} array The array to process.
6850 * @param {number} [size=1] The length of each chunk
6851 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6852 * @returns {Array} Returns the new array of chunks.
6855 * _.chunk(['a', 'b', 'c', 'd'], 2);
6856 * // => [['a', 'b'], ['c', 'd']]
6858 * _.chunk(['a', 'b', 'c', 'd'], 3);
6859 * // => [['a', 'b', 'c'], ['d']]
6861 function chunk(array, size, guard) {
6862 if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6865 size = nativeMax(toInteger(size), 0);
6867 var length = array == null ? 0 : array.length;
6868 if (!length || size < 1) {
6873 result = Array(nativeCeil(length / size));
6875 while (index < length) {
6876 result[resIndex++] = baseSlice(array, index, (index += size));
6882 * Creates an array with all falsey values removed. The values `false`, `null`,
6883 * `0`, `""`, `undefined`, and `NaN` are falsey.
6889 * @param {Array} array The array to compact.
6890 * @returns {Array} Returns the new array of filtered values.
6893 * _.compact([0, 1, false, 2, '', 3]);
6896 function compact(array) {
6898 length = array == null ? 0 : array.length,
6902 while (++index < length) {
6903 var value = array[index];
6905 result[resIndex++] = value;
6912 * Creates a new array concatenating `array` with any additional arrays
6919 * @param {Array} array The array to concatenate.
6920 * @param {...*} [values] The values to concatenate.
6921 * @returns {Array} Returns the new concatenated array.
6925 * var other = _.concat(array, 2, [3], [[4]]);
6927 * console.log(other);
6928 * // => [1, 2, 3, [4]]
6930 * console.log(array);
6934 var length = arguments.length;
6938 var args = Array(length - 1),
6939 array = arguments[0],
6943 args[index - 1] = arguments[index];
6945 return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
6949 * Creates an array of `array` values not included in the other given arrays
6950 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
6951 * for equality comparisons. The order and references of result values are
6952 * determined by the first array.
6954 * **Note:** Unlike `_.pullAll`, this method returns a new array.
6960 * @param {Array} array The array to inspect.
6961 * @param {...Array} [values] The values to exclude.
6962 * @returns {Array} Returns the new array of filtered values.
6963 * @see _.without, _.xor
6966 * _.difference([2, 1], [2, 3]);
6969 var difference = baseRest(function(array, values) {
6970 return isArrayLikeObject(array)
6971 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6976 * This method is like `_.difference` except that it accepts `iteratee` which
6977 * is invoked for each element of `array` and `values` to generate the criterion
6978 * by which they're compared. The order and references of result values are
6979 * determined by the first array. The iteratee is invoked with one argument:
6982 * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
6988 * @param {Array} array The array to inspect.
6989 * @param {...Array} [values] The values to exclude.
6990 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
6991 * @returns {Array} Returns the new array of filtered values.
6994 * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
6997 * // The `_.property` iteratee shorthand.
6998 * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
6999 * // => [{ 'x': 2 }]
7001 var differenceBy = baseRest(function(array, values) {
7002 var iteratee = last(values);
7003 if (isArrayLikeObject(iteratee)) {
7004 iteratee = undefined;
7006 return isArrayLikeObject(array)
7007 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
7012 * This method is like `_.difference` except that it accepts `comparator`
7013 * which is invoked to compare elements of `array` to `values`. The order and
7014 * references of result values are determined by the first array. The comparator
7015 * is invoked with two arguments: (arrVal, othVal).
7017 * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
7023 * @param {Array} array The array to inspect.
7024 * @param {...Array} [values] The values to exclude.
7025 * @param {Function} [comparator] The comparator invoked per element.
7026 * @returns {Array} Returns the new array of filtered values.
7029 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7031 * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
7032 * // => [{ 'x': 2, 'y': 1 }]
7034 var differenceWith = baseRest(function(array, values) {
7035 var comparator = last(values);
7036 if (isArrayLikeObject(comparator)) {
7037 comparator = undefined;
7039 return isArrayLikeObject(array)
7040 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
7045 * Creates a slice of `array` with `n` elements dropped from the beginning.
7051 * @param {Array} array The array to query.
7052 * @param {number} [n=1] The number of elements to drop.
7053 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7054 * @returns {Array} Returns the slice of `array`.
7057 * _.drop([1, 2, 3]);
7060 * _.drop([1, 2, 3], 2);
7063 * _.drop([1, 2, 3], 5);
7066 * _.drop([1, 2, 3], 0);
7069 function drop(array, n, guard) {
7070 var length = array == null ? 0 : array.length;
7074 n = (guard || n === undefined) ? 1 : toInteger(n);
7075 return baseSlice(array, n < 0 ? 0 : n, length);
7079 * Creates a slice of `array` with `n` elements dropped from the end.
7085 * @param {Array} array The array to query.
7086 * @param {number} [n=1] The number of elements to drop.
7087 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7088 * @returns {Array} Returns the slice of `array`.
7091 * _.dropRight([1, 2, 3]);
7094 * _.dropRight([1, 2, 3], 2);
7097 * _.dropRight([1, 2, 3], 5);
7100 * _.dropRight([1, 2, 3], 0);
7103 function dropRight(array, n, guard) {
7104 var length = array == null ? 0 : array.length;
7108 n = (guard || n === undefined) ? 1 : toInteger(n);
7110 return baseSlice(array, 0, n < 0 ? 0 : n);
7114 * Creates a slice of `array` excluding elements dropped from the end.
7115 * Elements are dropped until `predicate` returns falsey. The predicate is
7116 * invoked with three arguments: (value, index, array).
7122 * @param {Array} array The array to query.
7123 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7124 * @returns {Array} Returns the slice of `array`.
7128 * { 'user': 'barney', 'active': true },
7129 * { 'user': 'fred', 'active': false },
7130 * { 'user': 'pebbles', 'active': false }
7133 * _.dropRightWhile(users, function(o) { return !o.active; });
7134 * // => objects for ['barney']
7136 * // The `_.matches` iteratee shorthand.
7137 * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
7138 * // => objects for ['barney', 'fred']
7140 * // The `_.matchesProperty` iteratee shorthand.
7141 * _.dropRightWhile(users, ['active', false]);
7142 * // => objects for ['barney']
7144 * // The `_.property` iteratee shorthand.
7145 * _.dropRightWhile(users, 'active');
7146 * // => objects for ['barney', 'fred', 'pebbles']
7148 function dropRightWhile(array, predicate) {
7149 return (array && array.length)
7150 ? baseWhile(array, getIteratee(predicate, 3), true, true)
7155 * Creates a slice of `array` excluding elements dropped from the beginning.
7156 * Elements are dropped until `predicate` returns falsey. The predicate is
7157 * invoked with three arguments: (value, index, array).
7163 * @param {Array} array The array to query.
7164 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7165 * @returns {Array} Returns the slice of `array`.
7169 * { 'user': 'barney', 'active': false },
7170 * { 'user': 'fred', 'active': false },
7171 * { 'user': 'pebbles', 'active': true }
7174 * _.dropWhile(users, function(o) { return !o.active; });
7175 * // => objects for ['pebbles']
7177 * // The `_.matches` iteratee shorthand.
7178 * _.dropWhile(users, { 'user': 'barney', 'active': false });
7179 * // => objects for ['fred', 'pebbles']
7181 * // The `_.matchesProperty` iteratee shorthand.
7182 * _.dropWhile(users, ['active', false]);
7183 * // => objects for ['pebbles']
7185 * // The `_.property` iteratee shorthand.
7186 * _.dropWhile(users, 'active');
7187 * // => objects for ['barney', 'fred', 'pebbles']
7189 function dropWhile(array, predicate) {
7190 return (array && array.length)
7191 ? baseWhile(array, getIteratee(predicate, 3), true)
7196 * Fills elements of `array` with `value` from `start` up to, but not
7199 * **Note:** This method mutates `array`.
7205 * @param {Array} array The array to fill.
7206 * @param {*} value The value to fill `array` with.
7207 * @param {number} [start=0] The start position.
7208 * @param {number} [end=array.length] The end position.
7209 * @returns {Array} Returns `array`.
7212 * var array = [1, 2, 3];
7214 * _.fill(array, 'a');
7215 * console.log(array);
7216 * // => ['a', 'a', 'a']
7218 * _.fill(Array(3), 2);
7221 * _.fill([4, 6, 8, 10], '*', 1, 3);
7222 * // => [4, '*', '*', 10]
7224 function fill(array, value, start, end) {
7225 var length = array == null ? 0 : array.length;
7229 if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
7233 return baseFill(array, value, start, end);
7237 * This method is like `_.find` except that it returns the index of the first
7238 * element `predicate` returns truthy for instead of the element itself.
7244 * @param {Array} array The array to inspect.
7245 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7246 * @param {number} [fromIndex=0] The index to search from.
7247 * @returns {number} Returns the index of the found element, else `-1`.
7251 * { 'user': 'barney', 'active': false },
7252 * { 'user': 'fred', 'active': false },
7253 * { 'user': 'pebbles', 'active': true }
7256 * _.findIndex(users, function(o) { return o.user == 'barney'; });
7259 * // The `_.matches` iteratee shorthand.
7260 * _.findIndex(users, { 'user': 'fred', 'active': false });
7263 * // The `_.matchesProperty` iteratee shorthand.
7264 * _.findIndex(users, ['active', false]);
7267 * // The `_.property` iteratee shorthand.
7268 * _.findIndex(users, 'active');
7271 function findIndex(array, predicate, fromIndex) {
7272 var length = array == null ? 0 : array.length;
7276 var index = fromIndex == null ? 0 : toInteger(fromIndex);
7278 index = nativeMax(length + index, 0);
7280 return baseFindIndex(array, getIteratee(predicate, 3), index);
7284 * This method is like `_.findIndex` except that it iterates over elements
7285 * of `collection` from right to left.
7291 * @param {Array} array The array to inspect.
7292 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7293 * @param {number} [fromIndex=array.length-1] The index to search from.
7294 * @returns {number} Returns the index of the found element, else `-1`.
7298 * { 'user': 'barney', 'active': true },
7299 * { 'user': 'fred', 'active': false },
7300 * { 'user': 'pebbles', 'active': false }
7303 * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
7306 * // The `_.matches` iteratee shorthand.
7307 * _.findLastIndex(users, { 'user': 'barney', 'active': true });
7310 * // The `_.matchesProperty` iteratee shorthand.
7311 * _.findLastIndex(users, ['active', false]);
7314 * // The `_.property` iteratee shorthand.
7315 * _.findLastIndex(users, 'active');
7318 function findLastIndex(array, predicate, fromIndex) {
7319 var length = array == null ? 0 : array.length;
7323 var index = length - 1;
7324 if (fromIndex !== undefined) {
7325 index = toInteger(fromIndex);
7326 index = fromIndex < 0
7327 ? nativeMax(length + index, 0)
7328 : nativeMin(index, length - 1);
7330 return baseFindIndex(array, getIteratee(predicate, 3), index, true);
7334 * Flattens `array` a single level deep.
7340 * @param {Array} array The array to flatten.
7341 * @returns {Array} Returns the new flattened array.
7344 * _.flatten([1, [2, [3, [4]], 5]]);
7345 * // => [1, 2, [3, [4]], 5]
7347 function flatten(array) {
7348 var length = array == null ? 0 : array.length;
7349 return length ? baseFlatten(array, 1) : [];
7353 * Recursively flattens `array`.
7359 * @param {Array} array The array to flatten.
7360 * @returns {Array} Returns the new flattened array.
7363 * _.flattenDeep([1, [2, [3, [4]], 5]]);
7364 * // => [1, 2, 3, 4, 5]
7366 function flattenDeep(array) {
7367 var length = array == null ? 0 : array.length;
7368 return length ? baseFlatten(array, INFINITY) : [];
7372 * Recursively flatten `array` up to `depth` times.
7378 * @param {Array} array The array to flatten.
7379 * @param {number} [depth=1] The maximum recursion depth.
7380 * @returns {Array} Returns the new flattened array.
7383 * var array = [1, [2, [3, [4]], 5]];
7385 * _.flattenDepth(array, 1);
7386 * // => [1, 2, [3, [4]], 5]
7388 * _.flattenDepth(array, 2);
7389 * // => [1, 2, 3, [4], 5]
7391 function flattenDepth(array, depth) {
7392 var length = array == null ? 0 : array.length;
7396 depth = depth === undefined ? 1 : toInteger(depth);
7397 return baseFlatten(array, depth);
7401 * The inverse of `_.toPairs`; this method returns an object composed
7402 * from key-value `pairs`.
7408 * @param {Array} pairs The key-value pairs.
7409 * @returns {Object} Returns the new object.
7412 * _.fromPairs([['a', 1], ['b', 2]]);
7413 * // => { 'a': 1, 'b': 2 }
7415 function fromPairs(pairs) {
7417 length = pairs == null ? 0 : pairs.length,
7420 while (++index < length) {
7421 var pair = pairs[index];
7422 result[pair[0]] = pair[1];
7428 * Gets the first element of `array`.
7435 * @param {Array} array The array to query.
7436 * @returns {*} Returns the first element of `array`.
7439 * _.head([1, 2, 3]);
7445 function head(array) {
7446 return (array && array.length) ? array[0] : undefined;
7450 * Gets the index at which the first occurrence of `value` is found in `array`
7451 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7452 * for equality comparisons. If `fromIndex` is negative, it's used as the
7453 * offset from the end of `array`.
7459 * @param {Array} array The array to inspect.
7460 * @param {*} value The value to search for.
7461 * @param {number} [fromIndex=0] The index to search from.
7462 * @returns {number} Returns the index of the matched value, else `-1`.
7465 * _.indexOf([1, 2, 1, 2], 2);
7468 * // Search from the `fromIndex`.
7469 * _.indexOf([1, 2, 1, 2], 2, 2);
7472 function indexOf(array, value, fromIndex) {
7473 var length = array == null ? 0 : array.length;
7477 var index = fromIndex == null ? 0 : toInteger(fromIndex);
7479 index = nativeMax(length + index, 0);
7481 return baseIndexOf(array, value, index);
7485 * Gets all but the last element of `array`.
7491 * @param {Array} array The array to query.
7492 * @returns {Array} Returns the slice of `array`.
7495 * _.initial([1, 2, 3]);
7498 function initial(array) {
7499 var length = array == null ? 0 : array.length;
7500 return length ? baseSlice(array, 0, -1) : [];
7504 * Creates an array of unique values that are included in all given arrays
7505 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7506 * for equality comparisons. The order and references of result values are
7507 * determined by the first array.
7513 * @param {...Array} [arrays] The arrays to inspect.
7514 * @returns {Array} Returns the new array of intersecting values.
7517 * _.intersection([2, 1], [2, 3]);
7520 var intersection = baseRest(function(arrays) {
7521 var mapped = arrayMap(arrays, castArrayLikeObject);
7522 return (mapped.length && mapped[0] === arrays[0])
7523 ? baseIntersection(mapped)
7528 * This method is like `_.intersection` except that it accepts `iteratee`
7529 * which is invoked for each element of each `arrays` to generate the criterion
7530 * by which they're compared. The order and references of result values are
7531 * determined by the first array. The iteratee is invoked with one argument:
7538 * @param {...Array} [arrays] The arrays to inspect.
7539 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7540 * @returns {Array} Returns the new array of intersecting values.
7543 * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7546 * // The `_.property` iteratee shorthand.
7547 * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7548 * // => [{ 'x': 1 }]
7550 var intersectionBy = baseRest(function(arrays) {
7551 var iteratee = last(arrays),
7552 mapped = arrayMap(arrays, castArrayLikeObject);
7554 if (iteratee === last(mapped)) {
7555 iteratee = undefined;
7559 return (mapped.length && mapped[0] === arrays[0])
7560 ? baseIntersection(mapped, getIteratee(iteratee, 2))
7565 * This method is like `_.intersection` except that it accepts `comparator`
7566 * which is invoked to compare elements of `arrays`. The order and references
7567 * of result values are determined by the first array. The comparator is
7568 * invoked with two arguments: (arrVal, othVal).
7574 * @param {...Array} [arrays] The arrays to inspect.
7575 * @param {Function} [comparator] The comparator invoked per element.
7576 * @returns {Array} Returns the new array of intersecting values.
7579 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7580 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7582 * _.intersectionWith(objects, others, _.isEqual);
7583 * // => [{ 'x': 1, 'y': 2 }]
7585 var intersectionWith = baseRest(function(arrays) {
7586 var comparator = last(arrays),
7587 mapped = arrayMap(arrays, castArrayLikeObject);
7589 comparator = typeof comparator == 'function' ? comparator : undefined;
7593 return (mapped.length && mapped[0] === arrays[0])
7594 ? baseIntersection(mapped, undefined, comparator)
7599 * Converts all elements in `array` into a string separated by `separator`.
7605 * @param {Array} array The array to convert.
7606 * @param {string} [separator=','] The element separator.
7607 * @returns {string} Returns the joined string.
7610 * _.join(['a', 'b', 'c'], '~');
7613 function join(array, separator) {
7614 return array == null ? '' : nativeJoin.call(array, separator);
7618 * Gets the last element of `array`.
7624 * @param {Array} array The array to query.
7625 * @returns {*} Returns the last element of `array`.
7628 * _.last([1, 2, 3]);
7631 function last(array) {
7632 var length = array == null ? 0 : array.length;
7633 return length ? array[length - 1] : undefined;
7637 * This method is like `_.indexOf` except that it iterates over elements of
7638 * `array` from right to left.
7644 * @param {Array} array The array to inspect.
7645 * @param {*} value The value to search for.
7646 * @param {number} [fromIndex=array.length-1] The index to search from.
7647 * @returns {number} Returns the index of the matched value, else `-1`.
7650 * _.lastIndexOf([1, 2, 1, 2], 2);
7653 * // Search from the `fromIndex`.
7654 * _.lastIndexOf([1, 2, 1, 2], 2, 2);
7657 function lastIndexOf(array, value, fromIndex) {
7658 var length = array == null ? 0 : array.length;
7663 if (fromIndex !== undefined) {
7664 index = toInteger(fromIndex);
7665 index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
7667 return value === value
7668 ? strictLastIndexOf(array, value, index)
7669 : baseFindIndex(array, baseIsNaN, index, true);
7673 * Gets the element at index `n` of `array`. If `n` is negative, the nth
7674 * element from the end is returned.
7680 * @param {Array} array The array to query.
7681 * @param {number} [n=0] The index of the element to return.
7682 * @returns {*} Returns the nth element of `array`.
7685 * var array = ['a', 'b', 'c', 'd'];
7693 function nth(array, n) {
7694 return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
7698 * Removes all given values from `array` using
7699 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7700 * for equality comparisons.
7702 * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
7703 * to remove elements from an array by predicate.
7709 * @param {Array} array The array to modify.
7710 * @param {...*} [values] The values to remove.
7711 * @returns {Array} Returns `array`.
7714 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7716 * _.pull(array, 'a', 'c');
7717 * console.log(array);
7720 var pull = baseRest(pullAll);
7723 * This method is like `_.pull` except that it accepts an array of values to remove.
7725 * **Note:** Unlike `_.difference`, this method mutates `array`.
7731 * @param {Array} array The array to modify.
7732 * @param {Array} values The values to remove.
7733 * @returns {Array} Returns `array`.
7736 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7738 * _.pullAll(array, ['a', 'c']);
7739 * console.log(array);
7742 function pullAll(array, values) {
7743 return (array && array.length && values && values.length)
7744 ? basePullAll(array, values)
7749 * This method is like `_.pullAll` except that it accepts `iteratee` which is
7750 * invoked for each element of `array` and `values` to generate the criterion
7751 * by which they're compared. The iteratee is invoked with one argument: (value).
7753 * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7759 * @param {Array} array The array to modify.
7760 * @param {Array} values The values to remove.
7761 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7762 * @returns {Array} Returns `array`.
7765 * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7767 * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7768 * console.log(array);
7769 * // => [{ 'x': 2 }]
7771 function pullAllBy(array, values, iteratee) {
7772 return (array && array.length && values && values.length)
7773 ? basePullAll(array, values, getIteratee(iteratee, 2))
7778 * This method is like `_.pullAll` except that it accepts `comparator` which
7779 * is invoked to compare elements of `array` to `values`. The comparator is
7780 * invoked with two arguments: (arrVal, othVal).
7782 * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7788 * @param {Array} array The array to modify.
7789 * @param {Array} values The values to remove.
7790 * @param {Function} [comparator] The comparator invoked per element.
7791 * @returns {Array} Returns `array`.
7794 * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7796 * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7797 * console.log(array);
7798 * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7800 function pullAllWith(array, values, comparator) {
7801 return (array && array.length && values && values.length)
7802 ? basePullAll(array, values, undefined, comparator)
7807 * Removes elements from `array` corresponding to `indexes` and returns an
7808 * array of removed elements.
7810 * **Note:** Unlike `_.at`, this method mutates `array`.
7816 * @param {Array} array The array to modify.
7817 * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7818 * @returns {Array} Returns the new array of removed elements.
7821 * var array = ['a', 'b', 'c', 'd'];
7822 * var pulled = _.pullAt(array, [1, 3]);
7824 * console.log(array);
7827 * console.log(pulled);
7830 var pullAt = flatRest(function(array, indexes) {
7831 var length = array == null ? 0 : array.length,
7832 result = baseAt(array, indexes);
7834 basePullAt(array, arrayMap(indexes, function(index) {
7835 return isIndex(index, length) ? +index : index;
7836 }).sort(compareAscending));
7842 * Removes all elements from `array` that `predicate` returns truthy for
7843 * and returns an array of the removed elements. The predicate is invoked
7844 * with three arguments: (value, index, array).
7846 * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7847 * to pull elements from an array by value.
7853 * @param {Array} array The array to modify.
7854 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7855 * @returns {Array} Returns the new array of removed elements.
7858 * var array = [1, 2, 3, 4];
7859 * var evens = _.remove(array, function(n) {
7860 * return n % 2 == 0;
7863 * console.log(array);
7866 * console.log(evens);
7869 function remove(array, predicate) {
7871 if (!(array && array.length)) {
7876 length = array.length;
7878 predicate = getIteratee(predicate, 3);
7879 while (++index < length) {
7880 var value = array[index];
7881 if (predicate(value, index, array)) {
7883 indexes.push(index);
7886 basePullAt(array, indexes);
7891 * Reverses `array` so that the first element becomes the last, the second
7892 * element becomes the second to last, and so on.
7894 * **Note:** This method mutates `array` and is based on
7895 * [`Array#reverse`](https://mdn.io/Array/reverse).
7901 * @param {Array} array The array to modify.
7902 * @returns {Array} Returns `array`.
7905 * var array = [1, 2, 3];
7910 * console.log(array);
7913 function reverse(array) {
7914 return array == null ? array : nativeReverse.call(array);
7918 * Creates a slice of `array` from `start` up to, but not including, `end`.
7920 * **Note:** This method is used instead of
7921 * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7928 * @param {Array} array The array to slice.
7929 * @param {number} [start=0] The start position.
7930 * @param {number} [end=array.length] The end position.
7931 * @returns {Array} Returns the slice of `array`.
7933 function slice(array, start, end) {
7934 var length = array == null ? 0 : array.length;
7938 if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7943 start = start == null ? 0 : toInteger(start);
7944 end = end === undefined ? length : toInteger(end);
7946 return baseSlice(array, start, end);
7950 * Uses a binary search to determine the lowest index at which `value`
7951 * should be inserted into `array` in order to maintain its sort order.
7957 * @param {Array} array The sorted array to inspect.
7958 * @param {*} value The value to evaluate.
7959 * @returns {number} Returns the index at which `value` should be inserted
7963 * _.sortedIndex([30, 50], 40);
7966 function sortedIndex(array, value) {
7967 return baseSortedIndex(array, value);
7971 * This method is like `_.sortedIndex` except that it accepts `iteratee`
7972 * which is invoked for `value` and each element of `array` to compute their
7973 * sort ranking. The iteratee is invoked with one argument: (value).
7979 * @param {Array} array The sorted array to inspect.
7980 * @param {*} value The value to evaluate.
7981 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7982 * @returns {number} Returns the index at which `value` should be inserted
7986 * var objects = [{ 'x': 4 }, { 'x': 5 }];
7988 * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
7991 * // The `_.property` iteratee shorthand.
7992 * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
7995 function sortedIndexBy(array, value, iteratee) {
7996 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
8000 * This method is like `_.indexOf` except that it performs a binary
8001 * search on a sorted `array`.
8007 * @param {Array} array The array to inspect.
8008 * @param {*} value The value to search for.
8009 * @returns {number} Returns the index of the matched value, else `-1`.
8012 * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
8015 function sortedIndexOf(array, value) {
8016 var length = array == null ? 0 : array.length;
8018 var index = baseSortedIndex(array, value);
8019 if (index < length && eq(array[index], value)) {
8027 * This method is like `_.sortedIndex` except that it returns the highest
8028 * index at which `value` should be inserted into `array` in order to
8029 * maintain its sort order.
8035 * @param {Array} array The sorted array to inspect.
8036 * @param {*} value The value to evaluate.
8037 * @returns {number} Returns the index at which `value` should be inserted
8041 * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
8044 function sortedLastIndex(array, value) {
8045 return baseSortedIndex(array, value, true);
8049 * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
8050 * which is invoked for `value` and each element of `array` to compute their
8051 * sort ranking. The iteratee is invoked with one argument: (value).
8057 * @param {Array} array The sorted array to inspect.
8058 * @param {*} value The value to evaluate.
8059 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8060 * @returns {number} Returns the index at which `value` should be inserted
8064 * var objects = [{ 'x': 4 }, { 'x': 5 }];
8066 * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8069 * // The `_.property` iteratee shorthand.
8070 * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
8073 function sortedLastIndexBy(array, value, iteratee) {
8074 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
8078 * This method is like `_.lastIndexOf` except that it performs a binary
8079 * search on a sorted `array`.
8085 * @param {Array} array The array to inspect.
8086 * @param {*} value The value to search for.
8087 * @returns {number} Returns the index of the matched value, else `-1`.
8090 * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
8093 function sortedLastIndexOf(array, value) {
8094 var length = array == null ? 0 : array.length;
8096 var index = baseSortedIndex(array, value, true) - 1;
8097 if (eq(array[index], value)) {
8105 * This method is like `_.uniq` except that it's designed and optimized
8106 * for sorted arrays.
8112 * @param {Array} array The array to inspect.
8113 * @returns {Array} Returns the new duplicate free array.
8116 * _.sortedUniq([1, 1, 2]);
8119 function sortedUniq(array) {
8120 return (array && array.length)
8121 ? baseSortedUniq(array)
8126 * This method is like `_.uniqBy` except that it's designed and optimized
8127 * for sorted arrays.
8133 * @param {Array} array The array to inspect.
8134 * @param {Function} [iteratee] The iteratee invoked per element.
8135 * @returns {Array} Returns the new duplicate free array.
8138 * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
8141 function sortedUniqBy(array, iteratee) {
8142 return (array && array.length)
8143 ? baseSortedUniq(array, getIteratee(iteratee, 2))
8148 * Gets all but the first element of `array`.
8154 * @param {Array} array The array to query.
8155 * @returns {Array} Returns the slice of `array`.
8158 * _.tail([1, 2, 3]);
8161 function tail(array) {
8162 var length = array == null ? 0 : array.length;
8163 return length ? baseSlice(array, 1, length) : [];
8167 * Creates a slice of `array` with `n` elements taken from the beginning.
8173 * @param {Array} array The array to query.
8174 * @param {number} [n=1] The number of elements to take.
8175 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8176 * @returns {Array} Returns the slice of `array`.
8179 * _.take([1, 2, 3]);
8182 * _.take([1, 2, 3], 2);
8185 * _.take([1, 2, 3], 5);
8188 * _.take([1, 2, 3], 0);
8191 function take(array, n, guard) {
8192 if (!(array && array.length)) {
8195 n = (guard || n === undefined) ? 1 : toInteger(n);
8196 return baseSlice(array, 0, n < 0 ? 0 : n);
8200 * Creates a slice of `array` with `n` elements taken from the end.
8206 * @param {Array} array The array to query.
8207 * @param {number} [n=1] The number of elements to take.
8208 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8209 * @returns {Array} Returns the slice of `array`.
8212 * _.takeRight([1, 2, 3]);
8215 * _.takeRight([1, 2, 3], 2);
8218 * _.takeRight([1, 2, 3], 5);
8221 * _.takeRight([1, 2, 3], 0);
8224 function takeRight(array, n, guard) {
8225 var length = array == null ? 0 : array.length;
8229 n = (guard || n === undefined) ? 1 : toInteger(n);
8231 return baseSlice(array, n < 0 ? 0 : n, length);
8235 * Creates a slice of `array` with elements taken from the end. Elements are
8236 * taken until `predicate` returns falsey. The predicate is invoked with
8237 * three arguments: (value, index, array).
8243 * @param {Array} array The array to query.
8244 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8245 * @returns {Array} Returns the slice of `array`.
8249 * { 'user': 'barney', 'active': true },
8250 * { 'user': 'fred', 'active': false },
8251 * { 'user': 'pebbles', 'active': false }
8254 * _.takeRightWhile(users, function(o) { return !o.active; });
8255 * // => objects for ['fred', 'pebbles']
8257 * // The `_.matches` iteratee shorthand.
8258 * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
8259 * // => objects for ['pebbles']
8261 * // The `_.matchesProperty` iteratee shorthand.
8262 * _.takeRightWhile(users, ['active', false]);
8263 * // => objects for ['fred', 'pebbles']
8265 * // The `_.property` iteratee shorthand.
8266 * _.takeRightWhile(users, 'active');
8269 function takeRightWhile(array, predicate) {
8270 return (array && array.length)
8271 ? baseWhile(array, getIteratee(predicate, 3), false, true)
8276 * Creates a slice of `array` with elements taken from the beginning. Elements
8277 * are taken until `predicate` returns falsey. The predicate is invoked with
8278 * three arguments: (value, index, array).
8284 * @param {Array} array The array to query.
8285 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8286 * @returns {Array} Returns the slice of `array`.
8290 * { 'user': 'barney', 'active': false },
8291 * { 'user': 'fred', 'active': false},
8292 * { 'user': 'pebbles', 'active': true }
8295 * _.takeWhile(users, function(o) { return !o.active; });
8296 * // => objects for ['barney', 'fred']
8298 * // The `_.matches` iteratee shorthand.
8299 * _.takeWhile(users, { 'user': 'barney', 'active': false });
8300 * // => objects for ['barney']
8302 * // The `_.matchesProperty` iteratee shorthand.
8303 * _.takeWhile(users, ['active', false]);
8304 * // => objects for ['barney', 'fred']
8306 * // The `_.property` iteratee shorthand.
8307 * _.takeWhile(users, 'active');
8310 function takeWhile(array, predicate) {
8311 return (array && array.length)
8312 ? baseWhile(array, getIteratee(predicate, 3))
8317 * Creates an array of unique values, in order, from all given arrays using
8318 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8319 * for equality comparisons.
8325 * @param {...Array} [arrays] The arrays to inspect.
8326 * @returns {Array} Returns the new array of combined values.
8329 * _.union([2], [1, 2]);
8332 var union = baseRest(function(arrays) {
8333 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
8337 * This method is like `_.union` except that it accepts `iteratee` which is
8338 * invoked for each element of each `arrays` to generate the criterion by
8339 * which uniqueness is computed. Result values are chosen from the first
8340 * array in which the value occurs. The iteratee is invoked with one argument:
8347 * @param {...Array} [arrays] The arrays to inspect.
8348 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8349 * @returns {Array} Returns the new array of combined values.
8352 * _.unionBy([2.1], [1.2, 2.3], Math.floor);
8355 * // The `_.property` iteratee shorthand.
8356 * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8357 * // => [{ 'x': 1 }, { 'x': 2 }]
8359 var unionBy = baseRest(function(arrays) {
8360 var iteratee = last(arrays);
8361 if (isArrayLikeObject(iteratee)) {
8362 iteratee = undefined;
8364 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
8368 * This method is like `_.union` except that it accepts `comparator` which
8369 * is invoked to compare elements of `arrays`. Result values are chosen from
8370 * the first array in which the value occurs. The comparator is invoked
8371 * with two arguments: (arrVal, othVal).
8377 * @param {...Array} [arrays] The arrays to inspect.
8378 * @param {Function} [comparator] The comparator invoked per element.
8379 * @returns {Array} Returns the new array of combined values.
8382 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8383 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8385 * _.unionWith(objects, others, _.isEqual);
8386 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8388 var unionWith = baseRest(function(arrays) {
8389 var comparator = last(arrays);
8390 comparator = typeof comparator == 'function' ? comparator : undefined;
8391 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
8395 * Creates a duplicate-free version of an array, using
8396 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8397 * for equality comparisons, in which only the first occurrence of each element
8398 * is kept. The order of result values is determined by the order they occur
8405 * @param {Array} array The array to inspect.
8406 * @returns {Array} Returns the new duplicate free array.
8409 * _.uniq([2, 1, 2]);
8412 function uniq(array) {
8413 return (array && array.length) ? baseUniq(array) : [];
8417 * This method is like `_.uniq` except that it accepts `iteratee` which is
8418 * invoked for each element in `array` to generate the criterion by which
8419 * uniqueness is computed. The order of result values is determined by the
8420 * order they occur in the array. The iteratee is invoked with one argument:
8427 * @param {Array} array The array to inspect.
8428 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8429 * @returns {Array} Returns the new duplicate free array.
8432 * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
8435 * // The `_.property` iteratee shorthand.
8436 * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
8437 * // => [{ 'x': 1 }, { 'x': 2 }]
8439 function uniqBy(array, iteratee) {
8440 return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
8444 * This method is like `_.uniq` except that it accepts `comparator` which
8445 * is invoked to compare elements of `array`. The order of result values is
8446 * determined by the order they occur in the array.The comparator is invoked
8447 * with two arguments: (arrVal, othVal).
8453 * @param {Array} array The array to inspect.
8454 * @param {Function} [comparator] The comparator invoked per element.
8455 * @returns {Array} Returns the new duplicate free array.
8458 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
8460 * _.uniqWith(objects, _.isEqual);
8461 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
8463 function uniqWith(array, comparator) {
8464 comparator = typeof comparator == 'function' ? comparator : undefined;
8465 return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
8469 * This method is like `_.zip` except that it accepts an array of grouped
8470 * elements and creates an array regrouping the elements to their pre-zip
8477 * @param {Array} array The array of grouped elements to process.
8478 * @returns {Array} Returns the new array of regrouped elements.
8481 * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
8482 * // => [['a', 1, true], ['b', 2, false]]
8485 * // => [['a', 'b'], [1, 2], [true, false]]
8487 function unzip(array) {
8488 if (!(array && array.length)) {
8492 array = arrayFilter(array, function(group) {
8493 if (isArrayLikeObject(group)) {
8494 length = nativeMax(group.length, length);
8498 return baseTimes(length, function(index) {
8499 return arrayMap(array, baseProperty(index));
8504 * This method is like `_.unzip` except that it accepts `iteratee` to specify
8505 * how regrouped values should be combined. The iteratee is invoked with the
8506 * elements of each group: (...group).
8512 * @param {Array} array The array of grouped elements to process.
8513 * @param {Function} [iteratee=_.identity] The function to combine
8515 * @returns {Array} Returns the new array of regrouped elements.
8518 * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
8519 * // => [[1, 10, 100], [2, 20, 200]]
8521 * _.unzipWith(zipped, _.add);
8522 * // => [3, 30, 300]
8524 function unzipWith(array, iteratee) {
8525 if (!(array && array.length)) {
8528 var result = unzip(array);
8529 if (iteratee == null) {
8532 return arrayMap(result, function(group) {
8533 return apply(iteratee, undefined, group);
8538 * Creates an array excluding all given values using
8539 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8540 * for equality comparisons.
8542 * **Note:** Unlike `_.pull`, this method returns a new array.
8548 * @param {Array} array The array to inspect.
8549 * @param {...*} [values] The values to exclude.
8550 * @returns {Array} Returns the new array of filtered values.
8551 * @see _.difference, _.xor
8554 * _.without([2, 1, 2, 3], 1, 2);
8557 var without = baseRest(function(array, values) {
8558 return isArrayLikeObject(array)
8559 ? baseDifference(array, values)
8564 * Creates an array of unique values that is the
8565 * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
8566 * of the given arrays. The order of result values is determined by the order
8567 * they occur in the arrays.
8573 * @param {...Array} [arrays] The arrays to inspect.
8574 * @returns {Array} Returns the new array of filtered values.
8575 * @see _.difference, _.without
8578 * _.xor([2, 1], [2, 3]);
8581 var xor = baseRest(function(arrays) {
8582 return baseXor(arrayFilter(arrays, isArrayLikeObject));
8586 * This method is like `_.xor` except that it accepts `iteratee` which is
8587 * invoked for each element of each `arrays` to generate the criterion by
8588 * which by which they're compared. The order of result values is determined
8589 * by the order they occur in the arrays. The iteratee is invoked with one
8590 * argument: (value).
8596 * @param {...Array} [arrays] The arrays to inspect.
8597 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8598 * @returns {Array} Returns the new array of filtered values.
8601 * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8604 * // The `_.property` iteratee shorthand.
8605 * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8606 * // => [{ 'x': 2 }]
8608 var xorBy = baseRest(function(arrays) {
8609 var iteratee = last(arrays);
8610 if (isArrayLikeObject(iteratee)) {
8611 iteratee = undefined;
8613 return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
8617 * This method is like `_.xor` except that it accepts `comparator` which is
8618 * invoked to compare elements of `arrays`. The order of result values is
8619 * determined by the order they occur in the arrays. The comparator is invoked
8620 * with two arguments: (arrVal, othVal).
8626 * @param {...Array} [arrays] The arrays to inspect.
8627 * @param {Function} [comparator] The comparator invoked per element.
8628 * @returns {Array} Returns the new array of filtered values.
8631 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8632 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8634 * _.xorWith(objects, others, _.isEqual);
8635 * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8637 var xorWith = baseRest(function(arrays) {
8638 var comparator = last(arrays);
8639 comparator = typeof comparator == 'function' ? comparator : undefined;
8640 return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
8644 * Creates an array of grouped elements, the first of which contains the
8645 * first elements of the given arrays, the second of which contains the
8646 * second elements of the given arrays, and so on.
8652 * @param {...Array} [arrays] The arrays to process.
8653 * @returns {Array} Returns the new array of grouped elements.
8656 * _.zip(['a', 'b'], [1, 2], [true, false]);
8657 * // => [['a', 1, true], ['b', 2, false]]
8659 var zip = baseRest(unzip);
8662 * This method is like `_.fromPairs` except that it accepts two arrays,
8663 * one of property identifiers and one of corresponding values.
8669 * @param {Array} [props=[]] The property identifiers.
8670 * @param {Array} [values=[]] The property values.
8671 * @returns {Object} Returns the new object.
8674 * _.zipObject(['a', 'b'], [1, 2]);
8675 * // => { 'a': 1, 'b': 2 }
8677 function zipObject(props, values) {
8678 return baseZipObject(props || [], values || [], assignValue);
8682 * This method is like `_.zipObject` except that it supports property paths.
8688 * @param {Array} [props=[]] The property identifiers.
8689 * @param {Array} [values=[]] The property values.
8690 * @returns {Object} Returns the new object.
8693 * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
8694 * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
8696 function zipObjectDeep(props, values) {
8697 return baseZipObject(props || [], values || [], baseSet);
8701 * This method is like `_.zip` except that it accepts `iteratee` to specify
8702 * how grouped values should be combined. The iteratee is invoked with the
8703 * elements of each group: (...group).
8709 * @param {...Array} [arrays] The arrays to process.
8710 * @param {Function} [iteratee=_.identity] The function to combine
8712 * @returns {Array} Returns the new array of grouped elements.
8715 * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
8720 var zipWith = baseRest(function(arrays) {
8721 var length = arrays.length,
8722 iteratee = length > 1 ? arrays[length - 1] : undefined;
8724 iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
8725 return unzipWith(arrays, iteratee);
8728 /*------------------------------------------------------------------------*/
8731 * Creates a `lodash` wrapper instance that wraps `value` with explicit method
8732 * chain sequences enabled. The result of such sequences must be unwrapped
8739 * @param {*} value The value to wrap.
8740 * @returns {Object} Returns the new `lodash` wrapper instance.
8744 * { 'user': 'barney', 'age': 36 },
8745 * { 'user': 'fred', 'age': 40 },
8746 * { 'user': 'pebbles', 'age': 1 }
8752 * .map(function(o) {
8753 * return o.user + ' is ' + o.age;
8757 * // => 'pebbles is 1'
8759 function chain(value) {
8760 var result = lodash(value);
8761 result.__chain__ = true;
8766 * This method invokes `interceptor` and returns `value`. The interceptor
8767 * is invoked with one argument; (value). The purpose of this method is to
8768 * "tap into" a method chain sequence in order to modify intermediate results.
8774 * @param {*} value The value to provide to `interceptor`.
8775 * @param {Function} interceptor The function to invoke.
8776 * @returns {*} Returns `value`.
8780 * .tap(function(array) {
8781 * // Mutate input array.
8788 function tap(value, interceptor) {
8794 * This method is like `_.tap` except that it returns the result of `interceptor`.
8795 * The purpose of this method is to "pass thru" values replacing intermediate
8796 * results in a method chain sequence.
8802 * @param {*} value The value to provide to `interceptor`.
8803 * @param {Function} interceptor The function to invoke.
8804 * @returns {*} Returns the result of `interceptor`.
8810 * .thru(function(value) {
8816 function thru(value, interceptor) {
8817 return interceptor(value);
8821 * This method is the wrapper version of `_.at`.
8827 * @param {...(string|string[])} [paths] The property paths to pick.
8828 * @returns {Object} Returns the new `lodash` wrapper instance.
8831 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
8833 * _(object).at(['a[0].b.c', 'a[1]']).value();
8836 var wrapperAt = flatRest(function(paths) {
8837 var length = paths.length,
8838 start = length ? paths[0] : 0,
8839 value = this.__wrapped__,
8840 interceptor = function(object) { return baseAt(object, paths); };
8842 if (length > 1 || this.__actions__.length ||
8843 !(value instanceof LazyWrapper) || !isIndex(start)) {
8844 return this.thru(interceptor);
8846 value = value.slice(start, +start + (length ? 1 : 0));
8847 value.__actions__.push({
8849 'args': [interceptor],
8850 'thisArg': undefined
8852 return new LodashWrapper(value, this.__chain__).thru(function(array) {
8853 if (length && !array.length) {
8854 array.push(undefined);
8861 * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
8867 * @returns {Object} Returns the new `lodash` wrapper instance.
8871 * { 'user': 'barney', 'age': 36 },
8872 * { 'user': 'fred', 'age': 40 }
8875 * // A sequence without explicit chaining.
8877 * // => { 'user': 'barney', 'age': 36 }
8879 * // A sequence with explicit chaining.
8885 * // => { 'user': 'barney' }
8887 function wrapperChain() {
8892 * Executes the chain sequence and returns the wrapped result.
8898 * @returns {Object} Returns the new `lodash` wrapper instance.
8901 * var array = [1, 2];
8902 * var wrapped = _(array).push(3);
8904 * console.log(array);
8907 * wrapped = wrapped.commit();
8908 * console.log(array);
8914 * console.log(array);
8917 function wrapperCommit() {
8918 return new LodashWrapper(this.value(), this.__chain__);
8922 * Gets the next value on a wrapped object following the
8923 * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8929 * @returns {Object} Returns the next iterator value.
8932 * var wrapped = _([1, 2]);
8935 * // => { 'done': false, 'value': 1 }
8938 * // => { 'done': false, 'value': 2 }
8941 * // => { 'done': true, 'value': undefined }
8943 function wrapperNext() {
8944 if (this.__values__ === undefined) {
8945 this.__values__ = toArray(this.value());
8947 var done = this.__index__ >= this.__values__.length,
8948 value = done ? undefined : this.__values__[this.__index__++];
8950 return { 'done': done, 'value': value };
8954 * Enables the wrapper to be iterable.
8956 * @name Symbol.iterator
8960 * @returns {Object} Returns the wrapper object.
8963 * var wrapped = _([1, 2]);
8965 * wrapped[Symbol.iterator]() === wrapped;
8968 * Array.from(wrapped);
8971 function wrapperToIterator() {
8976 * Creates a clone of the chain sequence planting `value` as the wrapped value.
8982 * @param {*} value The value to plant.
8983 * @returns {Object} Returns the new `lodash` wrapper instance.
8986 * function square(n) {
8990 * var wrapped = _([1, 2]).map(square);
8991 * var other = wrapped.plant([3, 4]);
8999 function wrapperPlant(value) {
9003 while (parent instanceof baseLodash) {
9004 var clone = wrapperClone(parent);
9005 clone.__index__ = 0;
9006 clone.__values__ = undefined;
9008 previous.__wrapped__ = clone;
9012 var previous = clone;
9013 parent = parent.__wrapped__;
9015 previous.__wrapped__ = value;
9020 * This method is the wrapper version of `_.reverse`.
9022 * **Note:** This method mutates the wrapped array.
9028 * @returns {Object} Returns the new `lodash` wrapper instance.
9031 * var array = [1, 2, 3];
9033 * _(array).reverse().value()
9036 * console.log(array);
9039 function wrapperReverse() {
9040 var value = this.__wrapped__;
9041 if (value instanceof LazyWrapper) {
9042 var wrapped = value;
9043 if (this.__actions__.length) {
9044 wrapped = new LazyWrapper(this);
9046 wrapped = wrapped.reverse();
9047 wrapped.__actions__.push({
9050 'thisArg': undefined
9052 return new LodashWrapper(wrapped, this.__chain__);
9054 return this.thru(reverse);
9058 * Executes the chain sequence to resolve the unwrapped value.
9063 * @alias toJSON, valueOf
9065 * @returns {*} Returns the resolved unwrapped value.
9068 * _([1, 2, 3]).value();
9071 function wrapperValue() {
9072 return baseWrapperValue(this.__wrapped__, this.__actions__);
9075 /*------------------------------------------------------------------------*/
9078 * Creates an object composed of keys generated from the results of running
9079 * each element of `collection` thru `iteratee`. The corresponding value of
9080 * each key is the number of times the key was returned by `iteratee`. The
9081 * iteratee is invoked with one argument: (value).
9086 * @category Collection
9087 * @param {Array|Object} collection The collection to iterate over.
9088 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9089 * @returns {Object} Returns the composed aggregate object.
9092 * _.countBy([6.1, 4.2, 6.3], Math.floor);
9093 * // => { '4': 1, '6': 2 }
9095 * // The `_.property` iteratee shorthand.
9096 * _.countBy(['one', 'two', 'three'], 'length');
9097 * // => { '3': 2, '5': 1 }
9099 var countBy = createAggregator(function(result, value, key) {
9100 if (hasOwnProperty.call(result, key)) {
9103 baseAssignValue(result, key, 1);
9108 * Checks if `predicate` returns truthy for **all** elements of `collection`.
9109 * Iteration is stopped once `predicate` returns falsey. The predicate is
9110 * invoked with three arguments: (value, index|key, collection).
9112 * **Note:** This method returns `true` for
9113 * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
9114 * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
9115 * elements of empty collections.
9120 * @category Collection
9121 * @param {Array|Object} collection The collection to iterate over.
9122 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9123 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9124 * @returns {boolean} Returns `true` if all elements pass the predicate check,
9128 * _.every([true, 1, null, 'yes'], Boolean);
9132 * { 'user': 'barney', 'age': 36, 'active': false },
9133 * { 'user': 'fred', 'age': 40, 'active': false }
9136 * // The `_.matches` iteratee shorthand.
9137 * _.every(users, { 'user': 'barney', 'active': false });
9140 * // The `_.matchesProperty` iteratee shorthand.
9141 * _.every(users, ['active', false]);
9144 * // The `_.property` iteratee shorthand.
9145 * _.every(users, 'active');
9148 function every(collection, predicate, guard) {
9149 var func = isArray(collection) ? arrayEvery : baseEvery;
9150 if (guard && isIterateeCall(collection, predicate, guard)) {
9151 predicate = undefined;
9153 return func(collection, getIteratee(predicate, 3));
9157 * Iterates over elements of `collection`, returning an array of all elements
9158 * `predicate` returns truthy for. The predicate is invoked with three
9159 * arguments: (value, index|key, collection).
9161 * **Note:** Unlike `_.remove`, this method returns a new array.
9166 * @category Collection
9167 * @param {Array|Object} collection The collection to iterate over.
9168 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9169 * @returns {Array} Returns the new filtered array.
9174 * { 'user': 'barney', 'age': 36, 'active': true },
9175 * { 'user': 'fred', 'age': 40, 'active': false }
9178 * _.filter(users, function(o) { return !o.active; });
9179 * // => objects for ['fred']
9181 * // The `_.matches` iteratee shorthand.
9182 * _.filter(users, { 'age': 36, 'active': true });
9183 * // => objects for ['barney']
9185 * // The `_.matchesProperty` iteratee shorthand.
9186 * _.filter(users, ['active', false]);
9187 * // => objects for ['fred']
9189 * // The `_.property` iteratee shorthand.
9190 * _.filter(users, 'active');
9191 * // => objects for ['barney']
9193 function filter(collection, predicate) {
9194 var func = isArray(collection) ? arrayFilter : baseFilter;
9195 return func(collection, getIteratee(predicate, 3));
9199 * Iterates over elements of `collection`, returning the first element
9200 * `predicate` returns truthy for. The predicate is invoked with three
9201 * arguments: (value, index|key, collection).
9206 * @category Collection
9207 * @param {Array|Object} collection The collection to inspect.
9208 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9209 * @param {number} [fromIndex=0] The index to search from.
9210 * @returns {*} Returns the matched element, else `undefined`.
9214 * { 'user': 'barney', 'age': 36, 'active': true },
9215 * { 'user': 'fred', 'age': 40, 'active': false },
9216 * { 'user': 'pebbles', 'age': 1, 'active': true }
9219 * _.find(users, function(o) { return o.age < 40; });
9220 * // => object for 'barney'
9222 * // The `_.matches` iteratee shorthand.
9223 * _.find(users, { 'age': 1, 'active': true });
9224 * // => object for 'pebbles'
9226 * // The `_.matchesProperty` iteratee shorthand.
9227 * _.find(users, ['active', false]);
9228 * // => object for 'fred'
9230 * // The `_.property` iteratee shorthand.
9231 * _.find(users, 'active');
9232 * // => object for 'barney'
9234 var find = createFind(findIndex);
9237 * This method is like `_.find` except that it iterates over elements of
9238 * `collection` from right to left.
9243 * @category Collection
9244 * @param {Array|Object} collection The collection to inspect.
9245 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9246 * @param {number} [fromIndex=collection.length-1] The index to search from.
9247 * @returns {*} Returns the matched element, else `undefined`.
9250 * _.findLast([1, 2, 3, 4], function(n) {
9251 * return n % 2 == 1;
9255 var findLast = createFind(findLastIndex);
9258 * Creates a flattened array of values by running each element in `collection`
9259 * thru `iteratee` and flattening the mapped results. The iteratee is invoked
9260 * with three arguments: (value, index|key, collection).
9265 * @category Collection
9266 * @param {Array|Object} collection The collection to iterate over.
9267 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9268 * @returns {Array} Returns the new flattened array.
9271 * function duplicate(n) {
9275 * _.flatMap([1, 2], duplicate);
9276 * // => [1, 1, 2, 2]
9278 function flatMap(collection, iteratee) {
9279 return baseFlatten(map(collection, iteratee), 1);
9283 * This method is like `_.flatMap` except that it recursively flattens the
9289 * @category Collection
9290 * @param {Array|Object} collection The collection to iterate over.
9291 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9292 * @returns {Array} Returns the new flattened array.
9295 * function duplicate(n) {
9296 * return [[[n, n]]];
9299 * _.flatMapDeep([1, 2], duplicate);
9300 * // => [1, 1, 2, 2]
9302 function flatMapDeep(collection, iteratee) {
9303 return baseFlatten(map(collection, iteratee), INFINITY);
9307 * This method is like `_.flatMap` except that it recursively flattens the
9308 * mapped results up to `depth` times.
9313 * @category Collection
9314 * @param {Array|Object} collection The collection to iterate over.
9315 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9316 * @param {number} [depth=1] The maximum recursion depth.
9317 * @returns {Array} Returns the new flattened array.
9320 * function duplicate(n) {
9321 * return [[[n, n]]];
9324 * _.flatMapDepth([1, 2], duplicate, 2);
9325 * // => [[1, 1], [2, 2]]
9327 function flatMapDepth(collection, iteratee, depth) {
9328 depth = depth === undefined ? 1 : toInteger(depth);
9329 return baseFlatten(map(collection, iteratee), depth);
9333 * Iterates over elements of `collection` and invokes `iteratee` for each element.
9334 * The iteratee is invoked with three arguments: (value, index|key, collection).
9335 * Iteratee functions may exit iteration early by explicitly returning `false`.
9337 * **Note:** As with other "Collections" methods, objects with a "length"
9338 * property are iterated like arrays. To avoid this behavior use `_.forIn`
9339 * or `_.forOwn` for object iteration.
9345 * @category Collection
9346 * @param {Array|Object} collection The collection to iterate over.
9347 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9348 * @returns {Array|Object} Returns `collection`.
9349 * @see _.forEachRight
9352 * _.forEach([1, 2], function(value) {
9353 * console.log(value);
9355 * // => Logs `1` then `2`.
9357 * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
9360 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
9362 function forEach(collection, iteratee) {
9363 var func = isArray(collection) ? arrayEach : baseEach;
9364 return func(collection, getIteratee(iteratee, 3));
9368 * This method is like `_.forEach` except that it iterates over elements of
9369 * `collection` from right to left.
9375 * @category Collection
9376 * @param {Array|Object} collection The collection to iterate over.
9377 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9378 * @returns {Array|Object} Returns `collection`.
9382 * _.forEachRight([1, 2], function(value) {
9383 * console.log(value);
9385 * // => Logs `2` then `1`.
9387 function forEachRight(collection, iteratee) {
9388 var func = isArray(collection) ? arrayEachRight : baseEachRight;
9389 return func(collection, getIteratee(iteratee, 3));
9393 * Creates an object composed of keys generated from the results of running
9394 * each element of `collection` thru `iteratee`. The order of grouped values
9395 * is determined by the order they occur in `collection`. The corresponding
9396 * value of each key is an array of elements responsible for generating the
9397 * key. The iteratee is invoked with one argument: (value).
9402 * @category Collection
9403 * @param {Array|Object} collection The collection to iterate over.
9404 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9405 * @returns {Object} Returns the composed aggregate object.
9408 * _.groupBy([6.1, 4.2, 6.3], Math.floor);
9409 * // => { '4': [4.2], '6': [6.1, 6.3] }
9411 * // The `_.property` iteratee shorthand.
9412 * _.groupBy(['one', 'two', 'three'], 'length');
9413 * // => { '3': ['one', 'two'], '5': ['three'] }
9415 var groupBy = createAggregator(function(result, value, key) {
9416 if (hasOwnProperty.call(result, key)) {
9417 result[key].push(value);
9419 baseAssignValue(result, key, [value]);
9424 * Checks if `value` is in `collection`. If `collection` is a string, it's
9425 * checked for a substring of `value`, otherwise
9426 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9427 * is used for equality comparisons. If `fromIndex` is negative, it's used as
9428 * the offset from the end of `collection`.
9433 * @category Collection
9434 * @param {Array|Object|string} collection The collection to inspect.
9435 * @param {*} value The value to search for.
9436 * @param {number} [fromIndex=0] The index to search from.
9437 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9438 * @returns {boolean} Returns `true` if `value` is found, else `false`.
9441 * _.includes([1, 2, 3], 1);
9444 * _.includes([1, 2, 3], 1, 2);
9447 * _.includes({ 'a': 1, 'b': 2 }, 1);
9450 * _.includes('abcd', 'bc');
9453 function includes(collection, value, fromIndex, guard) {
9454 collection = isArrayLike(collection) ? collection : values(collection);
9455 fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
9457 var length = collection.length;
9458 if (fromIndex < 0) {
9459 fromIndex = nativeMax(length + fromIndex, 0);
9461 return isString(collection)
9462 ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
9463 : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
9467 * Invokes the method at `path` of each element in `collection`, returning
9468 * an array of the results of each invoked method. Any additional arguments
9469 * are provided to each invoked method. If `path` is a function, it's invoked
9470 * for, and `this` bound to, each element in `collection`.
9475 * @category Collection
9476 * @param {Array|Object} collection The collection to iterate over.
9477 * @param {Array|Function|string} path The path of the method to invoke or
9478 * the function invoked per iteration.
9479 * @param {...*} [args] The arguments to invoke each method with.
9480 * @returns {Array} Returns the array of results.
9483 * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
9484 * // => [[1, 5, 7], [1, 2, 3]]
9486 * _.invokeMap([123, 456], String.prototype.split, '');
9487 * // => [['1', '2', '3'], ['4', '5', '6']]
9489 var invokeMap = baseRest(function(collection, path, args) {
9491 isFunc = typeof path == 'function',
9492 result = isArrayLike(collection) ? Array(collection.length) : [];
9494 baseEach(collection, function(value) {
9495 result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
9501 * Creates an object composed of keys generated from the results of running
9502 * each element of `collection` thru `iteratee`. The corresponding value of
9503 * each key is the last element responsible for generating the key. The
9504 * iteratee is invoked with one argument: (value).
9509 * @category Collection
9510 * @param {Array|Object} collection The collection to iterate over.
9511 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9512 * @returns {Object} Returns the composed aggregate object.
9516 * { 'dir': 'left', 'code': 97 },
9517 * { 'dir': 'right', 'code': 100 }
9520 * _.keyBy(array, function(o) {
9521 * return String.fromCharCode(o.code);
9523 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
9525 * _.keyBy(array, 'dir');
9526 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
9528 var keyBy = createAggregator(function(result, value, key) {
9529 baseAssignValue(result, key, value);
9533 * Creates an array of values by running each element in `collection` thru
9534 * `iteratee`. The iteratee is invoked with three arguments:
9535 * (value, index|key, collection).
9537 * Many lodash methods are guarded to work as iteratees for methods like
9538 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
9540 * The guarded methods are:
9541 * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
9542 * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
9543 * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
9544 * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
9549 * @category Collection
9550 * @param {Array|Object} collection The collection to iterate over.
9551 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9552 * @returns {Array} Returns the new mapped array.
9555 * function square(n) {
9559 * _.map([4, 8], square);
9562 * _.map({ 'a': 4, 'b': 8 }, square);
9563 * // => [16, 64] (iteration order is not guaranteed)
9566 * { 'user': 'barney' },
9567 * { 'user': 'fred' }
9570 * // The `_.property` iteratee shorthand.
9571 * _.map(users, 'user');
9572 * // => ['barney', 'fred']
9574 function map(collection, iteratee) {
9575 var func = isArray(collection) ? arrayMap : baseMap;
9576 return func(collection, getIteratee(iteratee, 3));
9580 * This method is like `_.sortBy` except that it allows specifying the sort
9581 * orders of the iteratees to sort by. If `orders` is unspecified, all values
9582 * are sorted in ascending order. Otherwise, specify an order of "desc" for
9583 * descending or "asc" for ascending sort order of corresponding values.
9588 * @category Collection
9589 * @param {Array|Object} collection The collection to iterate over.
9590 * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
9591 * The iteratees to sort by.
9592 * @param {string[]} [orders] The sort orders of `iteratees`.
9593 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9594 * @returns {Array} Returns the new sorted array.
9598 * { 'user': 'fred', 'age': 48 },
9599 * { 'user': 'barney', 'age': 34 },
9600 * { 'user': 'fred', 'age': 40 },
9601 * { 'user': 'barney', 'age': 36 }
9604 * // Sort by `user` in ascending order and by `age` in descending order.
9605 * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
9606 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9608 function orderBy(collection, iteratees, orders, guard) {
9609 if (collection == null) {
9612 if (!isArray(iteratees)) {
9613 iteratees = iteratees == null ? [] : [iteratees];
9615 orders = guard ? undefined : orders;
9616 if (!isArray(orders)) {
9617 orders = orders == null ? [] : [orders];
9619 return baseOrderBy(collection, iteratees, orders);
9623 * Creates an array of elements split into two groups, the first of which
9624 * contains elements `predicate` returns truthy for, the second of which
9625 * contains elements `predicate` returns falsey for. The predicate is
9626 * invoked with one argument: (value).
9631 * @category Collection
9632 * @param {Array|Object} collection The collection to iterate over.
9633 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9634 * @returns {Array} Returns the array of grouped elements.
9638 * { 'user': 'barney', 'age': 36, 'active': false },
9639 * { 'user': 'fred', 'age': 40, 'active': true },
9640 * { 'user': 'pebbles', 'age': 1, 'active': false }
9643 * _.partition(users, function(o) { return o.active; });
9644 * // => objects for [['fred'], ['barney', 'pebbles']]
9646 * // The `_.matches` iteratee shorthand.
9647 * _.partition(users, { 'age': 1, 'active': false });
9648 * // => objects for [['pebbles'], ['barney', 'fred']]
9650 * // The `_.matchesProperty` iteratee shorthand.
9651 * _.partition(users, ['active', false]);
9652 * // => objects for [['barney', 'pebbles'], ['fred']]
9654 * // The `_.property` iteratee shorthand.
9655 * _.partition(users, 'active');
9656 * // => objects for [['fred'], ['barney', 'pebbles']]
9658 var partition = createAggregator(function(result, value, key) {
9659 result[key ? 0 : 1].push(value);
9660 }, function() { return [[], []]; });
9663 * Reduces `collection` to a value which is the accumulated result of running
9664 * each element in `collection` thru `iteratee`, where each successive
9665 * invocation is supplied the return value of the previous. If `accumulator`
9666 * is not given, the first element of `collection` is used as the initial
9667 * value. The iteratee is invoked with four arguments:
9668 * (accumulator, value, index|key, collection).
9670 * Many lodash methods are guarded to work as iteratees for methods like
9671 * `_.reduce`, `_.reduceRight`, and `_.transform`.
9673 * The guarded methods are:
9674 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
9680 * @category Collection
9681 * @param {Array|Object} collection The collection to iterate over.
9682 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9683 * @param {*} [accumulator] The initial value.
9684 * @returns {*} Returns the accumulated value.
9685 * @see _.reduceRight
9688 * _.reduce([1, 2], function(sum, n) {
9693 * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
9694 * (result[value] || (result[value] = [])).push(key);
9697 * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
9699 function reduce(collection, iteratee, accumulator) {
9700 var func = isArray(collection) ? arrayReduce : baseReduce,
9701 initAccum = arguments.length < 3;
9703 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
9707 * This method is like `_.reduce` except that it iterates over elements of
9708 * `collection` from right to left.
9713 * @category Collection
9714 * @param {Array|Object} collection The collection to iterate over.
9715 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9716 * @param {*} [accumulator] The initial value.
9717 * @returns {*} Returns the accumulated value.
9721 * var array = [[0, 1], [2, 3], [4, 5]];
9723 * _.reduceRight(array, function(flattened, other) {
9724 * return flattened.concat(other);
9726 * // => [4, 5, 2, 3, 0, 1]
9728 function reduceRight(collection, iteratee, accumulator) {
9729 var func = isArray(collection) ? arrayReduceRight : baseReduce,
9730 initAccum = arguments.length < 3;
9732 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
9736 * The opposite of `_.filter`; this method returns the elements of `collection`
9737 * that `predicate` does **not** return truthy for.
9742 * @category Collection
9743 * @param {Array|Object} collection The collection to iterate over.
9744 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9745 * @returns {Array} Returns the new filtered array.
9750 * { 'user': 'barney', 'age': 36, 'active': false },
9751 * { 'user': 'fred', 'age': 40, 'active': true }
9754 * _.reject(users, function(o) { return !o.active; });
9755 * // => objects for ['fred']
9757 * // The `_.matches` iteratee shorthand.
9758 * _.reject(users, { 'age': 40, 'active': true });
9759 * // => objects for ['barney']
9761 * // The `_.matchesProperty` iteratee shorthand.
9762 * _.reject(users, ['active', false]);
9763 * // => objects for ['fred']
9765 * // The `_.property` iteratee shorthand.
9766 * _.reject(users, 'active');
9767 * // => objects for ['barney']
9769 function reject(collection, predicate) {
9770 var func = isArray(collection) ? arrayFilter : baseFilter;
9771 return func(collection, negate(getIteratee(predicate, 3)));
9775 * Gets a random element from `collection`.
9780 * @category Collection
9781 * @param {Array|Object} collection The collection to sample.
9782 * @returns {*} Returns the random element.
9785 * _.sample([1, 2, 3, 4]);
9788 function sample(collection) {
9789 var func = isArray(collection) ? arraySample : baseSample;
9790 return func(collection);
9794 * Gets `n` random elements at unique keys from `collection` up to the
9795 * size of `collection`.
9800 * @category Collection
9801 * @param {Array|Object} collection The collection to sample.
9802 * @param {number} [n=1] The number of elements to sample.
9803 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9804 * @returns {Array} Returns the random elements.
9807 * _.sampleSize([1, 2, 3], 2);
9810 * _.sampleSize([1, 2, 3], 4);
9813 function sampleSize(collection, n, guard) {
9814 if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
9819 var func = isArray(collection) ? arraySampleSize : baseSampleSize;
9820 return func(collection, n);
9824 * Creates an array of shuffled values, using a version of the
9825 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
9830 * @category Collection
9831 * @param {Array|Object} collection The collection to shuffle.
9832 * @returns {Array} Returns the new shuffled array.
9835 * _.shuffle([1, 2, 3, 4]);
9836 * // => [4, 1, 3, 2]
9838 function shuffle(collection) {
9839 var func = isArray(collection) ? arrayShuffle : baseShuffle;
9840 return func(collection);
9844 * Gets the size of `collection` by returning its length for array-like
9845 * values or the number of own enumerable string keyed properties for objects.
9850 * @category Collection
9851 * @param {Array|Object|string} collection The collection to inspect.
9852 * @returns {number} Returns the collection size.
9855 * _.size([1, 2, 3]);
9858 * _.size({ 'a': 1, 'b': 2 });
9861 * _.size('pebbles');
9864 function size(collection) {
9865 if (collection == null) {
9868 if (isArrayLike(collection)) {
9869 return isString(collection) ? stringSize(collection) : collection.length;
9871 var tag = getTag(collection);
9872 if (tag == mapTag || tag == setTag) {
9873 return collection.size;
9875 return baseKeys(collection).length;
9879 * Checks if `predicate` returns truthy for **any** element of `collection`.
9880 * Iteration is stopped once `predicate` returns truthy. The predicate is
9881 * invoked with three arguments: (value, index|key, collection).
9886 * @category Collection
9887 * @param {Array|Object} collection The collection to iterate over.
9888 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9889 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9890 * @returns {boolean} Returns `true` if any element passes the predicate check,
9894 * _.some([null, 0, 'yes', false], Boolean);
9898 * { 'user': 'barney', 'active': true },
9899 * { 'user': 'fred', 'active': false }
9902 * // The `_.matches` iteratee shorthand.
9903 * _.some(users, { 'user': 'barney', 'active': false });
9906 * // The `_.matchesProperty` iteratee shorthand.
9907 * _.some(users, ['active', false]);
9910 * // The `_.property` iteratee shorthand.
9911 * _.some(users, 'active');
9914 function some(collection, predicate, guard) {
9915 var func = isArray(collection) ? arraySome : baseSome;
9916 if (guard && isIterateeCall(collection, predicate, guard)) {
9917 predicate = undefined;
9919 return func(collection, getIteratee(predicate, 3));
9923 * Creates an array of elements, sorted in ascending order by the results of
9924 * running each element in a collection thru each iteratee. This method
9925 * performs a stable sort, that is, it preserves the original sort order of
9926 * equal elements. The iteratees are invoked with one argument: (value).
9931 * @category Collection
9932 * @param {Array|Object} collection The collection to iterate over.
9933 * @param {...(Function|Function[])} [iteratees=[_.identity]]
9934 * The iteratees to sort by.
9935 * @returns {Array} Returns the new sorted array.
9939 * { 'user': 'fred', 'age': 48 },
9940 * { 'user': 'barney', 'age': 36 },
9941 * { 'user': 'fred', 'age': 40 },
9942 * { 'user': 'barney', 'age': 34 }
9945 * _.sortBy(users, [function(o) { return o.user; }]);
9946 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9948 * _.sortBy(users, ['user', 'age']);
9949 * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
9951 var sortBy = baseRest(function(collection, iteratees) {
9952 if (collection == null) {
9955 var length = iteratees.length;
9956 if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
9958 } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
9959 iteratees = [iteratees[0]];
9961 return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
9964 /*------------------------------------------------------------------------*/
9967 * Gets the timestamp of the number of milliseconds that have elapsed since
9968 * the Unix epoch (1 January 1970 00:00:00 UTC).
9974 * @returns {number} Returns the timestamp.
9977 * _.defer(function(stamp) {
9978 * console.log(_.now() - stamp);
9980 * // => Logs the number of milliseconds it took for the deferred invocation.
9982 var now = ctxNow || function() {
9983 return root.Date.now();
9986 /*------------------------------------------------------------------------*/
9989 * The opposite of `_.before`; this method creates a function that invokes
9990 * `func` once it's called `n` or more times.
9995 * @category Function
9996 * @param {number} n The number of calls before `func` is invoked.
9997 * @param {Function} func The function to restrict.
9998 * @returns {Function} Returns the new restricted function.
10001 * var saves = ['profile', 'settings'];
10003 * var done = _.after(saves.length, function() {
10004 * console.log('done saving!');
10007 * _.forEach(saves, function(type) {
10008 * asyncSave({ 'type': type, 'complete': done });
10010 * // => Logs 'done saving!' after the two async saves have completed.
10012 function after(n, func) {
10013 if (typeof func != 'function') {
10014 throw new TypeError(FUNC_ERROR_TEXT);
10017 return function() {
10019 return func.apply(this, arguments);
10025 * Creates a function that invokes `func`, with up to `n` arguments,
10026 * ignoring any additional arguments.
10031 * @category Function
10032 * @param {Function} func The function to cap arguments for.
10033 * @param {number} [n=func.length] The arity cap.
10034 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10035 * @returns {Function} Returns the new capped function.
10038 * _.map(['6', '8', '10'], _.ary(parseInt, 1));
10041 function ary(func, n, guard) {
10042 n = guard ? undefined : n;
10043 n = (func && n == null) ? func.length : n;
10044 return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
10048 * Creates a function that invokes `func`, with the `this` binding and arguments
10049 * of the created function, while it's called less than `n` times. Subsequent
10050 * calls to the created function return the result of the last `func` invocation.
10055 * @category Function
10056 * @param {number} n The number of calls at which `func` is no longer invoked.
10057 * @param {Function} func The function to restrict.
10058 * @returns {Function} Returns the new restricted function.
10061 * jQuery(element).on('click', _.before(5, addContactToList));
10062 * // => Allows adding up to 4 contacts to the list.
10064 function before(n, func) {
10066 if (typeof func != 'function') {
10067 throw new TypeError(FUNC_ERROR_TEXT);
10070 return function() {
10072 result = func.apply(this, arguments);
10082 * Creates a function that invokes `func` with the `this` binding of `thisArg`
10083 * and `partials` prepended to the arguments it receives.
10085 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
10086 * may be used as a placeholder for partially applied arguments.
10088 * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
10089 * property of bound functions.
10094 * @category Function
10095 * @param {Function} func The function to bind.
10096 * @param {*} thisArg The `this` binding of `func`.
10097 * @param {...*} [partials] The arguments to be partially applied.
10098 * @returns {Function} Returns the new bound function.
10101 * function greet(greeting, punctuation) {
10102 * return greeting + ' ' + this.user + punctuation;
10105 * var object = { 'user': 'fred' };
10107 * var bound = _.bind(greet, object, 'hi');
10111 * // Bound with placeholders.
10112 * var bound = _.bind(greet, object, _, '!');
10116 var bind = baseRest(function(func, thisArg, partials) {
10117 var bitmask = WRAP_BIND_FLAG;
10118 if (partials.length) {
10119 var holders = replaceHolders(partials, getHolder(bind));
10120 bitmask |= WRAP_PARTIAL_FLAG;
10122 return createWrap(func, bitmask, thisArg, partials, holders);
10126 * Creates a function that invokes the method at `object[key]` with `partials`
10127 * prepended to the arguments it receives.
10129 * This method differs from `_.bind` by allowing bound functions to reference
10130 * methods that may be redefined or don't yet exist. See
10131 * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
10132 * for more details.
10134 * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
10135 * builds, may be used as a placeholder for partially applied arguments.
10140 * @category Function
10141 * @param {Object} object The object to invoke the method on.
10142 * @param {string} key The key of the method.
10143 * @param {...*} [partials] The arguments to be partially applied.
10144 * @returns {Function} Returns the new bound function.
10149 * 'greet': function(greeting, punctuation) {
10150 * return greeting + ' ' + this.user + punctuation;
10154 * var bound = _.bindKey(object, 'greet', 'hi');
10158 * object.greet = function(greeting, punctuation) {
10159 * return greeting + 'ya ' + this.user + punctuation;
10163 * // => 'hiya fred!'
10165 * // Bound with placeholders.
10166 * var bound = _.bindKey(object, 'greet', _, '!');
10168 * // => 'hiya fred!'
10170 var bindKey = baseRest(function(object, key, partials) {
10171 var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
10172 if (partials.length) {
10173 var holders = replaceHolders(partials, getHolder(bindKey));
10174 bitmask |= WRAP_PARTIAL_FLAG;
10176 return createWrap(key, bitmask, object, partials, holders);
10180 * Creates a function that accepts arguments of `func` and either invokes
10181 * `func` returning its result, if at least `arity` number of arguments have
10182 * been provided, or returns a function that accepts the remaining `func`
10183 * arguments, and so on. The arity of `func` may be specified if `func.length`
10184 * is not sufficient.
10186 * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
10187 * may be used as a placeholder for provided arguments.
10189 * **Note:** This method doesn't set the "length" property of curried functions.
10194 * @category Function
10195 * @param {Function} func The function to curry.
10196 * @param {number} [arity=func.length] The arity of `func`.
10197 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10198 * @returns {Function} Returns the new curried function.
10201 * var abc = function(a, b, c) {
10202 * return [a, b, c];
10205 * var curried = _.curry(abc);
10207 * curried(1)(2)(3);
10210 * curried(1, 2)(3);
10213 * curried(1, 2, 3);
10216 * // Curried with placeholders.
10217 * curried(1)(_, 3)(2);
10220 function curry(func, arity, guard) {
10221 arity = guard ? undefined : arity;
10222 var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10223 result.placeholder = curry.placeholder;
10228 * This method is like `_.curry` except that arguments are applied to `func`
10229 * in the manner of `_.partialRight` instead of `_.partial`.
10231 * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
10232 * builds, may be used as a placeholder for provided arguments.
10234 * **Note:** This method doesn't set the "length" property of curried functions.
10239 * @category Function
10240 * @param {Function} func The function to curry.
10241 * @param {number} [arity=func.length] The arity of `func`.
10242 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10243 * @returns {Function} Returns the new curried function.
10246 * var abc = function(a, b, c) {
10247 * return [a, b, c];
10250 * var curried = _.curryRight(abc);
10252 * curried(3)(2)(1);
10255 * curried(2, 3)(1);
10258 * curried(1, 2, 3);
10261 * // Curried with placeholders.
10262 * curried(3)(1, _)(2);
10265 function curryRight(func, arity, guard) {
10266 arity = guard ? undefined : arity;
10267 var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10268 result.placeholder = curryRight.placeholder;
10273 * Creates a debounced function that delays invoking `func` until after `wait`
10274 * milliseconds have elapsed since the last time the debounced function was
10275 * invoked. The debounced function comes with a `cancel` method to cancel
10276 * delayed `func` invocations and a `flush` method to immediately invoke them.
10277 * Provide `options` to indicate whether `func` should be invoked on the
10278 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
10279 * with the last arguments provided to the debounced function. Subsequent
10280 * calls to the debounced function return the result of the last `func`
10283 * **Note:** If `leading` and `trailing` options are `true`, `func` is
10284 * invoked on the trailing edge of the timeout only if the debounced function
10285 * is invoked more than once during the `wait` timeout.
10287 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10288 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10290 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10291 * for details over the differences between `_.debounce` and `_.throttle`.
10296 * @category Function
10297 * @param {Function} func The function to debounce.
10298 * @param {number} [wait=0] The number of milliseconds to delay.
10299 * @param {Object} [options={}] The options object.
10300 * @param {boolean} [options.leading=false]
10301 * Specify invoking on the leading edge of the timeout.
10302 * @param {number} [options.maxWait]
10303 * The maximum time `func` is allowed to be delayed before it's invoked.
10304 * @param {boolean} [options.trailing=true]
10305 * Specify invoking on the trailing edge of the timeout.
10306 * @returns {Function} Returns the new debounced function.
10309 * // Avoid costly calculations while the window size is in flux.
10310 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
10312 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
10313 * jQuery(element).on('click', _.debounce(sendMail, 300, {
10315 * 'trailing': false
10318 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
10319 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
10320 * var source = new EventSource('/stream');
10321 * jQuery(source).on('message', debounced);
10323 * // Cancel the trailing debounced invocation.
10324 * jQuery(window).on('popstate', debounced.cancel);
10326 function debounce(func, wait, options) {
10333 lastInvokeTime = 0,
10338 if (typeof func != 'function') {
10339 throw new TypeError(FUNC_ERROR_TEXT);
10341 wait = toNumber(wait) || 0;
10342 if (isObject(options)) {
10343 leading = !!options.leading;
10344 maxing = 'maxWait' in options;
10345 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
10346 trailing = 'trailing' in options ? !!options.trailing : trailing;
10349 function invokeFunc(time) {
10350 var args = lastArgs,
10351 thisArg = lastThis;
10353 lastArgs = lastThis = undefined;
10354 lastInvokeTime = time;
10355 result = func.apply(thisArg, args);
10359 function leadingEdge(time) {
10360 // Reset any `maxWait` timer.
10361 lastInvokeTime = time;
10362 // Start the timer for the trailing edge.
10363 timerId = setTimeout(timerExpired, wait);
10364 // Invoke the leading edge.
10365 return leading ? invokeFunc(time) : result;
10368 function remainingWait(time) {
10369 var timeSinceLastCall = time - lastCallTime,
10370 timeSinceLastInvoke = time - lastInvokeTime,
10371 result = wait - timeSinceLastCall;
10373 return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
10376 function shouldInvoke(time) {
10377 var timeSinceLastCall = time - lastCallTime,
10378 timeSinceLastInvoke = time - lastInvokeTime;
10380 // Either this is the first call, activity has stopped and we're at the
10381 // trailing edge, the system time has gone backwards and we're treating
10382 // it as the trailing edge, or we've hit the `maxWait` limit.
10383 return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
10384 (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
10387 function timerExpired() {
10389 if (shouldInvoke(time)) {
10390 return trailingEdge(time);
10392 // Restart the timer.
10393 timerId = setTimeout(timerExpired, remainingWait(time));
10396 function trailingEdge(time) {
10397 timerId = undefined;
10399 // Only invoke if we have `lastArgs` which means `func` has been
10400 // debounced at least once.
10401 if (trailing && lastArgs) {
10402 return invokeFunc(time);
10404 lastArgs = lastThis = undefined;
10408 function cancel() {
10409 if (timerId !== undefined) {
10410 clearTimeout(timerId);
10412 lastInvokeTime = 0;
10413 lastArgs = lastCallTime = lastThis = timerId = undefined;
10417 return timerId === undefined ? result : trailingEdge(now());
10420 function debounced() {
10422 isInvoking = shouldInvoke(time);
10424 lastArgs = arguments;
10426 lastCallTime = time;
10429 if (timerId === undefined) {
10430 return leadingEdge(lastCallTime);
10433 // Handle invocations in a tight loop.
10434 timerId = setTimeout(timerExpired, wait);
10435 return invokeFunc(lastCallTime);
10438 if (timerId === undefined) {
10439 timerId = setTimeout(timerExpired, wait);
10443 debounced.cancel = cancel;
10444 debounced.flush = flush;
10449 * Defers invoking the `func` until the current call stack has cleared. Any
10450 * additional arguments are provided to `func` when it's invoked.
10455 * @category Function
10456 * @param {Function} func The function to defer.
10457 * @param {...*} [args] The arguments to invoke `func` with.
10458 * @returns {number} Returns the timer id.
10461 * _.defer(function(text) {
10462 * console.log(text);
10464 * // => Logs 'deferred' after one millisecond.
10466 var defer = baseRest(function(func, args) {
10467 return baseDelay(func, 1, args);
10471 * Invokes `func` after `wait` milliseconds. Any additional arguments are
10472 * provided to `func` when it's invoked.
10477 * @category Function
10478 * @param {Function} func The function to delay.
10479 * @param {number} wait The number of milliseconds to delay invocation.
10480 * @param {...*} [args] The arguments to invoke `func` with.
10481 * @returns {number} Returns the timer id.
10484 * _.delay(function(text) {
10485 * console.log(text);
10486 * }, 1000, 'later');
10487 * // => Logs 'later' after one second.
10489 var delay = baseRest(function(func, wait, args) {
10490 return baseDelay(func, toNumber(wait) || 0, args);
10494 * Creates a function that invokes `func` with arguments reversed.
10499 * @category Function
10500 * @param {Function} func The function to flip arguments for.
10501 * @returns {Function} Returns the new flipped function.
10504 * var flipped = _.flip(function() {
10505 * return _.toArray(arguments);
10508 * flipped('a', 'b', 'c', 'd');
10509 * // => ['d', 'c', 'b', 'a']
10511 function flip(func) {
10512 return createWrap(func, WRAP_FLIP_FLAG);
10516 * Creates a function that memoizes the result of `func`. If `resolver` is
10517 * provided, it determines the cache key for storing the result based on the
10518 * arguments provided to the memoized function. By default, the first argument
10519 * provided to the memoized function is used as the map cache key. The `func`
10520 * is invoked with the `this` binding of the memoized function.
10522 * **Note:** The cache is exposed as the `cache` property on the memoized
10523 * function. Its creation may be customized by replacing the `_.memoize.Cache`
10524 * constructor with one whose instances implement the
10525 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
10526 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
10531 * @category Function
10532 * @param {Function} func The function to have its output memoized.
10533 * @param {Function} [resolver] The function to resolve the cache key.
10534 * @returns {Function} Returns the new memoized function.
10537 * var object = { 'a': 1, 'b': 2 };
10538 * var other = { 'c': 3, 'd': 4 };
10540 * var values = _.memoize(_.values);
10551 * // Modify the result cache.
10552 * values.cache.set(object, ['a', 'b']);
10556 * // Replace `_.memoize.Cache`.
10557 * _.memoize.Cache = WeakMap;
10559 function memoize(func, resolver) {
10560 if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
10561 throw new TypeError(FUNC_ERROR_TEXT);
10563 var memoized = function() {
10564 var args = arguments,
10565 key = resolver ? resolver.apply(this, args) : args[0],
10566 cache = memoized.cache;
10568 if (cache.has(key)) {
10569 return cache.get(key);
10571 var result = func.apply(this, args);
10572 memoized.cache = cache.set(key, result) || cache;
10575 memoized.cache = new (memoize.Cache || MapCache);
10579 // Expose `MapCache`.
10580 memoize.Cache = MapCache;
10583 * Creates a function that negates the result of the predicate `func`. The
10584 * `func` predicate is invoked with the `this` binding and arguments of the
10585 * created function.
10590 * @category Function
10591 * @param {Function} predicate The predicate to negate.
10592 * @returns {Function} Returns the new negated function.
10595 * function isEven(n) {
10596 * return n % 2 == 0;
10599 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
10602 function negate(predicate) {
10603 if (typeof predicate != 'function') {
10604 throw new TypeError(FUNC_ERROR_TEXT);
10606 return function() {
10607 var args = arguments;
10608 switch (args.length) {
10609 case 0: return !predicate.call(this);
10610 case 1: return !predicate.call(this, args[0]);
10611 case 2: return !predicate.call(this, args[0], args[1]);
10612 case 3: return !predicate.call(this, args[0], args[1], args[2]);
10614 return !predicate.apply(this, args);
10619 * Creates a function that is restricted to invoking `func` once. Repeat calls
10620 * to the function return the value of the first invocation. The `func` is
10621 * invoked with the `this` binding and arguments of the created function.
10626 * @category Function
10627 * @param {Function} func The function to restrict.
10628 * @returns {Function} Returns the new restricted function.
10631 * var initialize = _.once(createApplication);
10634 * // => `createApplication` is invoked once
10636 function once(func) {
10637 return before(2, func);
10641 * Creates a function that invokes `func` with its arguments transformed.
10646 * @category Function
10647 * @param {Function} func The function to wrap.
10648 * @param {...(Function|Function[])} [transforms=[_.identity]]
10649 * The argument transforms.
10650 * @returns {Function} Returns the new function.
10653 * function doubled(n) {
10657 * function square(n) {
10661 * var func = _.overArgs(function(x, y) {
10663 * }, [square, doubled]);
10671 var overArgs = castRest(function(func, transforms) {
10672 transforms = (transforms.length == 1 && isArray(transforms[0]))
10673 ? arrayMap(transforms[0], baseUnary(getIteratee()))
10674 : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
10676 var funcsLength = transforms.length;
10677 return baseRest(function(args) {
10679 length = nativeMin(args.length, funcsLength);
10681 while (++index < length) {
10682 args[index] = transforms[index].call(this, args[index]);
10684 return apply(func, this, args);
10689 * Creates a function that invokes `func` with `partials` prepended to the
10690 * arguments it receives. This method is like `_.bind` except it does **not**
10691 * alter the `this` binding.
10693 * The `_.partial.placeholder` value, which defaults to `_` in monolithic
10694 * builds, may be used as a placeholder for partially applied arguments.
10696 * **Note:** This method doesn't set the "length" property of partially
10697 * applied functions.
10702 * @category Function
10703 * @param {Function} func The function to partially apply arguments to.
10704 * @param {...*} [partials] The arguments to be partially applied.
10705 * @returns {Function} Returns the new partially applied function.
10708 * function greet(greeting, name) {
10709 * return greeting + ' ' + name;
10712 * var sayHelloTo = _.partial(greet, 'hello');
10713 * sayHelloTo('fred');
10714 * // => 'hello fred'
10716 * // Partially applied with placeholders.
10717 * var greetFred = _.partial(greet, _, 'fred');
10721 var partial = baseRest(function(func, partials) {
10722 var holders = replaceHolders(partials, getHolder(partial));
10723 return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
10727 * This method is like `_.partial` except that partially applied arguments
10728 * are appended to the arguments it receives.
10730 * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
10731 * builds, may be used as a placeholder for partially applied arguments.
10733 * **Note:** This method doesn't set the "length" property of partially
10734 * applied functions.
10739 * @category Function
10740 * @param {Function} func The function to partially apply arguments to.
10741 * @param {...*} [partials] The arguments to be partially applied.
10742 * @returns {Function} Returns the new partially applied function.
10745 * function greet(greeting, name) {
10746 * return greeting + ' ' + name;
10749 * var greetFred = _.partialRight(greet, 'fred');
10753 * // Partially applied with placeholders.
10754 * var sayHelloTo = _.partialRight(greet, 'hello', _);
10755 * sayHelloTo('fred');
10756 * // => 'hello fred'
10758 var partialRight = baseRest(function(func, partials) {
10759 var holders = replaceHolders(partials, getHolder(partialRight));
10760 return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
10764 * Creates a function that invokes `func` with arguments arranged according
10765 * to the specified `indexes` where the argument value at the first index is
10766 * provided as the first argument, the argument value at the second index is
10767 * provided as the second argument, and so on.
10772 * @category Function
10773 * @param {Function} func The function to rearrange arguments for.
10774 * @param {...(number|number[])} indexes The arranged argument indexes.
10775 * @returns {Function} Returns the new function.
10778 * var rearged = _.rearg(function(a, b, c) {
10779 * return [a, b, c];
10782 * rearged('b', 'c', 'a')
10783 * // => ['a', 'b', 'c']
10785 var rearg = flatRest(function(func, indexes) {
10786 return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
10790 * Creates a function that invokes `func` with the `this` binding of the
10791 * created function and arguments from `start` and beyond provided as
10794 * **Note:** This method is based on the
10795 * [rest parameter](https://mdn.io/rest_parameters).
10800 * @category Function
10801 * @param {Function} func The function to apply a rest parameter to.
10802 * @param {number} [start=func.length-1] The start position of the rest parameter.
10803 * @returns {Function} Returns the new function.
10806 * var say = _.rest(function(what, names) {
10807 * return what + ' ' + _.initial(names).join(', ') +
10808 * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
10811 * say('hello', 'fred', 'barney', 'pebbles');
10812 * // => 'hello fred, barney, & pebbles'
10814 function rest(func, start) {
10815 if (typeof func != 'function') {
10816 throw new TypeError(FUNC_ERROR_TEXT);
10818 start = start === undefined ? start : toInteger(start);
10819 return baseRest(func, start);
10823 * Creates a function that invokes `func` with the `this` binding of the
10824 * create function and an array of arguments much like
10825 * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
10827 * **Note:** This method is based on the
10828 * [spread operator](https://mdn.io/spread_operator).
10833 * @category Function
10834 * @param {Function} func The function to spread arguments over.
10835 * @param {number} [start=0] The start position of the spread.
10836 * @returns {Function} Returns the new function.
10839 * var say = _.spread(function(who, what) {
10840 * return who + ' says ' + what;
10843 * say(['fred', 'hello']);
10844 * // => 'fred says hello'
10846 * var numbers = Promise.all([
10847 * Promise.resolve(40),
10848 * Promise.resolve(36)
10851 * numbers.then(_.spread(function(x, y) {
10854 * // => a Promise of 76
10856 function spread(func, start) {
10857 if (typeof func != 'function') {
10858 throw new TypeError(FUNC_ERROR_TEXT);
10860 start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
10861 return baseRest(function(args) {
10862 var array = args[start],
10863 otherArgs = castSlice(args, 0, start);
10866 arrayPush(otherArgs, array);
10868 return apply(func, this, otherArgs);
10873 * Creates a throttled function that only invokes `func` at most once per
10874 * every `wait` milliseconds. The throttled function comes with a `cancel`
10875 * method to cancel delayed `func` invocations and a `flush` method to
10876 * immediately invoke them. Provide `options` to indicate whether `func`
10877 * should be invoked on the leading and/or trailing edge of the `wait`
10878 * timeout. The `func` is invoked with the last arguments provided to the
10879 * throttled function. Subsequent calls to the throttled function return the
10880 * result of the last `func` invocation.
10882 * **Note:** If `leading` and `trailing` options are `true`, `func` is
10883 * invoked on the trailing edge of the timeout only if the throttled function
10884 * is invoked more than once during the `wait` timeout.
10886 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10887 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10889 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10890 * for details over the differences between `_.throttle` and `_.debounce`.
10895 * @category Function
10896 * @param {Function} func The function to throttle.
10897 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10898 * @param {Object} [options={}] The options object.
10899 * @param {boolean} [options.leading=true]
10900 * Specify invoking on the leading edge of the timeout.
10901 * @param {boolean} [options.trailing=true]
10902 * Specify invoking on the trailing edge of the timeout.
10903 * @returns {Function} Returns the new throttled function.
10906 * // Avoid excessively updating the position while scrolling.
10907 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10909 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10910 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10911 * jQuery(element).on('click', throttled);
10913 * // Cancel the trailing throttled invocation.
10914 * jQuery(window).on('popstate', throttled.cancel);
10916 function throttle(func, wait, options) {
10917 var leading = true,
10920 if (typeof func != 'function') {
10921 throw new TypeError(FUNC_ERROR_TEXT);
10923 if (isObject(options)) {
10924 leading = 'leading' in options ? !!options.leading : leading;
10925 trailing = 'trailing' in options ? !!options.trailing : trailing;
10927 return debounce(func, wait, {
10928 'leading': leading,
10930 'trailing': trailing
10935 * Creates a function that accepts up to one argument, ignoring any
10936 * additional arguments.
10941 * @category Function
10942 * @param {Function} func The function to cap arguments for.
10943 * @returns {Function} Returns the new capped function.
10946 * _.map(['6', '8', '10'], _.unary(parseInt));
10949 function unary(func) {
10950 return ary(func, 1);
10954 * Creates a function that provides `value` to `wrapper` as its first
10955 * argument. Any additional arguments provided to the function are appended
10956 * to those provided to the `wrapper`. The wrapper is invoked with the `this`
10957 * binding of the created function.
10962 * @category Function
10963 * @param {*} value The value to wrap.
10964 * @param {Function} [wrapper=identity] The wrapper function.
10965 * @returns {Function} Returns the new function.
10968 * var p = _.wrap(_.escape, function(func, text) {
10969 * return '<p>' + func(text) + '</p>';
10972 * p('fred, barney, & pebbles');
10973 * // => '<p>fred, barney, & pebbles</p>'
10975 function wrap(value, wrapper) {
10976 return partial(castFunction(wrapper), value);
10979 /*------------------------------------------------------------------------*/
10982 * Casts `value` as an array if it's not one.
10988 * @param {*} value The value to inspect.
10989 * @returns {Array} Returns the cast array.
10995 * _.castArray({ 'a': 1 });
10996 * // => [{ 'a': 1 }]
10998 * _.castArray('abc');
11001 * _.castArray(null);
11004 * _.castArray(undefined);
11005 * // => [undefined]
11010 * var array = [1, 2, 3];
11011 * console.log(_.castArray(array) === array);
11014 function castArray() {
11015 if (!arguments.length) {
11018 var value = arguments[0];
11019 return isArray(value) ? value : [value];
11023 * Creates a shallow clone of `value`.
11025 * **Note:** This method is loosely based on the
11026 * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
11027 * and supports cloning arrays, array buffers, booleans, date objects, maps,
11028 * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
11029 * arrays. The own enumerable properties of `arguments` objects are cloned
11030 * as plain objects. An empty object is returned for uncloneable values such
11031 * as error objects, functions, DOM nodes, and WeakMaps.
11037 * @param {*} value The value to clone.
11038 * @returns {*} Returns the cloned value.
11042 * var objects = [{ 'a': 1 }, { 'b': 2 }];
11044 * var shallow = _.clone(objects);
11045 * console.log(shallow[0] === objects[0]);
11048 function clone(value) {
11049 return baseClone(value, CLONE_SYMBOLS_FLAG);
11053 * This method is like `_.clone` except that it accepts `customizer` which
11054 * is invoked to produce the cloned value. If `customizer` returns `undefined`,
11055 * cloning is handled by the method instead. The `customizer` is invoked with
11056 * up to four arguments; (value [, index|key, object, stack]).
11062 * @param {*} value The value to clone.
11063 * @param {Function} [customizer] The function to customize cloning.
11064 * @returns {*} Returns the cloned value.
11065 * @see _.cloneDeepWith
11068 * function customizer(value) {
11069 * if (_.isElement(value)) {
11070 * return value.cloneNode(false);
11074 * var el = _.cloneWith(document.body, customizer);
11076 * console.log(el === document.body);
11078 * console.log(el.nodeName);
11080 * console.log(el.childNodes.length);
11083 function cloneWith(value, customizer) {
11084 customizer = typeof customizer == 'function' ? customizer : undefined;
11085 return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
11089 * This method is like `_.clone` except that it recursively clones `value`.
11095 * @param {*} value The value to recursively clone.
11096 * @returns {*} Returns the deep cloned value.
11100 * var objects = [{ 'a': 1 }, { 'b': 2 }];
11102 * var deep = _.cloneDeep(objects);
11103 * console.log(deep[0] === objects[0]);
11106 function cloneDeep(value) {
11107 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
11111 * This method is like `_.cloneWith` except that it recursively clones `value`.
11117 * @param {*} value The value to recursively clone.
11118 * @param {Function} [customizer] The function to customize cloning.
11119 * @returns {*} Returns the deep cloned value.
11123 * function customizer(value) {
11124 * if (_.isElement(value)) {
11125 * return value.cloneNode(true);
11129 * var el = _.cloneDeepWith(document.body, customizer);
11131 * console.log(el === document.body);
11133 * console.log(el.nodeName);
11135 * console.log(el.childNodes.length);
11138 function cloneDeepWith(value, customizer) {
11139 customizer = typeof customizer == 'function' ? customizer : undefined;
11140 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
11144 * Checks if `object` conforms to `source` by invoking the predicate
11145 * properties of `source` with the corresponding property values of `object`.
11147 * **Note:** This method is equivalent to `_.conforms` when `source` is
11148 * partially applied.
11154 * @param {Object} object The object to inspect.
11155 * @param {Object} source The object of property predicates to conform to.
11156 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
11159 * var object = { 'a': 1, 'b': 2 };
11161 * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
11164 * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
11167 function conformsTo(object, source) {
11168 return source == null || baseConformsTo(object, source, keys(source));
11173 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
11174 * comparison between two values to determine if they are equivalent.
11180 * @param {*} value The value to compare.
11181 * @param {*} other The other value to compare.
11182 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11185 * var object = { 'a': 1 };
11186 * var other = { 'a': 1 };
11188 * _.eq(object, object);
11191 * _.eq(object, other);
11197 * _.eq('a', Object('a'));
11203 function eq(value, other) {
11204 return value === other || (value !== value && other !== other);
11208 * Checks if `value` is greater than `other`.
11214 * @param {*} value The value to compare.
11215 * @param {*} other The other value to compare.
11216 * @returns {boolean} Returns `true` if `value` is greater than `other`,
11230 var gt = createRelationalOperation(baseGt);
11233 * Checks if `value` is greater than or equal to `other`.
11239 * @param {*} value The value to compare.
11240 * @param {*} other The other value to compare.
11241 * @returns {boolean} Returns `true` if `value` is greater than or equal to
11242 * `other`, else `false`.
11255 var gte = createRelationalOperation(function(value, other) {
11256 return value >= other;
11260 * Checks if `value` is likely an `arguments` object.
11266 * @param {*} value The value to check.
11267 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
11271 * _.isArguments(function() { return arguments; }());
11274 * _.isArguments([1, 2, 3]);
11277 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
11278 return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
11279 !propertyIsEnumerable.call(value, 'callee');
11283 * Checks if `value` is classified as an `Array` object.
11289 * @param {*} value The value to check.
11290 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
11293 * _.isArray([1, 2, 3]);
11296 * _.isArray(document.body.children);
11299 * _.isArray('abc');
11302 * _.isArray(_.noop);
11305 var isArray = Array.isArray;
11308 * Checks if `value` is classified as an `ArrayBuffer` object.
11314 * @param {*} value The value to check.
11315 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
11318 * _.isArrayBuffer(new ArrayBuffer(2));
11321 * _.isArrayBuffer(new Array(2));
11324 var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
11327 * Checks if `value` is array-like. A value is considered array-like if it's
11328 * not a function and has a `value.length` that's an integer greater than or
11329 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
11335 * @param {*} value The value to check.
11336 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
11339 * _.isArrayLike([1, 2, 3]);
11342 * _.isArrayLike(document.body.children);
11345 * _.isArrayLike('abc');
11348 * _.isArrayLike(_.noop);
11351 function isArrayLike(value) {
11352 return value != null && isLength(value.length) && !isFunction(value);
11356 * This method is like `_.isArrayLike` except that it also checks if `value`
11363 * @param {*} value The value to check.
11364 * @returns {boolean} Returns `true` if `value` is an array-like object,
11368 * _.isArrayLikeObject([1, 2, 3]);
11371 * _.isArrayLikeObject(document.body.children);
11374 * _.isArrayLikeObject('abc');
11377 * _.isArrayLikeObject(_.noop);
11380 function isArrayLikeObject(value) {
11381 return isObjectLike(value) && isArrayLike(value);
11385 * Checks if `value` is classified as a boolean primitive or object.
11391 * @param {*} value The value to check.
11392 * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
11395 * _.isBoolean(false);
11398 * _.isBoolean(null);
11401 function isBoolean(value) {
11402 return value === true || value === false ||
11403 (isObjectLike(value) && baseGetTag(value) == boolTag);
11407 * Checks if `value` is a buffer.
11413 * @param {*} value The value to check.
11414 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
11417 * _.isBuffer(new Buffer(2));
11420 * _.isBuffer(new Uint8Array(2));
11423 var isBuffer = nativeIsBuffer || stubFalse;
11426 * Checks if `value` is classified as a `Date` object.
11432 * @param {*} value The value to check.
11433 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
11436 * _.isDate(new Date);
11439 * _.isDate('Mon April 23 2012');
11442 var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
11445 * Checks if `value` is likely a DOM element.
11451 * @param {*} value The value to check.
11452 * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
11455 * _.isElement(document.body);
11458 * _.isElement('<body>');
11461 function isElement(value) {
11462 return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
11466 * Checks if `value` is an empty object, collection, map, or set.
11468 * Objects are considered empty if they have no own enumerable string keyed
11471 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
11472 * jQuery-like collections are considered empty if they have a `length` of `0`.
11473 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
11479 * @param {*} value The value to check.
11480 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
11492 * _.isEmpty([1, 2, 3]);
11495 * _.isEmpty({ 'a': 1 });
11498 function isEmpty(value) {
11499 if (value == null) {
11502 if (isArrayLike(value) &&
11503 (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
11504 isBuffer(value) || isTypedArray(value) || isArguments(value))) {
11505 return !value.length;
11507 var tag = getTag(value);
11508 if (tag == mapTag || tag == setTag) {
11509 return !value.size;
11511 if (isPrototype(value)) {
11512 return !baseKeys(value).length;
11514 for (var key in value) {
11515 if (hasOwnProperty.call(value, key)) {
11523 * Performs a deep comparison between two values to determine if they are
11526 * **Note:** This method supports comparing arrays, array buffers, booleans,
11527 * date objects, error objects, maps, numbers, `Object` objects, regexes,
11528 * sets, strings, symbols, and typed arrays. `Object` objects are compared
11529 * by their own, not inherited, enumerable properties. Functions and DOM
11530 * nodes are **not** supported.
11536 * @param {*} value The value to compare.
11537 * @param {*} other The other value to compare.
11538 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11541 * var object = { 'a': 1 };
11542 * var other = { 'a': 1 };
11544 * _.isEqual(object, other);
11547 * object === other;
11550 function isEqual(value, other) {
11551 return baseIsEqual(value, other);
11555 * This method is like `_.isEqual` except that it accepts `customizer` which
11556 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11557 * are handled by the method instead. The `customizer` is invoked with up to
11558 * six arguments: (objValue, othValue [, index|key, object, other, stack]).
11564 * @param {*} value The value to compare.
11565 * @param {*} other The other value to compare.
11566 * @param {Function} [customizer] The function to customize comparisons.
11567 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11570 * function isGreeting(value) {
11571 * return /^h(?:i|ello)$/.test(value);
11574 * function customizer(objValue, othValue) {
11575 * if (isGreeting(objValue) && isGreeting(othValue)) {
11580 * var array = ['hello', 'goodbye'];
11581 * var other = ['hi', 'goodbye'];
11583 * _.isEqualWith(array, other, customizer);
11586 function isEqualWith(value, other, customizer) {
11587 customizer = typeof customizer == 'function' ? customizer : undefined;
11588 var result = customizer ? customizer(value, other) : undefined;
11589 return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
11593 * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
11594 * `SyntaxError`, `TypeError`, or `URIError` object.
11600 * @param {*} value The value to check.
11601 * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
11604 * _.isError(new Error);
11607 * _.isError(Error);
11610 function isError(value) {
11611 if (!isObjectLike(value)) {
11614 var tag = baseGetTag(value);
11615 return tag == errorTag || tag == domExcTag ||
11616 (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
11620 * Checks if `value` is a finite primitive number.
11622 * **Note:** This method is based on
11623 * [`Number.isFinite`](https://mdn.io/Number/isFinite).
11629 * @param {*} value The value to check.
11630 * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
11636 * _.isFinite(Number.MIN_VALUE);
11639 * _.isFinite(Infinity);
11645 function isFinite(value) {
11646 return typeof value == 'number' && nativeIsFinite(value);
11650 * Checks if `value` is classified as a `Function` object.
11656 * @param {*} value The value to check.
11657 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
11663 * _.isFunction(/abc/);
11666 function isFunction(value) {
11667 if (!isObject(value)) {
11670 // The use of `Object#toString` avoids issues with the `typeof` operator
11671 // in Safari 9 which returns 'object' for typed arrays and other constructors.
11672 var tag = baseGetTag(value);
11673 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
11677 * Checks if `value` is an integer.
11679 * **Note:** This method is based on
11680 * [`Number.isInteger`](https://mdn.io/Number/isInteger).
11686 * @param {*} value The value to check.
11687 * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
11693 * _.isInteger(Number.MIN_VALUE);
11696 * _.isInteger(Infinity);
11699 * _.isInteger('3');
11702 function isInteger(value) {
11703 return typeof value == 'number' && value == toInteger(value);
11707 * Checks if `value` is a valid array-like length.
11709 * **Note:** This method is loosely based on
11710 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
11716 * @param {*} value The value to check.
11717 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
11723 * _.isLength(Number.MIN_VALUE);
11726 * _.isLength(Infinity);
11732 function isLength(value) {
11733 return typeof value == 'number' &&
11734 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
11738 * Checks if `value` is the
11739 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
11740 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
11746 * @param {*} value The value to check.
11747 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
11753 * _.isObject([1, 2, 3]);
11756 * _.isObject(_.noop);
11759 * _.isObject(null);
11762 function isObject(value) {
11763 var type = typeof value;
11764 return value != null && (type == 'object' || type == 'function');
11768 * Checks if `value` is object-like. A value is object-like if it's not `null`
11769 * and has a `typeof` result of "object".
11775 * @param {*} value The value to check.
11776 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
11779 * _.isObjectLike({});
11782 * _.isObjectLike([1, 2, 3]);
11785 * _.isObjectLike(_.noop);
11788 * _.isObjectLike(null);
11791 function isObjectLike(value) {
11792 return value != null && typeof value == 'object';
11796 * Checks if `value` is classified as a `Map` object.
11802 * @param {*} value The value to check.
11803 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
11806 * _.isMap(new Map);
11809 * _.isMap(new WeakMap);
11812 var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
11815 * Performs a partial deep comparison between `object` and `source` to
11816 * determine if `object` contains equivalent property values.
11818 * **Note:** This method is equivalent to `_.matches` when `source` is
11819 * partially applied.
11821 * Partial comparisons will match empty array and empty object `source`
11822 * values against any array or object value, respectively. See `_.isEqual`
11823 * for a list of supported value comparisons.
11829 * @param {Object} object The object to inspect.
11830 * @param {Object} source The object of property values to match.
11831 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11834 * var object = { 'a': 1, 'b': 2 };
11836 * _.isMatch(object, { 'b': 2 });
11839 * _.isMatch(object, { 'b': 1 });
11842 function isMatch(object, source) {
11843 return object === source || baseIsMatch(object, source, getMatchData(source));
11847 * This method is like `_.isMatch` except that it accepts `customizer` which
11848 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11849 * are handled by the method instead. The `customizer` is invoked with five
11850 * arguments: (objValue, srcValue, index|key, object, source).
11856 * @param {Object} object The object to inspect.
11857 * @param {Object} source The object of property values to match.
11858 * @param {Function} [customizer] The function to customize comparisons.
11859 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11862 * function isGreeting(value) {
11863 * return /^h(?:i|ello)$/.test(value);
11866 * function customizer(objValue, srcValue) {
11867 * if (isGreeting(objValue) && isGreeting(srcValue)) {
11872 * var object = { 'greeting': 'hello' };
11873 * var source = { 'greeting': 'hi' };
11875 * _.isMatchWith(object, source, customizer);
11878 function isMatchWith(object, source, customizer) {
11879 customizer = typeof customizer == 'function' ? customizer : undefined;
11880 return baseIsMatch(object, source, getMatchData(source), customizer);
11884 * Checks if `value` is `NaN`.
11886 * **Note:** This method is based on
11887 * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11888 * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11889 * `undefined` and other non-number values.
11895 * @param {*} value The value to check.
11896 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11902 * _.isNaN(new Number(NaN));
11905 * isNaN(undefined);
11908 * _.isNaN(undefined);
11911 function isNaN(value) {
11912 // An `NaN` primitive is the only value that is not equal to itself.
11913 // Perform the `toStringTag` check first to avoid errors with some
11914 // ActiveX objects in IE.
11915 return isNumber(value) && value != +value;
11919 * Checks if `value` is a pristine native function.
11921 * **Note:** This method can't reliably detect native functions in the presence
11922 * of the core-js package because core-js circumvents this kind of detection.
11923 * Despite multiple requests, the core-js maintainer has made it clear: any
11924 * attempt to fix the detection will be obstructed. As a result, we're left
11925 * with little choice but to throw an error. Unfortunately, this also affects
11926 * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
11927 * which rely on core-js.
11933 * @param {*} value The value to check.
11934 * @returns {boolean} Returns `true` if `value` is a native function,
11938 * _.isNative(Array.prototype.push);
11944 function isNative(value) {
11945 if (isMaskable(value)) {
11946 throw new Error(CORE_ERROR_TEXT);
11948 return baseIsNative(value);
11952 * Checks if `value` is `null`.
11958 * @param {*} value The value to check.
11959 * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
11965 * _.isNull(void 0);
11968 function isNull(value) {
11969 return value === null;
11973 * Checks if `value` is `null` or `undefined`.
11979 * @param {*} value The value to check.
11980 * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
11992 function isNil(value) {
11993 return value == null;
11997 * Checks if `value` is classified as a `Number` primitive or object.
11999 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
12000 * classified as numbers, use the `_.isFinite` method.
12006 * @param {*} value The value to check.
12007 * @returns {boolean} Returns `true` if `value` is a number, else `false`.
12013 * _.isNumber(Number.MIN_VALUE);
12016 * _.isNumber(Infinity);
12022 function isNumber(value) {
12023 return typeof value == 'number' ||
12024 (isObjectLike(value) && baseGetTag(value) == numberTag);
12028 * Checks if `value` is a plain object, that is, an object created by the
12029 * `Object` constructor or one with a `[[Prototype]]` of `null`.
12035 * @param {*} value The value to check.
12036 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
12043 * _.isPlainObject(new Foo);
12046 * _.isPlainObject([1, 2, 3]);
12049 * _.isPlainObject({ 'x': 0, 'y': 0 });
12052 * _.isPlainObject(Object.create(null));
12055 function isPlainObject(value) {
12056 if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
12059 var proto = getPrototype(value);
12060 if (proto === null) {
12063 var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
12064 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
12065 funcToString.call(Ctor) == objectCtorString;
12069 * Checks if `value` is classified as a `RegExp` object.
12075 * @param {*} value The value to check.
12076 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
12079 * _.isRegExp(/abc/);
12082 * _.isRegExp('/abc/');
12085 var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
12088 * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
12089 * double precision number which isn't the result of a rounded unsafe integer.
12091 * **Note:** This method is based on
12092 * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
12098 * @param {*} value The value to check.
12099 * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
12102 * _.isSafeInteger(3);
12105 * _.isSafeInteger(Number.MIN_VALUE);
12108 * _.isSafeInteger(Infinity);
12111 * _.isSafeInteger('3');
12114 function isSafeInteger(value) {
12115 return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
12119 * Checks if `value` is classified as a `Set` object.
12125 * @param {*} value The value to check.
12126 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
12129 * _.isSet(new Set);
12132 * _.isSet(new WeakSet);
12135 var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
12138 * Checks if `value` is classified as a `String` primitive or object.
12144 * @param {*} value The value to check.
12145 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
12148 * _.isString('abc');
12154 function isString(value) {
12155 return typeof value == 'string' ||
12156 (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
12160 * Checks if `value` is classified as a `Symbol` primitive or object.
12166 * @param {*} value The value to check.
12167 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
12170 * _.isSymbol(Symbol.iterator);
12173 * _.isSymbol('abc');
12176 function isSymbol(value) {
12177 return typeof value == 'symbol' ||
12178 (isObjectLike(value) && baseGetTag(value) == symbolTag);
12182 * Checks if `value` is classified as a typed array.
12188 * @param {*} value The value to check.
12189 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
12192 * _.isTypedArray(new Uint8Array);
12195 * _.isTypedArray([]);
12198 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
12201 * Checks if `value` is `undefined`.
12207 * @param {*} value The value to check.
12208 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
12211 * _.isUndefined(void 0);
12214 * _.isUndefined(null);
12217 function isUndefined(value) {
12218 return value === undefined;
12222 * Checks if `value` is classified as a `WeakMap` object.
12228 * @param {*} value The value to check.
12229 * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
12232 * _.isWeakMap(new WeakMap);
12235 * _.isWeakMap(new Map);
12238 function isWeakMap(value) {
12239 return isObjectLike(value) && getTag(value) == weakMapTag;
12243 * Checks if `value` is classified as a `WeakSet` object.
12249 * @param {*} value The value to check.
12250 * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
12253 * _.isWeakSet(new WeakSet);
12256 * _.isWeakSet(new Set);
12259 function isWeakSet(value) {
12260 return isObjectLike(value) && baseGetTag(value) == weakSetTag;
12264 * Checks if `value` is less than `other`.
12270 * @param {*} value The value to compare.
12271 * @param {*} other The other value to compare.
12272 * @returns {boolean} Returns `true` if `value` is less than `other`,
12286 var lt = createRelationalOperation(baseLt);
12289 * Checks if `value` is less than or equal to `other`.
12295 * @param {*} value The value to compare.
12296 * @param {*} other The other value to compare.
12297 * @returns {boolean} Returns `true` if `value` is less than or equal to
12298 * `other`, else `false`.
12311 var lte = createRelationalOperation(function(value, other) {
12312 return value <= other;
12316 * Converts `value` to an array.
12322 * @param {*} value The value to convert.
12323 * @returns {Array} Returns the converted array.
12326 * _.toArray({ 'a': 1, 'b': 2 });
12329 * _.toArray('abc');
12330 * // => ['a', 'b', 'c']
12338 function toArray(value) {
12342 if (isArrayLike(value)) {
12343 return isString(value) ? stringToArray(value) : copyArray(value);
12345 if (symIterator && value[symIterator]) {
12346 return iteratorToArray(value[symIterator]());
12348 var tag = getTag(value),
12349 func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
12351 return func(value);
12355 * Converts `value` to a finite number.
12361 * @param {*} value The value to convert.
12362 * @returns {number} Returns the converted number.
12368 * _.toFinite(Number.MIN_VALUE);
12371 * _.toFinite(Infinity);
12372 * // => 1.7976931348623157e+308
12374 * _.toFinite('3.2');
12377 function toFinite(value) {
12379 return value === 0 ? value : 0;
12381 value = toNumber(value);
12382 if (value === INFINITY || value === -INFINITY) {
12383 var sign = (value < 0 ? -1 : 1);
12384 return sign * MAX_INTEGER;
12386 return value === value ? value : 0;
12390 * Converts `value` to an integer.
12392 * **Note:** This method is loosely based on
12393 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
12399 * @param {*} value The value to convert.
12400 * @returns {number} Returns the converted integer.
12403 * _.toInteger(3.2);
12406 * _.toInteger(Number.MIN_VALUE);
12409 * _.toInteger(Infinity);
12410 * // => 1.7976931348623157e+308
12412 * _.toInteger('3.2');
12415 function toInteger(value) {
12416 var result = toFinite(value),
12417 remainder = result % 1;
12419 return result === result ? (remainder ? result - remainder : result) : 0;
12423 * Converts `value` to an integer suitable for use as the length of an
12424 * array-like object.
12426 * **Note:** This method is based on
12427 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12433 * @param {*} value The value to convert.
12434 * @returns {number} Returns the converted integer.
12440 * _.toLength(Number.MIN_VALUE);
12443 * _.toLength(Infinity);
12446 * _.toLength('3.2');
12449 function toLength(value) {
12450 return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
12454 * Converts `value` to a number.
12460 * @param {*} value The value to process.
12461 * @returns {number} Returns the number.
12467 * _.toNumber(Number.MIN_VALUE);
12470 * _.toNumber(Infinity);
12473 * _.toNumber('3.2');
12476 function toNumber(value) {
12477 if (typeof value == 'number') {
12480 if (isSymbol(value)) {
12483 if (isObject(value)) {
12484 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
12485 value = isObject(other) ? (other + '') : other;
12487 if (typeof value != 'string') {
12488 return value === 0 ? value : +value;
12490 value = value.replace(reTrim, '');
12491 var isBinary = reIsBinary.test(value);
12492 return (isBinary || reIsOctal.test(value))
12493 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
12494 : (reIsBadHex.test(value) ? NAN : +value);
12498 * Converts `value` to a plain object flattening inherited enumerable string
12499 * keyed properties of `value` to own properties of the plain object.
12505 * @param {*} value The value to convert.
12506 * @returns {Object} Returns the converted plain object.
12513 * Foo.prototype.c = 3;
12515 * _.assign({ 'a': 1 }, new Foo);
12516 * // => { 'a': 1, 'b': 2 }
12518 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
12519 * // => { 'a': 1, 'b': 2, 'c': 3 }
12521 function toPlainObject(value) {
12522 return copyObject(value, keysIn(value));
12526 * Converts `value` to a safe integer. A safe integer can be compared and
12527 * represented correctly.
12533 * @param {*} value The value to convert.
12534 * @returns {number} Returns the converted integer.
12537 * _.toSafeInteger(3.2);
12540 * _.toSafeInteger(Number.MIN_VALUE);
12543 * _.toSafeInteger(Infinity);
12544 * // => 9007199254740991
12546 * _.toSafeInteger('3.2');
12549 function toSafeInteger(value) {
12550 return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
12554 * Converts `value` to a string. An empty string is returned for `null`
12555 * and `undefined` values. The sign of `-0` is preserved.
12561 * @param {*} value The value to convert.
12562 * @returns {string} Returns the converted string.
12565 * _.toString(null);
12571 * _.toString([1, 2, 3]);
12574 function toString(value) {
12575 return value == null ? '' : baseToString(value);
12578 /*------------------------------------------------------------------------*/
12581 * Assigns own enumerable string keyed properties of source objects to the
12582 * destination object. Source objects are applied from left to right.
12583 * Subsequent sources overwrite property assignments of previous sources.
12585 * **Note:** This method mutates `object` and is loosely based on
12586 * [`Object.assign`](https://mdn.io/Object/assign).
12592 * @param {Object} object The destination object.
12593 * @param {...Object} [sources] The source objects.
12594 * @returns {Object} Returns `object`.
12606 * Foo.prototype.b = 2;
12607 * Bar.prototype.d = 4;
12609 * _.assign({ 'a': 0 }, new Foo, new Bar);
12610 * // => { 'a': 1, 'c': 3 }
12612 var assign = createAssigner(function(object, source) {
12613 if (isPrototype(source) || isArrayLike(source)) {
12614 copyObject(source, keys(source), object);
12617 for (var key in source) {
12618 if (hasOwnProperty.call(source, key)) {
12619 assignValue(object, key, source[key]);
12625 * This method is like `_.assign` except that it iterates over own and
12626 * inherited source properties.
12628 * **Note:** This method mutates `object`.
12635 * @param {Object} object The destination object.
12636 * @param {...Object} [sources] The source objects.
12637 * @returns {Object} Returns `object`.
12649 * Foo.prototype.b = 2;
12650 * Bar.prototype.d = 4;
12652 * _.assignIn({ 'a': 0 }, new Foo, new Bar);
12653 * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
12655 var assignIn = createAssigner(function(object, source) {
12656 copyObject(source, keysIn(source), object);
12660 * This method is like `_.assignIn` except that it accepts `customizer`
12661 * which is invoked to produce the assigned values. If `customizer` returns
12662 * `undefined`, assignment is handled by the method instead. The `customizer`
12663 * is invoked with five arguments: (objValue, srcValue, key, object, source).
12665 * **Note:** This method mutates `object`.
12670 * @alias extendWith
12672 * @param {Object} object The destination object.
12673 * @param {...Object} sources The source objects.
12674 * @param {Function} [customizer] The function to customize assigned values.
12675 * @returns {Object} Returns `object`.
12676 * @see _.assignWith
12679 * function customizer(objValue, srcValue) {
12680 * return _.isUndefined(objValue) ? srcValue : objValue;
12683 * var defaults = _.partialRight(_.assignInWith, customizer);
12685 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12686 * // => { 'a': 1, 'b': 2 }
12688 var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
12689 copyObject(source, keysIn(source), object, customizer);
12693 * This method is like `_.assign` except that it accepts `customizer`
12694 * which is invoked to produce the assigned values. If `customizer` returns
12695 * `undefined`, assignment is handled by the method instead. The `customizer`
12696 * is invoked with five arguments: (objValue, srcValue, key, object, source).
12698 * **Note:** This method mutates `object`.
12704 * @param {Object} object The destination object.
12705 * @param {...Object} sources The source objects.
12706 * @param {Function} [customizer] The function to customize assigned values.
12707 * @returns {Object} Returns `object`.
12708 * @see _.assignInWith
12711 * function customizer(objValue, srcValue) {
12712 * return _.isUndefined(objValue) ? srcValue : objValue;
12715 * var defaults = _.partialRight(_.assignWith, customizer);
12717 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12718 * // => { 'a': 1, 'b': 2 }
12720 var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
12721 copyObject(source, keys(source), object, customizer);
12725 * Creates an array of values corresponding to `paths` of `object`.
12731 * @param {Object} object The object to iterate over.
12732 * @param {...(string|string[])} [paths] The property paths to pick.
12733 * @returns {Array} Returns the picked values.
12736 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
12738 * _.at(object, ['a[0].b.c', 'a[1]']);
12741 var at = flatRest(baseAt);
12744 * Creates an object that inherits from the `prototype` object. If a
12745 * `properties` object is given, its own enumerable string keyed properties
12746 * are assigned to the created object.
12752 * @param {Object} prototype The object to inherit from.
12753 * @param {Object} [properties] The properties to assign to the object.
12754 * @returns {Object} Returns the new object.
12757 * function Shape() {
12762 * function Circle() {
12763 * Shape.call(this);
12766 * Circle.prototype = _.create(Shape.prototype, {
12767 * 'constructor': Circle
12770 * var circle = new Circle;
12771 * circle instanceof Circle;
12774 * circle instanceof Shape;
12777 function create(prototype, properties) {
12778 var result = baseCreate(prototype);
12779 return properties == null ? result : baseAssign(result, properties);
12783 * Assigns own and inherited enumerable string keyed properties of source
12784 * objects to the destination object for all destination properties that
12785 * resolve to `undefined`. Source objects are applied from left to right.
12786 * Once a property is set, additional values of the same property are ignored.
12788 * **Note:** This method mutates `object`.
12794 * @param {Object} object The destination object.
12795 * @param {...Object} [sources] The source objects.
12796 * @returns {Object} Returns `object`.
12797 * @see _.defaultsDeep
12800 * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12801 * // => { 'a': 1, 'b': 2 }
12803 var defaults = baseRest(function(args) {
12804 args.push(undefined, assignInDefaults);
12805 return apply(assignInWith, undefined, args);
12809 * This method is like `_.defaults` except that it recursively assigns
12810 * default properties.
12812 * **Note:** This method mutates `object`.
12818 * @param {Object} object The destination object.
12819 * @param {...Object} [sources] The source objects.
12820 * @returns {Object} Returns `object`.
12824 * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
12825 * // => { 'a': { 'b': 2, 'c': 3 } }
12827 var defaultsDeep = baseRest(function(args) {
12828 args.push(undefined, mergeDefaults);
12829 return apply(mergeWith, undefined, args);
12833 * This method is like `_.find` except that it returns the key of the first
12834 * element `predicate` returns truthy for instead of the element itself.
12840 * @param {Object} object The object to inspect.
12841 * @param {Function} [predicate=_.identity] The function invoked per iteration.
12842 * @returns {string|undefined} Returns the key of the matched element,
12843 * else `undefined`.
12847 * 'barney': { 'age': 36, 'active': true },
12848 * 'fred': { 'age': 40, 'active': false },
12849 * 'pebbles': { 'age': 1, 'active': true }
12852 * _.findKey(users, function(o) { return o.age < 40; });
12853 * // => 'barney' (iteration order is not guaranteed)
12855 * // The `_.matches` iteratee shorthand.
12856 * _.findKey(users, { 'age': 1, 'active': true });
12859 * // The `_.matchesProperty` iteratee shorthand.
12860 * _.findKey(users, ['active', false]);
12863 * // The `_.property` iteratee shorthand.
12864 * _.findKey(users, 'active');
12867 function findKey(object, predicate) {
12868 return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
12872 * This method is like `_.findKey` except that it iterates over elements of
12873 * a collection in the opposite order.
12879 * @param {Object} object The object to inspect.
12880 * @param {Function} [predicate=_.identity] The function invoked per iteration.
12881 * @returns {string|undefined} Returns the key of the matched element,
12882 * else `undefined`.
12886 * 'barney': { 'age': 36, 'active': true },
12887 * 'fred': { 'age': 40, 'active': false },
12888 * 'pebbles': { 'age': 1, 'active': true }
12891 * _.findLastKey(users, function(o) { return o.age < 40; });
12892 * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12894 * // The `_.matches` iteratee shorthand.
12895 * _.findLastKey(users, { 'age': 36, 'active': true });
12898 * // The `_.matchesProperty` iteratee shorthand.
12899 * _.findLastKey(users, ['active', false]);
12902 * // The `_.property` iteratee shorthand.
12903 * _.findLastKey(users, 'active');
12906 function findLastKey(object, predicate) {
12907 return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
12911 * Iterates over own and inherited enumerable string keyed properties of an
12912 * object and invokes `iteratee` for each property. The iteratee is invoked
12913 * with three arguments: (value, key, object). Iteratee functions may exit
12914 * iteration early by explicitly returning `false`.
12920 * @param {Object} object The object to iterate over.
12921 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12922 * @returns {Object} Returns `object`.
12923 * @see _.forInRight
12931 * Foo.prototype.c = 3;
12933 * _.forIn(new Foo, function(value, key) {
12934 * console.log(key);
12936 * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
12938 function forIn(object, iteratee) {
12939 return object == null
12941 : baseFor(object, getIteratee(iteratee, 3), keysIn);
12945 * This method is like `_.forIn` except that it iterates over properties of
12946 * `object` in the opposite order.
12952 * @param {Object} object The object to iterate over.
12953 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12954 * @returns {Object} Returns `object`.
12963 * Foo.prototype.c = 3;
12965 * _.forInRight(new Foo, function(value, key) {
12966 * console.log(key);
12968 * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
12970 function forInRight(object, iteratee) {
12971 return object == null
12973 : baseForRight(object, getIteratee(iteratee, 3), keysIn);
12977 * Iterates over own enumerable string keyed properties of an object and
12978 * invokes `iteratee` for each property. The iteratee is invoked with three
12979 * arguments: (value, key, object). Iteratee functions may exit iteration
12980 * early by explicitly returning `false`.
12986 * @param {Object} object The object to iterate over.
12987 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12988 * @returns {Object} Returns `object`.
12989 * @see _.forOwnRight
12997 * Foo.prototype.c = 3;
12999 * _.forOwn(new Foo, function(value, key) {
13000 * console.log(key);
13002 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
13004 function forOwn(object, iteratee) {
13005 return object && baseForOwn(object, getIteratee(iteratee, 3));
13009 * This method is like `_.forOwn` except that it iterates over properties of
13010 * `object` in the opposite order.
13016 * @param {Object} object The object to iterate over.
13017 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13018 * @returns {Object} Returns `object`.
13027 * Foo.prototype.c = 3;
13029 * _.forOwnRight(new Foo, function(value, key) {
13030 * console.log(key);
13032 * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
13034 function forOwnRight(object, iteratee) {
13035 return object && baseForOwnRight(object, getIteratee(iteratee, 3));
13039 * Creates an array of function property names from own enumerable properties
13046 * @param {Object} object The object to inspect.
13047 * @returns {Array} Returns the function names.
13048 * @see _.functionsIn
13052 * this.a = _.constant('a');
13053 * this.b = _.constant('b');
13056 * Foo.prototype.c = _.constant('c');
13058 * _.functions(new Foo);
13061 function functions(object) {
13062 return object == null ? [] : baseFunctions(object, keys(object));
13066 * Creates an array of function property names from own and inherited
13067 * enumerable properties of `object`.
13073 * @param {Object} object The object to inspect.
13074 * @returns {Array} Returns the function names.
13079 * this.a = _.constant('a');
13080 * this.b = _.constant('b');
13083 * Foo.prototype.c = _.constant('c');
13085 * _.functionsIn(new Foo);
13086 * // => ['a', 'b', 'c']
13088 function functionsIn(object) {
13089 return object == null ? [] : baseFunctions(object, keysIn(object));
13093 * Gets the value at `path` of `object`. If the resolved value is
13094 * `undefined`, the `defaultValue` is returned in its place.
13100 * @param {Object} object The object to query.
13101 * @param {Array|string} path The path of the property to get.
13102 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13103 * @returns {*} Returns the resolved value.
13106 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13108 * _.get(object, 'a[0].b.c');
13111 * _.get(object, ['a', '0', 'b', 'c']);
13114 * _.get(object, 'a.b.c', 'default');
13117 function get(object, path, defaultValue) {
13118 var result = object == null ? undefined : baseGet(object, path);
13119 return result === undefined ? defaultValue : result;
13123 * Checks if `path` is a direct property of `object`.
13129 * @param {Object} object The object to query.
13130 * @param {Array|string} path The path to check.
13131 * @returns {boolean} Returns `true` if `path` exists, else `false`.
13134 * var object = { 'a': { 'b': 2 } };
13135 * var other = _.create({ 'a': _.create({ 'b': 2 }) });
13137 * _.has(object, 'a');
13140 * _.has(object, 'a.b');
13143 * _.has(object, ['a', 'b']);
13146 * _.has(other, 'a');
13149 function has(object, path) {
13150 return object != null && hasPath(object, path, baseHas);
13154 * Checks if `path` is a direct or inherited property of `object`.
13160 * @param {Object} object The object to query.
13161 * @param {Array|string} path The path to check.
13162 * @returns {boolean} Returns `true` if `path` exists, else `false`.
13165 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
13167 * _.hasIn(object, 'a');
13170 * _.hasIn(object, 'a.b');
13173 * _.hasIn(object, ['a', 'b']);
13176 * _.hasIn(object, 'b');
13179 function hasIn(object, path) {
13180 return object != null && hasPath(object, path, baseHasIn);
13184 * Creates an object composed of the inverted keys and values of `object`.
13185 * If `object` contains duplicate values, subsequent values overwrite
13186 * property assignments of previous values.
13192 * @param {Object} object The object to invert.
13193 * @returns {Object} Returns the new inverted object.
13196 * var object = { 'a': 1, 'b': 2, 'c': 1 };
13198 * _.invert(object);
13199 * // => { '1': 'c', '2': 'b' }
13201 var invert = createInverter(function(result, value, key) {
13202 result[value] = key;
13203 }, constant(identity));
13206 * This method is like `_.invert` except that the inverted object is generated
13207 * from the results of running each element of `object` thru `iteratee`. The
13208 * corresponding inverted value of each inverted key is an array of keys
13209 * responsible for generating the inverted value. The iteratee is invoked
13210 * with one argument: (value).
13216 * @param {Object} object The object to invert.
13217 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
13218 * @returns {Object} Returns the new inverted object.
13221 * var object = { 'a': 1, 'b': 2, 'c': 1 };
13223 * _.invertBy(object);
13224 * // => { '1': ['a', 'c'], '2': ['b'] }
13226 * _.invertBy(object, function(value) {
13227 * return 'group' + value;
13229 * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
13231 var invertBy = createInverter(function(result, value, key) {
13232 if (hasOwnProperty.call(result, value)) {
13233 result[value].push(key);
13235 result[value] = [key];
13240 * Invokes the method at `path` of `object`.
13246 * @param {Object} object The object to query.
13247 * @param {Array|string} path The path of the method to invoke.
13248 * @param {...*} [args] The arguments to invoke the method with.
13249 * @returns {*} Returns the result of the invoked method.
13252 * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
13254 * _.invoke(object, 'a[0].b.c.slice', 1, 3);
13257 var invoke = baseRest(baseInvoke);
13260 * Creates an array of the own enumerable property names of `object`.
13262 * **Note:** Non-object values are coerced to objects. See the
13263 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
13264 * for more details.
13270 * @param {Object} object The object to query.
13271 * @returns {Array} Returns the array of property names.
13279 * Foo.prototype.c = 3;
13282 * // => ['a', 'b'] (iteration order is not guaranteed)
13287 function keys(object) {
13288 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
13292 * Creates an array of the own and inherited enumerable property names of `object`.
13294 * **Note:** Non-object values are coerced to objects.
13300 * @param {Object} object The object to query.
13301 * @returns {Array} Returns the array of property names.
13309 * Foo.prototype.c = 3;
13311 * _.keysIn(new Foo);
13312 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
13314 function keysIn(object) {
13315 return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
13319 * The opposite of `_.mapValues`; this method creates an object with the
13320 * same values as `object` and keys generated by running each own enumerable
13321 * string keyed property of `object` thru `iteratee`. The iteratee is invoked
13322 * with three arguments: (value, key, object).
13328 * @param {Object} object The object to iterate over.
13329 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13330 * @returns {Object} Returns the new mapped object.
13334 * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
13335 * return key + value;
13337 * // => { 'a1': 1, 'b2': 2 }
13339 function mapKeys(object, iteratee) {
13341 iteratee = getIteratee(iteratee, 3);
13343 baseForOwn(object, function(value, key, object) {
13344 baseAssignValue(result, iteratee(value, key, object), value);
13350 * Creates an object with the same keys as `object` and values generated
13351 * by running each own enumerable string keyed property of `object` thru
13352 * `iteratee`. The iteratee is invoked with three arguments:
13353 * (value, key, object).
13359 * @param {Object} object The object to iterate over.
13360 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13361 * @returns {Object} Returns the new mapped object.
13366 * 'fred': { 'user': 'fred', 'age': 40 },
13367 * 'pebbles': { 'user': 'pebbles', 'age': 1 }
13370 * _.mapValues(users, function(o) { return o.age; });
13371 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13373 * // The `_.property` iteratee shorthand.
13374 * _.mapValues(users, 'age');
13375 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13377 function mapValues(object, iteratee) {
13379 iteratee = getIteratee(iteratee, 3);
13381 baseForOwn(object, function(value, key, object) {
13382 baseAssignValue(result, key, iteratee(value, key, object));
13388 * This method is like `_.assign` except that it recursively merges own and
13389 * inherited enumerable string keyed properties of source objects into the
13390 * destination object. Source properties that resolve to `undefined` are
13391 * skipped if a destination value exists. Array and plain object properties
13392 * are merged recursively. Other objects and value types are overridden by
13393 * assignment. Source objects are applied from left to right. Subsequent
13394 * sources overwrite property assignments of previous sources.
13396 * **Note:** This method mutates `object`.
13402 * @param {Object} object The destination object.
13403 * @param {...Object} [sources] The source objects.
13404 * @returns {Object} Returns `object`.
13408 * 'a': [{ 'b': 2 }, { 'd': 4 }]
13412 * 'a': [{ 'c': 3 }, { 'e': 5 }]
13415 * _.merge(object, other);
13416 * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
13418 var merge = createAssigner(function(object, source, srcIndex) {
13419 baseMerge(object, source, srcIndex);
13423 * This method is like `_.merge` except that it accepts `customizer` which
13424 * is invoked to produce the merged values of the destination and source
13425 * properties. If `customizer` returns `undefined`, merging is handled by the
13426 * method instead. The `customizer` is invoked with six arguments:
13427 * (objValue, srcValue, key, object, source, stack).
13429 * **Note:** This method mutates `object`.
13435 * @param {Object} object The destination object.
13436 * @param {...Object} sources The source objects.
13437 * @param {Function} customizer The function to customize assigned values.
13438 * @returns {Object} Returns `object`.
13441 * function customizer(objValue, srcValue) {
13442 * if (_.isArray(objValue)) {
13443 * return objValue.concat(srcValue);
13447 * var object = { 'a': [1], 'b': [2] };
13448 * var other = { 'a': [3], 'b': [4] };
13450 * _.mergeWith(object, other, customizer);
13451 * // => { 'a': [1, 3], 'b': [2, 4] }
13453 var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
13454 baseMerge(object, source, srcIndex, customizer);
13458 * The opposite of `_.pick`; this method creates an object composed of the
13459 * own and inherited enumerable property paths of `object` that are not omitted.
13461 * **Note:** This method is considerably slower than `_.pick`.
13467 * @param {Object} object The source object.
13468 * @param {...(string|string[])} [paths] The property paths to omit.
13469 * @returns {Object} Returns the new object.
13472 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13474 * _.omit(object, ['a', 'c']);
13475 * // => { 'b': '2' }
13477 var omit = flatRest(function(object, paths) {
13479 if (object == null) {
13482 var isDeep = false;
13483 paths = arrayMap(paths, function(path) {
13484 path = castPath(path, object);
13485 isDeep || (isDeep = path.length > 1);
13488 copyObject(object, getAllKeysIn(object), result);
13490 result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG);
13492 var length = paths.length;
13494 baseUnset(result, paths[length]);
13500 * The opposite of `_.pickBy`; this method creates an object composed of
13501 * the own and inherited enumerable string keyed properties of `object` that
13502 * `predicate` doesn't return truthy for. The predicate is invoked with two
13503 * arguments: (value, key).
13509 * @param {Object} object The source object.
13510 * @param {Function} [predicate=_.identity] The function invoked per property.
13511 * @returns {Object} Returns the new object.
13514 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13516 * _.omitBy(object, _.isNumber);
13517 * // => { 'b': '2' }
13519 function omitBy(object, predicate) {
13520 return pickBy(object, negate(getIteratee(predicate)));
13524 * Creates an object composed of the picked `object` properties.
13530 * @param {Object} object The source object.
13531 * @param {...(string|string[])} [paths] The property paths to pick.
13532 * @returns {Object} Returns the new object.
13535 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13537 * _.pick(object, ['a', 'c']);
13538 * // => { 'a': 1, 'c': 3 }
13540 var pick = flatRest(function(object, paths) {
13541 return object == null ? {} : basePick(object, paths);
13545 * Creates an object composed of the `object` properties `predicate` returns
13546 * truthy for. The predicate is invoked with two arguments: (value, key).
13552 * @param {Object} object The source object.
13553 * @param {Function} [predicate=_.identity] The function invoked per property.
13554 * @returns {Object} Returns the new object.
13557 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13559 * _.pickBy(object, _.isNumber);
13560 * // => { 'a': 1, 'c': 3 }
13562 function pickBy(object, predicate) {
13563 if (object == null) {
13566 var props = arrayMap(getAllKeysIn(object), function(prop) {
13569 predicate = getIteratee(predicate);
13570 return basePickBy(object, props, function(value, path) {
13571 return predicate(value, path[0]);
13576 * This method is like `_.get` except that if the resolved value is a
13577 * function it's invoked with the `this` binding of its parent object and
13578 * its result is returned.
13584 * @param {Object} object The object to query.
13585 * @param {Array|string} path The path of the property to resolve.
13586 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13587 * @returns {*} Returns the resolved value.
13590 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
13592 * _.result(object, 'a[0].b.c1');
13595 * _.result(object, 'a[0].b.c2');
13598 * _.result(object, 'a[0].b.c3', 'default');
13601 * _.result(object, 'a[0].b.c3', _.constant('default'));
13604 function result(object, path, defaultValue) {
13605 path = castPath(path, object);
13608 length = path.length;
13610 // Ensure the loop is entered when path is empty.
13613 object = undefined;
13615 while (++index < length) {
13616 var value = object == null ? undefined : object[toKey(path[index])];
13617 if (value === undefined) {
13619 value = defaultValue;
13621 object = isFunction(value) ? value.call(object) : value;
13627 * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
13628 * it's created. Arrays are created for missing index properties while objects
13629 * are created for all other missing properties. Use `_.setWith` to customize
13632 * **Note:** This method mutates `object`.
13638 * @param {Object} object The object to modify.
13639 * @param {Array|string} path The path of the property to set.
13640 * @param {*} value The value to set.
13641 * @returns {Object} Returns `object`.
13644 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13646 * _.set(object, 'a[0].b.c', 4);
13647 * console.log(object.a[0].b.c);
13650 * _.set(object, ['x', '0', 'y', 'z'], 5);
13651 * console.log(object.x[0].y.z);
13654 function set(object, path, value) {
13655 return object == null ? object : baseSet(object, path, value);
13659 * This method is like `_.set` except that it accepts `customizer` which is
13660 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
13661 * path creation is handled by the method instead. The `customizer` is invoked
13662 * with three arguments: (nsValue, key, nsObject).
13664 * **Note:** This method mutates `object`.
13670 * @param {Object} object The object to modify.
13671 * @param {Array|string} path The path of the property to set.
13672 * @param {*} value The value to set.
13673 * @param {Function} [customizer] The function to customize assigned values.
13674 * @returns {Object} Returns `object`.
13679 * _.setWith(object, '[0][1]', 'a', Object);
13680 * // => { '0': { '1': 'a' } }
13682 function setWith(object, path, value, customizer) {
13683 customizer = typeof customizer == 'function' ? customizer : undefined;
13684 return object == null ? object : baseSet(object, path, value, customizer);
13688 * Creates an array of own enumerable string keyed-value pairs for `object`
13689 * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
13690 * entries are returned.
13697 * @param {Object} object The object to query.
13698 * @returns {Array} Returns the key-value pairs.
13706 * Foo.prototype.c = 3;
13708 * _.toPairs(new Foo);
13709 * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
13711 var toPairs = createToPairs(keys);
13714 * Creates an array of own and inherited enumerable string keyed-value pairs
13715 * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
13716 * or set, its entries are returned.
13723 * @param {Object} object The object to query.
13724 * @returns {Array} Returns the key-value pairs.
13732 * Foo.prototype.c = 3;
13734 * _.toPairsIn(new Foo);
13735 * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
13737 var toPairsIn = createToPairs(keysIn);
13740 * An alternative to `_.reduce`; this method transforms `object` to a new
13741 * `accumulator` object which is the result of running each of its own
13742 * enumerable string keyed properties thru `iteratee`, with each invocation
13743 * potentially mutating the `accumulator` object. If `accumulator` is not
13744 * provided, a new object with the same `[[Prototype]]` will be used. The
13745 * iteratee is invoked with four arguments: (accumulator, value, key, object).
13746 * Iteratee functions may exit iteration early by explicitly returning `false`.
13752 * @param {Object} object The object to iterate over.
13753 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13754 * @param {*} [accumulator] The custom accumulator value.
13755 * @returns {*} Returns the accumulated value.
13758 * _.transform([2, 3, 4], function(result, n) {
13759 * result.push(n *= n);
13760 * return n % 2 == 0;
13764 * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
13765 * (result[value] || (result[value] = [])).push(key);
13767 * // => { '1': ['a', 'c'], '2': ['b'] }
13769 function transform(object, iteratee, accumulator) {
13770 var isArr = isArray(object),
13771 isArrLike = isArr || isBuffer(object) || isTypedArray(object);
13773 iteratee = getIteratee(iteratee, 4);
13774 if (accumulator == null) {
13775 var Ctor = object && object.constructor;
13777 accumulator = isArr ? new Ctor : [];
13779 else if (isObject(object)) {
13780 accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
13786 (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
13787 return iteratee(accumulator, value, index, object);
13789 return accumulator;
13793 * Removes the property at `path` of `object`.
13795 * **Note:** This method mutates `object`.
13801 * @param {Object} object The object to modify.
13802 * @param {Array|string} path The path of the property to unset.
13803 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
13806 * var object = { 'a': [{ 'b': { 'c': 7 } }] };
13807 * _.unset(object, 'a[0].b.c');
13810 * console.log(object);
13811 * // => { 'a': [{ 'b': {} }] };
13813 * _.unset(object, ['a', '0', 'b', 'c']);
13816 * console.log(object);
13817 * // => { 'a': [{ 'b': {} }] };
13819 function unset(object, path) {
13820 return object == null ? true : baseUnset(object, path);
13824 * This method is like `_.set` except that accepts `updater` to produce the
13825 * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13826 * is invoked with one argument: (value).
13828 * **Note:** This method mutates `object`.
13834 * @param {Object} object The object to modify.
13835 * @param {Array|string} path The path of the property to set.
13836 * @param {Function} updater The function to produce the updated value.
13837 * @returns {Object} Returns `object`.
13840 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13842 * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13843 * console.log(object.a[0].b.c);
13846 * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13847 * console.log(object.x[0].y.z);
13850 function update(object, path, updater) {
13851 return object == null ? object : baseUpdate(object, path, castFunction(updater));
13855 * This method is like `_.update` except that it accepts `customizer` which is
13856 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
13857 * path creation is handled by the method instead. The `customizer` is invoked
13858 * with three arguments: (nsValue, key, nsObject).
13860 * **Note:** This method mutates `object`.
13866 * @param {Object} object The object to modify.
13867 * @param {Array|string} path The path of the property to set.
13868 * @param {Function} updater The function to produce the updated value.
13869 * @param {Function} [customizer] The function to customize assigned values.
13870 * @returns {Object} Returns `object`.
13875 * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13876 * // => { '0': { '1': 'a' } }
13878 function updateWith(object, path, updater, customizer) {
13879 customizer = typeof customizer == 'function' ? customizer : undefined;
13880 return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13884 * Creates an array of the own enumerable string keyed property values of `object`.
13886 * **Note:** Non-object values are coerced to objects.
13892 * @param {Object} object The object to query.
13893 * @returns {Array} Returns the array of property values.
13901 * Foo.prototype.c = 3;
13903 * _.values(new Foo);
13904 * // => [1, 2] (iteration order is not guaranteed)
13909 function values(object) {
13910 return object == null ? [] : baseValues(object, keys(object));
13914 * Creates an array of the own and inherited enumerable string keyed property
13915 * values of `object`.
13917 * **Note:** Non-object values are coerced to objects.
13923 * @param {Object} object The object to query.
13924 * @returns {Array} Returns the array of property values.
13932 * Foo.prototype.c = 3;
13934 * _.valuesIn(new Foo);
13935 * // => [1, 2, 3] (iteration order is not guaranteed)
13937 function valuesIn(object) {
13938 return object == null ? [] : baseValues(object, keysIn(object));
13941 /*------------------------------------------------------------------------*/
13944 * Clamps `number` within the inclusive `lower` and `upper` bounds.
13950 * @param {number} number The number to clamp.
13951 * @param {number} [lower] The lower bound.
13952 * @param {number} upper The upper bound.
13953 * @returns {number} Returns the clamped number.
13956 * _.clamp(-10, -5, 5);
13959 * _.clamp(10, -5, 5);
13962 function clamp(number, lower, upper) {
13963 if (upper === undefined) {
13967 if (upper !== undefined) {
13968 upper = toNumber(upper);
13969 upper = upper === upper ? upper : 0;
13971 if (lower !== undefined) {
13972 lower = toNumber(lower);
13973 lower = lower === lower ? lower : 0;
13975 return baseClamp(toNumber(number), lower, upper);
13979 * Checks if `n` is between `start` and up to, but not including, `end`. If
13980 * `end` is not specified, it's set to `start` with `start` then set to `0`.
13981 * If `start` is greater than `end` the params are swapped to support
13988 * @param {number} number The number to check.
13989 * @param {number} [start=0] The start of the range.
13990 * @param {number} end The end of the range.
13991 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
13992 * @see _.range, _.rangeRight
13995 * _.inRange(3, 2, 4);
14007 * _.inRange(1.2, 2);
14010 * _.inRange(5.2, 4);
14013 * _.inRange(-3, -2, -6);
14016 function inRange(number, start, end) {
14017 start = toFinite(start);
14018 if (end === undefined) {
14022 end = toFinite(end);
14024 number = toNumber(number);
14025 return baseInRange(number, start, end);
14029 * Produces a random number between the inclusive `lower` and `upper` bounds.
14030 * If only one argument is provided a number between `0` and the given number
14031 * is returned. If `floating` is `true`, or either `lower` or `upper` are
14032 * floats, a floating-point number is returned instead of an integer.
14034 * **Note:** JavaScript follows the IEEE-754 standard for resolving
14035 * floating-point values which can produce unexpected results.
14041 * @param {number} [lower=0] The lower bound.
14042 * @param {number} [upper=1] The upper bound.
14043 * @param {boolean} [floating] Specify returning a floating-point number.
14044 * @returns {number} Returns the random number.
14048 * // => an integer between 0 and 5
14051 * // => also an integer between 0 and 5
14053 * _.random(5, true);
14054 * // => a floating-point number between 0 and 5
14056 * _.random(1.2, 5.2);
14057 * // => a floating-point number between 1.2 and 5.2
14059 function random(lower, upper, floating) {
14060 if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
14061 upper = floating = undefined;
14063 if (floating === undefined) {
14064 if (typeof upper == 'boolean') {
14068 else if (typeof lower == 'boolean') {
14073 if (lower === undefined && upper === undefined) {
14078 lower = toFinite(lower);
14079 if (upper === undefined) {
14083 upper = toFinite(upper);
14086 if (lower > upper) {
14091 if (floating || lower % 1 || upper % 1) {
14092 var rand = nativeRandom();
14093 return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
14095 return baseRandom(lower, upper);
14098 /*------------------------------------------------------------------------*/
14101 * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
14107 * @param {string} [string=''] The string to convert.
14108 * @returns {string} Returns the camel cased string.
14111 * _.camelCase('Foo Bar');
14114 * _.camelCase('--foo-bar--');
14117 * _.camelCase('__FOO_BAR__');
14120 var camelCase = createCompounder(function(result, word, index) {
14121 word = word.toLowerCase();
14122 return result + (index ? capitalize(word) : word);
14126 * Converts the first character of `string` to upper case and the remaining
14133 * @param {string} [string=''] The string to capitalize.
14134 * @returns {string} Returns the capitalized string.
14137 * _.capitalize('FRED');
14140 function capitalize(string) {
14141 return upperFirst(toString(string).toLowerCase());
14145 * Deburrs `string` by converting
14146 * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
14147 * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
14148 * letters to basic Latin letters and removing
14149 * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
14155 * @param {string} [string=''] The string to deburr.
14156 * @returns {string} Returns the deburred string.
14159 * _.deburr('déjà vu');
14162 function deburr(string) {
14163 string = toString(string);
14164 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
14168 * Checks if `string` ends with the given target string.
14174 * @param {string} [string=''] The string to inspect.
14175 * @param {string} [target] The string to search for.
14176 * @param {number} [position=string.length] The position to search up to.
14177 * @returns {boolean} Returns `true` if `string` ends with `target`,
14181 * _.endsWith('abc', 'c');
14184 * _.endsWith('abc', 'b');
14187 * _.endsWith('abc', 'b', 2);
14190 function endsWith(string, target, position) {
14191 string = toString(string);
14192 target = baseToString(target);
14194 var length = string.length;
14195 position = position === undefined
14197 : baseClamp(toInteger(position), 0, length);
14199 var end = position;
14200 position -= target.length;
14201 return position >= 0 && string.slice(position, end) == target;
14205 * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
14206 * corresponding HTML entities.
14208 * **Note:** No other characters are escaped. To escape additional
14209 * characters use a third-party library like [_he_](https://mths.be/he).
14211 * Though the ">" character is escaped for symmetry, characters like
14212 * ">" and "/" don't need escaping in HTML and have no special meaning
14213 * unless they're part of a tag or unquoted attribute value. See
14214 * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
14215 * (under "semi-related fun fact") for more details.
14217 * When working with HTML you should always
14218 * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
14225 * @param {string} [string=''] The string to escape.
14226 * @returns {string} Returns the escaped string.
14229 * _.escape('fred, barney, & pebbles');
14230 * // => 'fred, barney, & pebbles'
14232 function escape(string) {
14233 string = toString(string);
14234 return (string && reHasUnescapedHtml.test(string))
14235 ? string.replace(reUnescapedHtml, escapeHtmlChar)
14240 * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
14241 * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
14247 * @param {string} [string=''] The string to escape.
14248 * @returns {string} Returns the escaped string.
14251 * _.escapeRegExp('[lodash](https://lodash.com/)');
14252 * // => '\[lodash\]\(https://lodash\.com/\)'
14254 function escapeRegExp(string) {
14255 string = toString(string);
14256 return (string && reHasRegExpChar.test(string))
14257 ? string.replace(reRegExpChar, '\\$&')
14262 * Converts `string` to
14263 * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
14269 * @param {string} [string=''] The string to convert.
14270 * @returns {string} Returns the kebab cased string.
14273 * _.kebabCase('Foo Bar');
14276 * _.kebabCase('fooBar');
14279 * _.kebabCase('__FOO_BAR__');
14282 var kebabCase = createCompounder(function(result, word, index) {
14283 return result + (index ? '-' : '') + word.toLowerCase();
14287 * Converts `string`, as space separated words, to lower case.
14293 * @param {string} [string=''] The string to convert.
14294 * @returns {string} Returns the lower cased string.
14297 * _.lowerCase('--Foo-Bar--');
14300 * _.lowerCase('fooBar');
14303 * _.lowerCase('__FOO_BAR__');
14306 var lowerCase = createCompounder(function(result, word, index) {
14307 return result + (index ? ' ' : '') + word.toLowerCase();
14311 * Converts the first character of `string` to lower case.
14317 * @param {string} [string=''] The string to convert.
14318 * @returns {string} Returns the converted string.
14321 * _.lowerFirst('Fred');
14324 * _.lowerFirst('FRED');
14327 var lowerFirst = createCaseFirst('toLowerCase');
14330 * Pads `string` on the left and right sides if it's shorter than `length`.
14331 * Padding characters are truncated if they can't be evenly divided by `length`.
14337 * @param {string} [string=''] The string to pad.
14338 * @param {number} [length=0] The padding length.
14339 * @param {string} [chars=' '] The string used as padding.
14340 * @returns {string} Returns the padded string.
14346 * _.pad('abc', 8, '_-');
14352 function pad(string, length, chars) {
14353 string = toString(string);
14354 length = toInteger(length);
14356 var strLength = length ? stringSize(string) : 0;
14357 if (!length || strLength >= length) {
14360 var mid = (length - strLength) / 2;
14362 createPadding(nativeFloor(mid), chars) +
14364 createPadding(nativeCeil(mid), chars)
14369 * Pads `string` on the right side if it's shorter than `length`. Padding
14370 * characters are truncated if they exceed `length`.
14376 * @param {string} [string=''] The string to pad.
14377 * @param {number} [length=0] The padding length.
14378 * @param {string} [chars=' '] The string used as padding.
14379 * @returns {string} Returns the padded string.
14382 * _.padEnd('abc', 6);
14385 * _.padEnd('abc', 6, '_-');
14388 * _.padEnd('abc', 3);
14391 function padEnd(string, length, chars) {
14392 string = toString(string);
14393 length = toInteger(length);
14395 var strLength = length ? stringSize(string) : 0;
14396 return (length && strLength < length)
14397 ? (string + createPadding(length - strLength, chars))
14402 * Pads `string` on the left side if it's shorter than `length`. Padding
14403 * characters are truncated if they exceed `length`.
14409 * @param {string} [string=''] The string to pad.
14410 * @param {number} [length=0] The padding length.
14411 * @param {string} [chars=' '] The string used as padding.
14412 * @returns {string} Returns the padded string.
14415 * _.padStart('abc', 6);
14418 * _.padStart('abc', 6, '_-');
14421 * _.padStart('abc', 3);
14424 function padStart(string, length, chars) {
14425 string = toString(string);
14426 length = toInteger(length);
14428 var strLength = length ? stringSize(string) : 0;
14429 return (length && strLength < length)
14430 ? (createPadding(length - strLength, chars) + string)
14435 * Converts `string` to an integer of the specified radix. If `radix` is
14436 * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
14437 * hexadecimal, in which case a `radix` of `16` is used.
14439 * **Note:** This method aligns with the
14440 * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
14446 * @param {string} string The string to convert.
14447 * @param {number} [radix=10] The radix to interpret `value` by.
14448 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14449 * @returns {number} Returns the converted integer.
14452 * _.parseInt('08');
14455 * _.map(['6', '08', '10'], _.parseInt);
14458 function parseInt(string, radix, guard) {
14459 if (guard || radix == null) {
14461 } else if (radix) {
14464 return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
14468 * Repeats the given string `n` times.
14474 * @param {string} [string=''] The string to repeat.
14475 * @param {number} [n=1] The number of times to repeat the string.
14476 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14477 * @returns {string} Returns the repeated string.
14480 * _.repeat('*', 3);
14483 * _.repeat('abc', 2);
14486 * _.repeat('abc', 0);
14489 function repeat(string, n, guard) {
14490 if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
14495 return baseRepeat(toString(string), n);
14499 * Replaces matches for `pattern` in `string` with `replacement`.
14501 * **Note:** This method is based on
14502 * [`String#replace`](https://mdn.io/String/replace).
14508 * @param {string} [string=''] The string to modify.
14509 * @param {RegExp|string} pattern The pattern to replace.
14510 * @param {Function|string} replacement The match replacement.
14511 * @returns {string} Returns the modified string.
14514 * _.replace('Hi Fred', 'Fred', 'Barney');
14515 * // => 'Hi Barney'
14517 function replace() {
14518 var args = arguments,
14519 string = toString(args[0]);
14521 return args.length < 3 ? string : string.replace(args[1], args[2]);
14525 * Converts `string` to
14526 * [snake case](https://en.wikipedia.org/wiki/Snake_case).
14532 * @param {string} [string=''] The string to convert.
14533 * @returns {string} Returns the snake cased string.
14536 * _.snakeCase('Foo Bar');
14539 * _.snakeCase('fooBar');
14542 * _.snakeCase('--FOO-BAR--');
14545 var snakeCase = createCompounder(function(result, word, index) {
14546 return result + (index ? '_' : '') + word.toLowerCase();
14550 * Splits `string` by `separator`.
14552 * **Note:** This method is based on
14553 * [`String#split`](https://mdn.io/String/split).
14559 * @param {string} [string=''] The string to split.
14560 * @param {RegExp|string} separator The separator pattern to split by.
14561 * @param {number} [limit] The length to truncate results to.
14562 * @returns {Array} Returns the string segments.
14565 * _.split('a-b-c', '-', 2);
14568 function split(string, separator, limit) {
14569 if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
14570 separator = limit = undefined;
14572 limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
14576 string = toString(string);
14578 typeof separator == 'string' ||
14579 (separator != null && !isRegExp(separator))
14581 separator = baseToString(separator);
14582 if (!separator && hasUnicode(string)) {
14583 return castSlice(stringToArray(string), 0, limit);
14586 return string.split(separator, limit);
14590 * Converts `string` to
14591 * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
14597 * @param {string} [string=''] The string to convert.
14598 * @returns {string} Returns the start cased string.
14601 * _.startCase('--foo-bar--');
14604 * _.startCase('fooBar');
14607 * _.startCase('__FOO_BAR__');
14610 var startCase = createCompounder(function(result, word, index) {
14611 return result + (index ? ' ' : '') + upperFirst(word);
14615 * Checks if `string` starts with the given target string.
14621 * @param {string} [string=''] The string to inspect.
14622 * @param {string} [target] The string to search for.
14623 * @param {number} [position=0] The position to search from.
14624 * @returns {boolean} Returns `true` if `string` starts with `target`,
14628 * _.startsWith('abc', 'a');
14631 * _.startsWith('abc', 'b');
14634 * _.startsWith('abc', 'b', 1);
14637 function startsWith(string, target, position) {
14638 string = toString(string);
14639 position = baseClamp(toInteger(position), 0, string.length);
14640 target = baseToString(target);
14641 return string.slice(position, position + target.length) == target;
14645 * Creates a compiled template function that can interpolate data properties
14646 * in "interpolate" delimiters, HTML-escape interpolated data properties in
14647 * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
14648 * properties may be accessed as free variables in the template. If a setting
14649 * object is given, it takes precedence over `_.templateSettings` values.
14651 * **Note:** In the development build `_.template` utilizes
14652 * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
14653 * for easier debugging.
14655 * For more information on precompiling templates see
14656 * [lodash's custom builds documentation](https://lodash.com/custom-builds).
14658 * For more information on Chrome extension sandboxes see
14659 * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
14665 * @param {string} [string=''] The template string.
14666 * @param {Object} [options={}] The options object.
14667 * @param {RegExp} [options.escape=_.templateSettings.escape]
14668 * The HTML "escape" delimiter.
14669 * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
14670 * The "evaluate" delimiter.
14671 * @param {Object} [options.imports=_.templateSettings.imports]
14672 * An object to import into the template as free variables.
14673 * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
14674 * The "interpolate" delimiter.
14675 * @param {string} [options.sourceURL='lodash.templateSources[n]']
14676 * The sourceURL of the compiled template.
14677 * @param {string} [options.variable='obj']
14678 * The data object variable name.
14679 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14680 * @returns {Function} Returns the compiled template function.
14683 * // Use the "interpolate" delimiter to create a compiled template.
14684 * var compiled = _.template('hello <%= user %>!');
14685 * compiled({ 'user': 'fred' });
14686 * // => 'hello fred!'
14688 * // Use the HTML "escape" delimiter to escape data property values.
14689 * var compiled = _.template('<b><%- value %></b>');
14690 * compiled({ 'value': '<script>' });
14691 * // => '<b><script></b>'
14693 * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
14694 * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
14695 * compiled({ 'users': ['fred', 'barney'] });
14696 * // => '<li>fred</li><li>barney</li>'
14698 * // Use the internal `print` function in "evaluate" delimiters.
14699 * var compiled = _.template('<% print("hello " + user); %>!');
14700 * compiled({ 'user': 'barney' });
14701 * // => 'hello barney!'
14703 * // Use the ES template literal delimiter as an "interpolate" delimiter.
14704 * // Disable support by replacing the "interpolate" delimiter.
14705 * var compiled = _.template('hello ${ user }!');
14706 * compiled({ 'user': 'pebbles' });
14707 * // => 'hello pebbles!'
14709 * // Use backslashes to treat delimiters as plain text.
14710 * var compiled = _.template('<%= "\\<%- value %\\>" %>');
14711 * compiled({ 'value': 'ignored' });
14712 * // => '<%- value %>'
14714 * // Use the `imports` option to import `jQuery` as `jq`.
14715 * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
14716 * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
14717 * compiled({ 'users': ['fred', 'barney'] });
14718 * // => '<li>fred</li><li>barney</li>'
14720 * // Use the `sourceURL` option to specify a custom sourceURL for the template.
14721 * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
14723 * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
14725 * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
14726 * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
14728 * // => function(data) {
14729 * // var __t, __p = '';
14730 * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
14734 * // Use custom template delimiters.
14735 * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
14736 * var compiled = _.template('hello {{ user }}!');
14737 * compiled({ 'user': 'mustache' });
14738 * // => 'hello mustache!'
14740 * // Use the `source` property to inline compiled templates for meaningful
14741 * // line numbers in error messages and stack traces.
14742 * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
14744 * "main": ' + _.template(mainText).source + '\
14748 function template(string, options, guard) {
14749 // Based on John Resig's `tmpl` implementation
14750 // (http://ejohn.org/blog/javascript-micro-templating/)
14751 // and Laura Doktorova's doT.js (https://github.com/olado/doT).
14752 var settings = lodash.templateSettings;
14754 if (guard && isIterateeCall(string, options, guard)) {
14755 options = undefined;
14757 string = toString(string);
14758 options = assignInWith({}, options, settings, assignInDefaults);
14760 var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
14761 importsKeys = keys(imports),
14762 importsValues = baseValues(imports, importsKeys);
14767 interpolate = options.interpolate || reNoMatch,
14768 source = "__p += '";
14770 // Compile the regexp to match each delimiter.
14771 var reDelimiters = RegExp(
14772 (options.escape || reNoMatch).source + '|' +
14773 interpolate.source + '|' +
14774 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
14775 (options.evaluate || reNoMatch).source + '|$'
14778 // Use a sourceURL for easier debugging.
14779 var sourceURL = '//# sourceURL=' +
14780 ('sourceURL' in options
14781 ? options.sourceURL
14782 : ('lodash.templateSources[' + (++templateCounter) + ']')
14785 string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
14786 interpolateValue || (interpolateValue = esTemplateValue);
14788 // Escape characters that can't be included in string literals.
14789 source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
14791 // Replace delimiters with snippets.
14794 source += "' +\n__e(" + escapeValue + ") +\n'";
14796 if (evaluateValue) {
14797 isEvaluating = true;
14798 source += "';\n" + evaluateValue + ";\n__p += '";
14800 if (interpolateValue) {
14801 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
14803 index = offset + match.length;
14805 // The JS engine embedded in Adobe products needs `match` returned in
14806 // order to produce the correct `offset` value.
14812 // If `variable` is not specified wrap a with-statement around the generated
14813 // code to add the data object to the top of the scope chain.
14814 var variable = options.variable;
14816 source = 'with (obj) {\n' + source + '\n}\n';
14818 // Cleanup code by stripping empty strings.
14819 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14820 .replace(reEmptyStringMiddle, '$1')
14821 .replace(reEmptyStringTrailing, '$1;');
14823 // Frame code as the function body.
14824 source = 'function(' + (variable || 'obj') + ') {\n' +
14827 : 'obj || (obj = {});\n'
14829 "var __t, __p = ''" +
14831 ? ', __e = _.escape'
14835 ? ', __j = Array.prototype.join;\n' +
14836 "function print() { __p += __j.call(arguments, '') }\n"
14842 var result = attempt(function() {
14843 return Function(importsKeys, sourceURL + 'return ' + source)
14844 .apply(undefined, importsValues);
14847 // Provide the compiled function's source by its `toString` method or
14848 // the `source` property as a convenience for inlining compiled templates.
14849 result.source = source;
14850 if (isError(result)) {
14857 * Converts `string`, as a whole, to lower case just like
14858 * [String#toLowerCase](https://mdn.io/toLowerCase).
14864 * @param {string} [string=''] The string to convert.
14865 * @returns {string} Returns the lower cased string.
14868 * _.toLower('--Foo-Bar--');
14869 * // => '--foo-bar--'
14871 * _.toLower('fooBar');
14874 * _.toLower('__FOO_BAR__');
14875 * // => '__foo_bar__'
14877 function toLower(value) {
14878 return toString(value).toLowerCase();
14882 * Converts `string`, as a whole, to upper case just like
14883 * [String#toUpperCase](https://mdn.io/toUpperCase).
14889 * @param {string} [string=''] The string to convert.
14890 * @returns {string} Returns the upper cased string.
14893 * _.toUpper('--foo-bar--');
14894 * // => '--FOO-BAR--'
14896 * _.toUpper('fooBar');
14899 * _.toUpper('__foo_bar__');
14900 * // => '__FOO_BAR__'
14902 function toUpper(value) {
14903 return toString(value).toUpperCase();
14907 * Removes leading and trailing whitespace or specified characters from `string`.
14913 * @param {string} [string=''] The string to trim.
14914 * @param {string} [chars=whitespace] The characters to trim.
14915 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14916 * @returns {string} Returns the trimmed string.
14922 * _.trim('-_-abc-_-', '_-');
14925 * _.map([' foo ', ' bar '], _.trim);
14926 * // => ['foo', 'bar']
14928 function trim(string, chars, guard) {
14929 string = toString(string);
14930 if (string && (guard || chars === undefined)) {
14931 return string.replace(reTrim, '');
14933 if (!string || !(chars = baseToString(chars))) {
14936 var strSymbols = stringToArray(string),
14937 chrSymbols = stringToArray(chars),
14938 start = charsStartIndex(strSymbols, chrSymbols),
14939 end = charsEndIndex(strSymbols, chrSymbols) + 1;
14941 return castSlice(strSymbols, start, end).join('');
14945 * Removes trailing whitespace or specified characters from `string`.
14951 * @param {string} [string=''] The string to trim.
14952 * @param {string} [chars=whitespace] The characters to trim.
14953 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14954 * @returns {string} Returns the trimmed string.
14957 * _.trimEnd(' abc ');
14960 * _.trimEnd('-_-abc-_-', '_-');
14963 function trimEnd(string, chars, guard) {
14964 string = toString(string);
14965 if (string && (guard || chars === undefined)) {
14966 return string.replace(reTrimEnd, '');
14968 if (!string || !(chars = baseToString(chars))) {
14971 var strSymbols = stringToArray(string),
14972 end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
14974 return castSlice(strSymbols, 0, end).join('');
14978 * Removes leading whitespace or specified characters from `string`.
14984 * @param {string} [string=''] The string to trim.
14985 * @param {string} [chars=whitespace] The characters to trim.
14986 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14987 * @returns {string} Returns the trimmed string.
14990 * _.trimStart(' abc ');
14993 * _.trimStart('-_-abc-_-', '_-');
14996 function trimStart(string, chars, guard) {
14997 string = toString(string);
14998 if (string && (guard || chars === undefined)) {
14999 return string.replace(reTrimStart, '');
15001 if (!string || !(chars = baseToString(chars))) {
15004 var strSymbols = stringToArray(string),
15005 start = charsStartIndex(strSymbols, stringToArray(chars));
15007 return castSlice(strSymbols, start).join('');
15011 * Truncates `string` if it's longer than the given maximum string length.
15012 * The last characters of the truncated string are replaced with the omission
15013 * string which defaults to "...".
15019 * @param {string} [string=''] The string to truncate.
15020 * @param {Object} [options={}] The options object.
15021 * @param {number} [options.length=30] The maximum string length.
15022 * @param {string} [options.omission='...'] The string to indicate text is omitted.
15023 * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
15024 * @returns {string} Returns the truncated string.
15027 * _.truncate('hi-diddly-ho there, neighborino');
15028 * // => 'hi-diddly-ho there, neighbo...'
15030 * _.truncate('hi-diddly-ho there, neighborino', {
15034 * // => 'hi-diddly-ho there,...'
15036 * _.truncate('hi-diddly-ho there, neighborino', {
15038 * 'separator': /,? +/
15040 * // => 'hi-diddly-ho there...'
15042 * _.truncate('hi-diddly-ho there, neighborino', {
15043 * 'omission': ' [...]'
15045 * // => 'hi-diddly-ho there, neig [...]'
15047 function truncate(string, options) {
15048 var length = DEFAULT_TRUNC_LENGTH,
15049 omission = DEFAULT_TRUNC_OMISSION;
15051 if (isObject(options)) {
15052 var separator = 'separator' in options ? options.separator : separator;
15053 length = 'length' in options ? toInteger(options.length) : length;
15054 omission = 'omission' in options ? baseToString(options.omission) : omission;
15056 string = toString(string);
15058 var strLength = string.length;
15059 if (hasUnicode(string)) {
15060 var strSymbols = stringToArray(string);
15061 strLength = strSymbols.length;
15063 if (length >= strLength) {
15066 var end = length - stringSize(omission);
15070 var result = strSymbols
15071 ? castSlice(strSymbols, 0, end).join('')
15072 : string.slice(0, end);
15074 if (separator === undefined) {
15075 return result + omission;
15078 end += (result.length - end);
15080 if (isRegExp(separator)) {
15081 if (string.slice(end).search(separator)) {
15083 substring = result;
15085 if (!separator.global) {
15086 separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
15088 separator.lastIndex = 0;
15089 while ((match = separator.exec(substring))) {
15090 var newEnd = match.index;
15092 result = result.slice(0, newEnd === undefined ? end : newEnd);
15094 } else if (string.indexOf(baseToString(separator), end) != end) {
15095 var index = result.lastIndexOf(separator);
15097 result = result.slice(0, index);
15100 return result + omission;
15104 * The inverse of `_.escape`; this method converts the HTML entities
15105 * `&`, `<`, `>`, `"`, and `'` in `string` to
15106 * their corresponding characters.
15108 * **Note:** No other HTML entities are unescaped. To unescape additional
15109 * HTML entities use a third-party library like [_he_](https://mths.be/he).
15115 * @param {string} [string=''] The string to unescape.
15116 * @returns {string} Returns the unescaped string.
15119 * _.unescape('fred, barney, & pebbles');
15120 * // => 'fred, barney, & pebbles'
15122 function unescape(string) {
15123 string = toString(string);
15124 return (string && reHasEscapedHtml.test(string))
15125 ? string.replace(reEscapedHtml, unescapeHtmlChar)
15130 * Converts `string`, as space separated words, to upper case.
15136 * @param {string} [string=''] The string to convert.
15137 * @returns {string} Returns the upper cased string.
15140 * _.upperCase('--foo-bar');
15143 * _.upperCase('fooBar');
15146 * _.upperCase('__foo_bar__');
15149 var upperCase = createCompounder(function(result, word, index) {
15150 return result + (index ? ' ' : '') + word.toUpperCase();
15154 * Converts the first character of `string` to upper case.
15160 * @param {string} [string=''] The string to convert.
15161 * @returns {string} Returns the converted string.
15164 * _.upperFirst('fred');
15167 * _.upperFirst('FRED');
15170 var upperFirst = createCaseFirst('toUpperCase');
15173 * Splits `string` into an array of its words.
15179 * @param {string} [string=''] The string to inspect.
15180 * @param {RegExp|string} [pattern] The pattern to match words.
15181 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15182 * @returns {Array} Returns the words of `string`.
15185 * _.words('fred, barney, & pebbles');
15186 * // => ['fred', 'barney', 'pebbles']
15188 * _.words('fred, barney, & pebbles', /[^, ]+/g);
15189 * // => ['fred', 'barney', '&', 'pebbles']
15191 function words(string, pattern, guard) {
15192 string = toString(string);
15193 pattern = guard ? undefined : pattern;
15195 if (pattern === undefined) {
15196 return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
15198 return string.match(pattern) || [];
15201 /*------------------------------------------------------------------------*/
15204 * Attempts to invoke `func`, returning either the result or the caught error
15205 * object. Any additional arguments are provided to `func` when it's invoked.
15211 * @param {Function} func The function to attempt.
15212 * @param {...*} [args] The arguments to invoke `func` with.
15213 * @returns {*} Returns the `func` result or error object.
15216 * // Avoid throwing errors for invalid selectors.
15217 * var elements = _.attempt(function(selector) {
15218 * return document.querySelectorAll(selector);
15221 * if (_.isError(elements)) {
15225 var attempt = baseRest(function(func, args) {
15227 return apply(func, undefined, args);
15229 return isError(e) ? e : new Error(e);
15234 * Binds methods of an object to the object itself, overwriting the existing
15237 * **Note:** This method doesn't set the "length" property of bound functions.
15243 * @param {Object} object The object to bind and assign the bound methods to.
15244 * @param {...(string|string[])} methodNames The object method names to bind.
15245 * @returns {Object} Returns `object`.
15250 * 'click': function() {
15251 * console.log('clicked ' + this.label);
15255 * _.bindAll(view, ['click']);
15256 * jQuery(element).on('click', view.click);
15257 * // => Logs 'clicked docs' when clicked.
15259 var bindAll = flatRest(function(object, methodNames) {
15260 arrayEach(methodNames, function(key) {
15262 baseAssignValue(object, key, bind(object[key], object));
15268 * Creates a function that iterates over `pairs` and invokes the corresponding
15269 * function of the first predicate to return truthy. The predicate-function
15270 * pairs are invoked with the `this` binding and arguments of the created
15277 * @param {Array} pairs The predicate-function pairs.
15278 * @returns {Function} Returns the new composite function.
15281 * var func = _.cond([
15282 * [_.matches({ 'a': 1 }), _.constant('matches A')],
15283 * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
15284 * [_.stubTrue, _.constant('no match')]
15287 * func({ 'a': 1, 'b': 2 });
15288 * // => 'matches A'
15290 * func({ 'a': 0, 'b': 1 });
15291 * // => 'matches B'
15293 * func({ 'a': '1', 'b': '2' });
15296 function cond(pairs) {
15297 var length = pairs == null ? 0 : pairs.length,
15298 toIteratee = getIteratee();
15300 pairs = !length ? [] : arrayMap(pairs, function(pair) {
15301 if (typeof pair[1] != 'function') {
15302 throw new TypeError(FUNC_ERROR_TEXT);
15304 return [toIteratee(pair[0]), pair[1]];
15307 return baseRest(function(args) {
15309 while (++index < length) {
15310 var pair = pairs[index];
15311 if (apply(pair[0], this, args)) {
15312 return apply(pair[1], this, args);
15319 * Creates a function that invokes the predicate properties of `source` with
15320 * the corresponding property values of a given object, returning `true` if
15321 * all predicates return truthy, else `false`.
15323 * **Note:** The created function is equivalent to `_.conformsTo` with
15324 * `source` partially applied.
15330 * @param {Object} source The object of property predicates to conform to.
15331 * @returns {Function} Returns the new spec function.
15335 * { 'a': 2, 'b': 1 },
15336 * { 'a': 1, 'b': 2 }
15339 * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
15340 * // => [{ 'a': 1, 'b': 2 }]
15342 function conforms(source) {
15343 return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
15347 * Creates a function that returns `value`.
15353 * @param {*} value The value to return from the new function.
15354 * @returns {Function} Returns the new constant function.
15357 * var objects = _.times(2, _.constant({ 'a': 1 }));
15359 * console.log(objects);
15360 * // => [{ 'a': 1 }, { 'a': 1 }]
15362 * console.log(objects[0] === objects[1]);
15365 function constant(value) {
15366 return function() {
15372 * Checks `value` to determine whether a default value should be returned in
15373 * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
15380 * @param {*} value The value to check.
15381 * @param {*} defaultValue The default value.
15382 * @returns {*} Returns the resolved value.
15385 * _.defaultTo(1, 10);
15388 * _.defaultTo(undefined, 10);
15391 function defaultTo(value, defaultValue) {
15392 return (value == null || value !== value) ? defaultValue : value;
15396 * Creates a function that returns the result of invoking the given functions
15397 * with the `this` binding of the created function, where each successive
15398 * invocation is supplied the return value of the previous.
15404 * @param {...(Function|Function[])} [funcs] The functions to invoke.
15405 * @returns {Function} Returns the new composite function.
15409 * function square(n) {
15413 * var addSquare = _.flow([_.add, square]);
15417 var flow = createFlow();
15420 * This method is like `_.flow` except that it creates a function that
15421 * invokes the given functions from right to left.
15427 * @param {...(Function|Function[])} [funcs] The functions to invoke.
15428 * @returns {Function} Returns the new composite function.
15432 * function square(n) {
15436 * var addSquare = _.flowRight([square, _.add]);
15440 var flowRight = createFlow(true);
15443 * This method returns the first argument it receives.
15449 * @param {*} value Any value.
15450 * @returns {*} Returns `value`.
15453 * var object = { 'a': 1 };
15455 * console.log(_.identity(object) === object);
15458 function identity(value) {
15463 * Creates a function that invokes `func` with the arguments of the created
15464 * function. If `func` is a property name, the created function returns the
15465 * property value for a given element. If `func` is an array or object, the
15466 * created function returns `true` for elements that contain the equivalent
15467 * source properties, otherwise it returns `false`.
15473 * @param {*} [func=_.identity] The value to convert to a callback.
15474 * @returns {Function} Returns the callback.
15478 * { 'user': 'barney', 'age': 36, 'active': true },
15479 * { 'user': 'fred', 'age': 40, 'active': false }
15482 * // The `_.matches` iteratee shorthand.
15483 * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
15484 * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
15486 * // The `_.matchesProperty` iteratee shorthand.
15487 * _.filter(users, _.iteratee(['user', 'fred']));
15488 * // => [{ 'user': 'fred', 'age': 40 }]
15490 * // The `_.property` iteratee shorthand.
15491 * _.map(users, _.iteratee('user'));
15492 * // => ['barney', 'fred']
15494 * // Create custom iteratee shorthands.
15495 * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
15496 * return !_.isRegExp(func) ? iteratee(func) : function(string) {
15497 * return func.test(string);
15501 * _.filter(['abc', 'def'], /ef/);
15504 function iteratee(func) {
15505 return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
15509 * Creates a function that performs a partial deep comparison between a given
15510 * object and `source`, returning `true` if the given object has equivalent
15511 * property values, else `false`.
15513 * **Note:** The created function is equivalent to `_.isMatch` with `source`
15514 * partially applied.
15516 * Partial comparisons will match empty array and empty object `source`
15517 * values against any array or object value, respectively. See `_.isEqual`
15518 * for a list of supported value comparisons.
15524 * @param {Object} source The object of property values to match.
15525 * @returns {Function} Returns the new spec function.
15529 * { 'a': 1, 'b': 2, 'c': 3 },
15530 * { 'a': 4, 'b': 5, 'c': 6 }
15533 * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
15534 * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
15536 function matches(source) {
15537 return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
15541 * Creates a function that performs a partial deep comparison between the
15542 * value at `path` of a given object to `srcValue`, returning `true` if the
15543 * object value is equivalent, else `false`.
15545 * **Note:** Partial comparisons will match empty array and empty object
15546 * `srcValue` values against any array or object value, respectively. See
15547 * `_.isEqual` for a list of supported value comparisons.
15553 * @param {Array|string} path The path of the property to get.
15554 * @param {*} srcValue The value to match.
15555 * @returns {Function} Returns the new spec function.
15559 * { 'a': 1, 'b': 2, 'c': 3 },
15560 * { 'a': 4, 'b': 5, 'c': 6 }
15563 * _.find(objects, _.matchesProperty('a', 4));
15564 * // => { 'a': 4, 'b': 5, 'c': 6 }
15566 function matchesProperty(path, srcValue) {
15567 return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
15571 * Creates a function that invokes the method at `path` of a given object.
15572 * Any additional arguments are provided to the invoked method.
15578 * @param {Array|string} path The path of the method to invoke.
15579 * @param {...*} [args] The arguments to invoke the method with.
15580 * @returns {Function} Returns the new invoker function.
15584 * { 'a': { 'b': _.constant(2) } },
15585 * { 'a': { 'b': _.constant(1) } }
15588 * _.map(objects, _.method('a.b'));
15591 * _.map(objects, _.method(['a', 'b']));
15594 var method = baseRest(function(path, args) {
15595 return function(object) {
15596 return baseInvoke(object, path, args);
15601 * The opposite of `_.method`; this method creates a function that invokes
15602 * the method at a given path of `object`. Any additional arguments are
15603 * provided to the invoked method.
15609 * @param {Object} object The object to query.
15610 * @param {...*} [args] The arguments to invoke the method with.
15611 * @returns {Function} Returns the new invoker function.
15614 * var array = _.times(3, _.constant),
15615 * object = { 'a': array, 'b': array, 'c': array };
15617 * _.map(['a[2]', 'c[0]'], _.methodOf(object));
15620 * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
15623 var methodOf = baseRest(function(object, args) {
15624 return function(path) {
15625 return baseInvoke(object, path, args);
15630 * Adds all own enumerable string keyed function properties of a source
15631 * object to the destination object. If `object` is a function, then methods
15632 * are added to its prototype as well.
15634 * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
15635 * avoid conflicts caused by modifying the original.
15641 * @param {Function|Object} [object=lodash] The destination object.
15642 * @param {Object} source The object of functions to add.
15643 * @param {Object} [options={}] The options object.
15644 * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
15645 * @returns {Function|Object} Returns `object`.
15648 * function vowels(string) {
15649 * return _.filter(string, function(v) {
15650 * return /[aeiou]/i.test(v);
15654 * _.mixin({ 'vowels': vowels });
15655 * _.vowels('fred');
15658 * _('fred').vowels().value();
15661 * _.mixin({ 'vowels': vowels }, { 'chain': false });
15662 * _('fred').vowels();
15665 function mixin(object, source, options) {
15666 var props = keys(source),
15667 methodNames = baseFunctions(source, props);
15669 if (options == null &&
15670 !(isObject(source) && (methodNames.length || !props.length))) {
15674 methodNames = baseFunctions(source, keys(source));
15676 var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
15677 isFunc = isFunction(object);
15679 arrayEach(methodNames, function(methodName) {
15680 var func = source[methodName];
15681 object[methodName] = func;
15683 object.prototype[methodName] = function() {
15684 var chainAll = this.__chain__;
15685 if (chain || chainAll) {
15686 var result = object(this.__wrapped__),
15687 actions = result.__actions__ = copyArray(this.__actions__);
15689 actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
15690 result.__chain__ = chainAll;
15693 return func.apply(object, arrayPush([this.value()], arguments));
15702 * Reverts the `_` variable to its previous value and returns a reference to
15703 * the `lodash` function.
15709 * @returns {Function} Returns the `lodash` function.
15712 * var lodash = _.noConflict();
15714 function noConflict() {
15715 if (root._ === this) {
15722 * This method returns `undefined`.
15730 * _.times(2, _.noop);
15731 * // => [undefined, undefined]
15734 // No operation performed.
15738 * Creates a function that gets the argument at index `n`. If `n` is negative,
15739 * the nth argument from the end is returned.
15745 * @param {number} [n=0] The index of the argument to return.
15746 * @returns {Function} Returns the new pass-thru function.
15749 * var func = _.nthArg(1);
15750 * func('a', 'b', 'c', 'd');
15753 * var func = _.nthArg(-2);
15754 * func('a', 'b', 'c', 'd');
15757 function nthArg(n) {
15759 return baseRest(function(args) {
15760 return baseNth(args, n);
15765 * Creates a function that invokes `iteratees` with the arguments it receives
15766 * and returns their results.
15772 * @param {...(Function|Function[])} [iteratees=[_.identity]]
15773 * The iteratees to invoke.
15774 * @returns {Function} Returns the new function.
15777 * var func = _.over([Math.max, Math.min]);
15779 * func(1, 2, 3, 4);
15782 var over = createOver(arrayMap);
15785 * Creates a function that checks if **all** of the `predicates` return
15786 * truthy when invoked with the arguments it receives.
15792 * @param {...(Function|Function[])} [predicates=[_.identity]]
15793 * The predicates to check.
15794 * @returns {Function} Returns the new function.
15797 * var func = _.overEvery([Boolean, isFinite]);
15808 var overEvery = createOver(arrayEvery);
15811 * Creates a function that checks if **any** of the `predicates` return
15812 * truthy when invoked with the arguments it receives.
15818 * @param {...(Function|Function[])} [predicates=[_.identity]]
15819 * The predicates to check.
15820 * @returns {Function} Returns the new function.
15823 * var func = _.overSome([Boolean, isFinite]);
15834 var overSome = createOver(arraySome);
15837 * Creates a function that returns the value at `path` of a given object.
15843 * @param {Array|string} path The path of the property to get.
15844 * @returns {Function} Returns the new accessor function.
15848 * { 'a': { 'b': 2 } },
15849 * { 'a': { 'b': 1 } }
15852 * _.map(objects, _.property('a.b'));
15855 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15858 function property(path) {
15859 return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15863 * The opposite of `_.property`; this method creates a function that returns
15864 * the value at a given path of `object`.
15870 * @param {Object} object The object to query.
15871 * @returns {Function} Returns the new accessor function.
15874 * var array = [0, 1, 2],
15875 * object = { 'a': array, 'b': array, 'c': array };
15877 * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
15880 * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
15883 function propertyOf(object) {
15884 return function(path) {
15885 return object == null ? undefined : baseGet(object, path);
15890 * Creates an array of numbers (positive and/or negative) progressing from
15891 * `start` up to, but not including, `end`. A step of `-1` is used if a negative
15892 * `start` is specified without an `end` or `step`. If `end` is not specified,
15893 * it's set to `start` with `start` then set to `0`.
15895 * **Note:** JavaScript follows the IEEE-754 standard for resolving
15896 * floating-point values which can produce unexpected results.
15902 * @param {number} [start=0] The start of the range.
15903 * @param {number} end The end of the range.
15904 * @param {number} [step=1] The value to increment or decrement by.
15905 * @returns {Array} Returns the range of numbers.
15906 * @see _.inRange, _.rangeRight
15910 * // => [0, 1, 2, 3]
15913 * // => [0, -1, -2, -3]
15916 * // => [1, 2, 3, 4]
15918 * _.range(0, 20, 5);
15919 * // => [0, 5, 10, 15]
15921 * _.range(0, -4, -1);
15922 * // => [0, -1, -2, -3]
15924 * _.range(1, 4, 0);
15930 var range = createRange();
15933 * This method is like `_.range` except that it populates values in
15934 * descending order.
15940 * @param {number} [start=0] The start of the range.
15941 * @param {number} end The end of the range.
15942 * @param {number} [step=1] The value to increment or decrement by.
15943 * @returns {Array} Returns the range of numbers.
15944 * @see _.inRange, _.range
15948 * // => [3, 2, 1, 0]
15950 * _.rangeRight(-4);
15951 * // => [-3, -2, -1, 0]
15953 * _.rangeRight(1, 5);
15954 * // => [4, 3, 2, 1]
15956 * _.rangeRight(0, 20, 5);
15957 * // => [15, 10, 5, 0]
15959 * _.rangeRight(0, -4, -1);
15960 * // => [-3, -2, -1, 0]
15962 * _.rangeRight(1, 4, 0);
15968 var rangeRight = createRange(true);
15971 * This method returns a new empty array.
15977 * @returns {Array} Returns the new empty array.
15980 * var arrays = _.times(2, _.stubArray);
15982 * console.log(arrays);
15985 * console.log(arrays[0] === arrays[1]);
15988 function stubArray() {
15993 * This method returns `false`.
15999 * @returns {boolean} Returns `false`.
16002 * _.times(2, _.stubFalse);
16003 * // => [false, false]
16005 function stubFalse() {
16010 * This method returns a new empty object.
16016 * @returns {Object} Returns the new empty object.
16019 * var objects = _.times(2, _.stubObject);
16021 * console.log(objects);
16024 * console.log(objects[0] === objects[1]);
16027 function stubObject() {
16032 * This method returns an empty string.
16038 * @returns {string} Returns the empty string.
16041 * _.times(2, _.stubString);
16044 function stubString() {
16049 * This method returns `true`.
16055 * @returns {boolean} Returns `true`.
16058 * _.times(2, _.stubTrue);
16059 * // => [true, true]
16061 function stubTrue() {
16066 * Invokes the iteratee `n` times, returning an array of the results of
16067 * each invocation. The iteratee is invoked with one argument; (index).
16073 * @param {number} n The number of times to invoke `iteratee`.
16074 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
16075 * @returns {Array} Returns the array of results.
16078 * _.times(3, String);
16079 * // => ['0', '1', '2']
16081 * _.times(4, _.constant(0));
16082 * // => [0, 0, 0, 0]
16084 function times(n, iteratee) {
16086 if (n < 1 || n > MAX_SAFE_INTEGER) {
16089 var index = MAX_ARRAY_LENGTH,
16090 length = nativeMin(n, MAX_ARRAY_LENGTH);
16092 iteratee = getIteratee(iteratee);
16093 n -= MAX_ARRAY_LENGTH;
16095 var result = baseTimes(length, iteratee);
16096 while (++index < n) {
16103 * Converts `value` to a property path array.
16109 * @param {*} value The value to convert.
16110 * @returns {Array} Returns the new property path array.
16113 * _.toPath('a.b.c');
16114 * // => ['a', 'b', 'c']
16116 * _.toPath('a[0].b.c');
16117 * // => ['a', '0', 'b', 'c']
16119 function toPath(value) {
16120 if (isArray(value)) {
16121 return arrayMap(value, toKey);
16123 return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
16127 * Generates a unique ID. If `prefix` is given, the ID is appended to it.
16133 * @param {string} [prefix=''] The value to prefix the ID with.
16134 * @returns {string} Returns the unique ID.
16137 * _.uniqueId('contact_');
16138 * // => 'contact_104'
16143 function uniqueId(prefix) {
16144 var id = ++idCounter;
16145 return toString(prefix) + id;
16148 /*------------------------------------------------------------------------*/
16151 * Adds two numbers.
16157 * @param {number} augend The first number in an addition.
16158 * @param {number} addend The second number in an addition.
16159 * @returns {number} Returns the total.
16165 var add = createMathOperation(function(augend, addend) {
16166 return augend + addend;
16170 * Computes `number` rounded up to `precision`.
16176 * @param {number} number The number to round up.
16177 * @param {number} [precision=0] The precision to round up to.
16178 * @returns {number} Returns the rounded up number.
16184 * _.ceil(6.004, 2);
16187 * _.ceil(6040, -2);
16190 var ceil = createRound('ceil');
16193 * Divide two numbers.
16199 * @param {number} dividend The first number in a division.
16200 * @param {number} divisor The second number in a division.
16201 * @returns {number} Returns the quotient.
16207 var divide = createMathOperation(function(dividend, divisor) {
16208 return dividend / divisor;
16212 * Computes `number` rounded down to `precision`.
16218 * @param {number} number The number to round down.
16219 * @param {number} [precision=0] The precision to round down to.
16220 * @returns {number} Returns the rounded down number.
16226 * _.floor(0.046, 2);
16229 * _.floor(4060, -2);
16232 var floor = createRound('floor');
16235 * Computes the maximum value of `array`. If `array` is empty or falsey,
16236 * `undefined` is returned.
16242 * @param {Array} array The array to iterate over.
16243 * @returns {*} Returns the maximum value.
16246 * _.max([4, 2, 8, 6]);
16252 function max(array) {
16253 return (array && array.length)
16254 ? baseExtremum(array, identity, baseGt)
16259 * This method is like `_.max` except that it accepts `iteratee` which is
16260 * invoked for each element in `array` to generate the criterion by which
16261 * the value is ranked. The iteratee is invoked with one argument: (value).
16267 * @param {Array} array The array to iterate over.
16268 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16269 * @returns {*} Returns the maximum value.
16272 * var objects = [{ 'n': 1 }, { 'n': 2 }];
16274 * _.maxBy(objects, function(o) { return o.n; });
16277 * // The `_.property` iteratee shorthand.
16278 * _.maxBy(objects, 'n');
16281 function maxBy(array, iteratee) {
16282 return (array && array.length)
16283 ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
16288 * Computes the mean of the values in `array`.
16294 * @param {Array} array The array to iterate over.
16295 * @returns {number} Returns the mean.
16298 * _.mean([4, 2, 8, 6]);
16301 function mean(array) {
16302 return baseMean(array, identity);
16306 * This method is like `_.mean` except that it accepts `iteratee` which is
16307 * invoked for each element in `array` to generate the value to be averaged.
16308 * The iteratee is invoked with one argument: (value).
16314 * @param {Array} array The array to iterate over.
16315 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16316 * @returns {number} Returns the mean.
16319 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16321 * _.meanBy(objects, function(o) { return o.n; });
16324 * // The `_.property` iteratee shorthand.
16325 * _.meanBy(objects, 'n');
16328 function meanBy(array, iteratee) {
16329 return baseMean(array, getIteratee(iteratee, 2));
16333 * Computes the minimum value of `array`. If `array` is empty or falsey,
16334 * `undefined` is returned.
16340 * @param {Array} array The array to iterate over.
16341 * @returns {*} Returns the minimum value.
16344 * _.min([4, 2, 8, 6]);
16350 function min(array) {
16351 return (array && array.length)
16352 ? baseExtremum(array, identity, baseLt)
16357 * This method is like `_.min` except that it accepts `iteratee` which is
16358 * invoked for each element in `array` to generate the criterion by which
16359 * the value is ranked. The iteratee is invoked with one argument: (value).
16365 * @param {Array} array The array to iterate over.
16366 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16367 * @returns {*} Returns the minimum value.
16370 * var objects = [{ 'n': 1 }, { 'n': 2 }];
16372 * _.minBy(objects, function(o) { return o.n; });
16375 * // The `_.property` iteratee shorthand.
16376 * _.minBy(objects, 'n');
16379 function minBy(array, iteratee) {
16380 return (array && array.length)
16381 ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
16386 * Multiply two numbers.
16392 * @param {number} multiplier The first number in a multiplication.
16393 * @param {number} multiplicand The second number in a multiplication.
16394 * @returns {number} Returns the product.
16397 * _.multiply(6, 4);
16400 var multiply = createMathOperation(function(multiplier, multiplicand) {
16401 return multiplier * multiplicand;
16405 * Computes `number` rounded to `precision`.
16411 * @param {number} number The number to round.
16412 * @param {number} [precision=0] The precision to round to.
16413 * @returns {number} Returns the rounded number.
16419 * _.round(4.006, 2);
16422 * _.round(4060, -2);
16425 var round = createRound('round');
16428 * Subtract two numbers.
16434 * @param {number} minuend The first number in a subtraction.
16435 * @param {number} subtrahend The second number in a subtraction.
16436 * @returns {number} Returns the difference.
16439 * _.subtract(6, 4);
16442 var subtract = createMathOperation(function(minuend, subtrahend) {
16443 return minuend - subtrahend;
16447 * Computes the sum of the values in `array`.
16453 * @param {Array} array The array to iterate over.
16454 * @returns {number} Returns the sum.
16457 * _.sum([4, 2, 8, 6]);
16460 function sum(array) {
16461 return (array && array.length)
16462 ? baseSum(array, identity)
16467 * This method is like `_.sum` except that it accepts `iteratee` which is
16468 * invoked for each element in `array` to generate the value to be summed.
16469 * The iteratee is invoked with one argument: (value).
16475 * @param {Array} array The array to iterate over.
16476 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16477 * @returns {number} Returns the sum.
16480 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16482 * _.sumBy(objects, function(o) { return o.n; });
16485 * // The `_.property` iteratee shorthand.
16486 * _.sumBy(objects, 'n');
16489 function sumBy(array, iteratee) {
16490 return (array && array.length)
16491 ? baseSum(array, getIteratee(iteratee, 2))
16495 /*------------------------------------------------------------------------*/
16497 // Add methods that return wrapped values in chain sequences.
16498 lodash.after = after;
16500 lodash.assign = assign;
16501 lodash.assignIn = assignIn;
16502 lodash.assignInWith = assignInWith;
16503 lodash.assignWith = assignWith;
16505 lodash.before = before;
16506 lodash.bind = bind;
16507 lodash.bindAll = bindAll;
16508 lodash.bindKey = bindKey;
16509 lodash.castArray = castArray;
16510 lodash.chain = chain;
16511 lodash.chunk = chunk;
16512 lodash.compact = compact;
16513 lodash.concat = concat;
16514 lodash.cond = cond;
16515 lodash.conforms = conforms;
16516 lodash.constant = constant;
16517 lodash.countBy = countBy;
16518 lodash.create = create;
16519 lodash.curry = curry;
16520 lodash.curryRight = curryRight;
16521 lodash.debounce = debounce;
16522 lodash.defaults = defaults;
16523 lodash.defaultsDeep = defaultsDeep;
16524 lodash.defer = defer;
16525 lodash.delay = delay;
16526 lodash.difference = difference;
16527 lodash.differenceBy = differenceBy;
16528 lodash.differenceWith = differenceWith;
16529 lodash.drop = drop;
16530 lodash.dropRight = dropRight;
16531 lodash.dropRightWhile = dropRightWhile;
16532 lodash.dropWhile = dropWhile;
16533 lodash.fill = fill;
16534 lodash.filter = filter;
16535 lodash.flatMap = flatMap;
16536 lodash.flatMapDeep = flatMapDeep;
16537 lodash.flatMapDepth = flatMapDepth;
16538 lodash.flatten = flatten;
16539 lodash.flattenDeep = flattenDeep;
16540 lodash.flattenDepth = flattenDepth;
16541 lodash.flip = flip;
16542 lodash.flow = flow;
16543 lodash.flowRight = flowRight;
16544 lodash.fromPairs = fromPairs;
16545 lodash.functions = functions;
16546 lodash.functionsIn = functionsIn;
16547 lodash.groupBy = groupBy;
16548 lodash.initial = initial;
16549 lodash.intersection = intersection;
16550 lodash.intersectionBy = intersectionBy;
16551 lodash.intersectionWith = intersectionWith;
16552 lodash.invert = invert;
16553 lodash.invertBy = invertBy;
16554 lodash.invokeMap = invokeMap;
16555 lodash.iteratee = iteratee;
16556 lodash.keyBy = keyBy;
16557 lodash.keys = keys;
16558 lodash.keysIn = keysIn;
16560 lodash.mapKeys = mapKeys;
16561 lodash.mapValues = mapValues;
16562 lodash.matches = matches;
16563 lodash.matchesProperty = matchesProperty;
16564 lodash.memoize = memoize;
16565 lodash.merge = merge;
16566 lodash.mergeWith = mergeWith;
16567 lodash.method = method;
16568 lodash.methodOf = methodOf;
16569 lodash.mixin = mixin;
16570 lodash.negate = negate;
16571 lodash.nthArg = nthArg;
16572 lodash.omit = omit;
16573 lodash.omitBy = omitBy;
16574 lodash.once = once;
16575 lodash.orderBy = orderBy;
16576 lodash.over = over;
16577 lodash.overArgs = overArgs;
16578 lodash.overEvery = overEvery;
16579 lodash.overSome = overSome;
16580 lodash.partial = partial;
16581 lodash.partialRight = partialRight;
16582 lodash.partition = partition;
16583 lodash.pick = pick;
16584 lodash.pickBy = pickBy;
16585 lodash.property = property;
16586 lodash.propertyOf = propertyOf;
16587 lodash.pull = pull;
16588 lodash.pullAll = pullAll;
16589 lodash.pullAllBy = pullAllBy;
16590 lodash.pullAllWith = pullAllWith;
16591 lodash.pullAt = pullAt;
16592 lodash.range = range;
16593 lodash.rangeRight = rangeRight;
16594 lodash.rearg = rearg;
16595 lodash.reject = reject;
16596 lodash.remove = remove;
16597 lodash.rest = rest;
16598 lodash.reverse = reverse;
16599 lodash.sampleSize = sampleSize;
16601 lodash.setWith = setWith;
16602 lodash.shuffle = shuffle;
16603 lodash.slice = slice;
16604 lodash.sortBy = sortBy;
16605 lodash.sortedUniq = sortedUniq;
16606 lodash.sortedUniqBy = sortedUniqBy;
16607 lodash.split = split;
16608 lodash.spread = spread;
16609 lodash.tail = tail;
16610 lodash.take = take;
16611 lodash.takeRight = takeRight;
16612 lodash.takeRightWhile = takeRightWhile;
16613 lodash.takeWhile = takeWhile;
16615 lodash.throttle = throttle;
16616 lodash.thru = thru;
16617 lodash.toArray = toArray;
16618 lodash.toPairs = toPairs;
16619 lodash.toPairsIn = toPairsIn;
16620 lodash.toPath = toPath;
16621 lodash.toPlainObject = toPlainObject;
16622 lodash.transform = transform;
16623 lodash.unary = unary;
16624 lodash.union = union;
16625 lodash.unionBy = unionBy;
16626 lodash.unionWith = unionWith;
16627 lodash.uniq = uniq;
16628 lodash.uniqBy = uniqBy;
16629 lodash.uniqWith = uniqWith;
16630 lodash.unset = unset;
16631 lodash.unzip = unzip;
16632 lodash.unzipWith = unzipWith;
16633 lodash.update = update;
16634 lodash.updateWith = updateWith;
16635 lodash.values = values;
16636 lodash.valuesIn = valuesIn;
16637 lodash.without = without;
16638 lodash.words = words;
16639 lodash.wrap = wrap;
16641 lodash.xorBy = xorBy;
16642 lodash.xorWith = xorWith;
16644 lodash.zipObject = zipObject;
16645 lodash.zipObjectDeep = zipObjectDeep;
16646 lodash.zipWith = zipWith;
16649 lodash.entries = toPairs;
16650 lodash.entriesIn = toPairsIn;
16651 lodash.extend = assignIn;
16652 lodash.extendWith = assignInWith;
16654 // Add methods to `lodash.prototype`.
16655 mixin(lodash, lodash);
16657 /*------------------------------------------------------------------------*/
16659 // Add methods that return unwrapped values in chain sequences.
16661 lodash.attempt = attempt;
16662 lodash.camelCase = camelCase;
16663 lodash.capitalize = capitalize;
16664 lodash.ceil = ceil;
16665 lodash.clamp = clamp;
16666 lodash.clone = clone;
16667 lodash.cloneDeep = cloneDeep;
16668 lodash.cloneDeepWith = cloneDeepWith;
16669 lodash.cloneWith = cloneWith;
16670 lodash.conformsTo = conformsTo;
16671 lodash.deburr = deburr;
16672 lodash.defaultTo = defaultTo;
16673 lodash.divide = divide;
16674 lodash.endsWith = endsWith;
16676 lodash.escape = escape;
16677 lodash.escapeRegExp = escapeRegExp;
16678 lodash.every = every;
16679 lodash.find = find;
16680 lodash.findIndex = findIndex;
16681 lodash.findKey = findKey;
16682 lodash.findLast = findLast;
16683 lodash.findLastIndex = findLastIndex;
16684 lodash.findLastKey = findLastKey;
16685 lodash.floor = floor;
16686 lodash.forEach = forEach;
16687 lodash.forEachRight = forEachRight;
16688 lodash.forIn = forIn;
16689 lodash.forInRight = forInRight;
16690 lodash.forOwn = forOwn;
16691 lodash.forOwnRight = forOwnRight;
16696 lodash.hasIn = hasIn;
16697 lodash.head = head;
16698 lodash.identity = identity;
16699 lodash.includes = includes;
16700 lodash.indexOf = indexOf;
16701 lodash.inRange = inRange;
16702 lodash.invoke = invoke;
16703 lodash.isArguments = isArguments;
16704 lodash.isArray = isArray;
16705 lodash.isArrayBuffer = isArrayBuffer;
16706 lodash.isArrayLike = isArrayLike;
16707 lodash.isArrayLikeObject = isArrayLikeObject;
16708 lodash.isBoolean = isBoolean;
16709 lodash.isBuffer = isBuffer;
16710 lodash.isDate = isDate;
16711 lodash.isElement = isElement;
16712 lodash.isEmpty = isEmpty;
16713 lodash.isEqual = isEqual;
16714 lodash.isEqualWith = isEqualWith;
16715 lodash.isError = isError;
16716 lodash.isFinite = isFinite;
16717 lodash.isFunction = isFunction;
16718 lodash.isInteger = isInteger;
16719 lodash.isLength = isLength;
16720 lodash.isMap = isMap;
16721 lodash.isMatch = isMatch;
16722 lodash.isMatchWith = isMatchWith;
16723 lodash.isNaN = isNaN;
16724 lodash.isNative = isNative;
16725 lodash.isNil = isNil;
16726 lodash.isNull = isNull;
16727 lodash.isNumber = isNumber;
16728 lodash.isObject = isObject;
16729 lodash.isObjectLike = isObjectLike;
16730 lodash.isPlainObject = isPlainObject;
16731 lodash.isRegExp = isRegExp;
16732 lodash.isSafeInteger = isSafeInteger;
16733 lodash.isSet = isSet;
16734 lodash.isString = isString;
16735 lodash.isSymbol = isSymbol;
16736 lodash.isTypedArray = isTypedArray;
16737 lodash.isUndefined = isUndefined;
16738 lodash.isWeakMap = isWeakMap;
16739 lodash.isWeakSet = isWeakSet;
16740 lodash.join = join;
16741 lodash.kebabCase = kebabCase;
16742 lodash.last = last;
16743 lodash.lastIndexOf = lastIndexOf;
16744 lodash.lowerCase = lowerCase;
16745 lodash.lowerFirst = lowerFirst;
16749 lodash.maxBy = maxBy;
16750 lodash.mean = mean;
16751 lodash.meanBy = meanBy;
16753 lodash.minBy = minBy;
16754 lodash.stubArray = stubArray;
16755 lodash.stubFalse = stubFalse;
16756 lodash.stubObject = stubObject;
16757 lodash.stubString = stubString;
16758 lodash.stubTrue = stubTrue;
16759 lodash.multiply = multiply;
16761 lodash.noConflict = noConflict;
16762 lodash.noop = noop;
16765 lodash.padEnd = padEnd;
16766 lodash.padStart = padStart;
16767 lodash.parseInt = parseInt;
16768 lodash.random = random;
16769 lodash.reduce = reduce;
16770 lodash.reduceRight = reduceRight;
16771 lodash.repeat = repeat;
16772 lodash.replace = replace;
16773 lodash.result = result;
16774 lodash.round = round;
16775 lodash.runInContext = runInContext;
16776 lodash.sample = sample;
16777 lodash.size = size;
16778 lodash.snakeCase = snakeCase;
16779 lodash.some = some;
16780 lodash.sortedIndex = sortedIndex;
16781 lodash.sortedIndexBy = sortedIndexBy;
16782 lodash.sortedIndexOf = sortedIndexOf;
16783 lodash.sortedLastIndex = sortedLastIndex;
16784 lodash.sortedLastIndexBy = sortedLastIndexBy;
16785 lodash.sortedLastIndexOf = sortedLastIndexOf;
16786 lodash.startCase = startCase;
16787 lodash.startsWith = startsWith;
16788 lodash.subtract = subtract;
16790 lodash.sumBy = sumBy;
16791 lodash.template = template;
16792 lodash.times = times;
16793 lodash.toFinite = toFinite;
16794 lodash.toInteger = toInteger;
16795 lodash.toLength = toLength;
16796 lodash.toLower = toLower;
16797 lodash.toNumber = toNumber;
16798 lodash.toSafeInteger = toSafeInteger;
16799 lodash.toString = toString;
16800 lodash.toUpper = toUpper;
16801 lodash.trim = trim;
16802 lodash.trimEnd = trimEnd;
16803 lodash.trimStart = trimStart;
16804 lodash.truncate = truncate;
16805 lodash.unescape = unescape;
16806 lodash.uniqueId = uniqueId;
16807 lodash.upperCase = upperCase;
16808 lodash.upperFirst = upperFirst;
16811 lodash.each = forEach;
16812 lodash.eachRight = forEachRight;
16813 lodash.first = head;
16815 mixin(lodash, (function() {
16817 baseForOwn(lodash, function(func, methodName) {
16818 if (!hasOwnProperty.call(lodash.prototype, methodName)) {
16819 source[methodName] = func;
16823 }()), { 'chain': false });
16825 /*------------------------------------------------------------------------*/
16828 * The semantic version number.
16834 lodash.VERSION = VERSION;
16836 // Assign default placeholders.
16837 arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
16838 lodash[methodName].placeholder = lodash;
16841 // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
16842 arrayEach(['drop', 'take'], function(methodName, index) {
16843 LazyWrapper.prototype[methodName] = function(n) {
16844 var filtered = this.__filtered__;
16845 if (filtered && !index) {
16846 return new LazyWrapper(this);
16848 n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
16850 var result = this.clone();
16852 result.__takeCount__ = nativeMin(n, result.__takeCount__);
16854 result.__views__.push({
16855 'size': nativeMin(n, MAX_ARRAY_LENGTH),
16856 'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
16862 LazyWrapper.prototype[methodName + 'Right'] = function(n) {
16863 return this.reverse()[methodName](n).reverse();
16867 // Add `LazyWrapper` methods that accept an `iteratee` value.
16868 arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
16869 var type = index + 1,
16870 isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
16872 LazyWrapper.prototype[methodName] = function(iteratee) {
16873 var result = this.clone();
16874 result.__iteratees__.push({
16875 'iteratee': getIteratee(iteratee, 3),
16878 result.__filtered__ = result.__filtered__ || isFilter;
16883 // Add `LazyWrapper` methods for `_.head` and `_.last`.
16884 arrayEach(['head', 'last'], function(methodName, index) {
16885 var takeName = 'take' + (index ? 'Right' : '');
16887 LazyWrapper.prototype[methodName] = function() {
16888 return this[takeName](1).value()[0];
16892 // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
16893 arrayEach(['initial', 'tail'], function(methodName, index) {
16894 var dropName = 'drop' + (index ? '' : 'Right');
16896 LazyWrapper.prototype[methodName] = function() {
16897 return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
16901 LazyWrapper.prototype.compact = function() {
16902 return this.filter(identity);
16905 LazyWrapper.prototype.find = function(predicate) {
16906 return this.filter(predicate).head();
16909 LazyWrapper.prototype.findLast = function(predicate) {
16910 return this.reverse().find(predicate);
16913 LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
16914 if (typeof path == 'function') {
16915 return new LazyWrapper(this);
16917 return this.map(function(value) {
16918 return baseInvoke(value, path, args);
16922 LazyWrapper.prototype.reject = function(predicate) {
16923 return this.filter(negate(getIteratee(predicate)));
16926 LazyWrapper.prototype.slice = function(start, end) {
16927 start = toInteger(start);
16930 if (result.__filtered__ && (start > 0 || end < 0)) {
16931 return new LazyWrapper(result);
16934 result = result.takeRight(-start);
16935 } else if (start) {
16936 result = result.drop(start);
16938 if (end !== undefined) {
16939 end = toInteger(end);
16940 result = end < 0 ? result.dropRight(-end) : result.take(end - start);
16945 LazyWrapper.prototype.takeRightWhile = function(predicate) {
16946 return this.reverse().takeWhile(predicate).reverse();
16949 LazyWrapper.prototype.toArray = function() {
16950 return this.take(MAX_ARRAY_LENGTH);
16953 // Add `LazyWrapper` methods to `lodash.prototype`.
16954 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16955 var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
16956 isTaker = /^(?:head|last)$/.test(methodName),
16957 lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
16958 retUnwrapped = isTaker || /^find/.test(methodName);
16963 lodash.prototype[methodName] = function() {
16964 var value = this.__wrapped__,
16965 args = isTaker ? [1] : arguments,
16966 isLazy = value instanceof LazyWrapper,
16967 iteratee = args[0],
16968 useLazy = isLazy || isArray(value);
16970 var interceptor = function(value) {
16971 var result = lodashFunc.apply(lodash, arrayPush([value], args));
16972 return (isTaker && chainAll) ? result[0] : result;
16975 if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
16976 // Avoid lazy use if the iteratee has a "length" value other than `1`.
16977 isLazy = useLazy = false;
16979 var chainAll = this.__chain__,
16980 isHybrid = !!this.__actions__.length,
16981 isUnwrapped = retUnwrapped && !chainAll,
16982 onlyLazy = isLazy && !isHybrid;
16984 if (!retUnwrapped && useLazy) {
16985 value = onlyLazy ? value : new LazyWrapper(this);
16986 var result = func.apply(value, args);
16987 result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
16988 return new LodashWrapper(result, chainAll);
16990 if (isUnwrapped && onlyLazy) {
16991 return func.apply(this, args);
16993 result = this.thru(interceptor);
16994 return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
16998 // Add `Array` methods to `lodash.prototype`.
16999 arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
17000 var func = arrayProto[methodName],
17001 chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
17002 retUnwrapped = /^(?:pop|shift)$/.test(methodName);
17004 lodash.prototype[methodName] = function() {
17005 var args = arguments;
17006 if (retUnwrapped && !this.__chain__) {
17007 var value = this.value();
17008 return func.apply(isArray(value) ? value : [], args);
17010 return this[chainName](function(value) {
17011 return func.apply(isArray(value) ? value : [], args);
17016 // Map minified method names to their real names.
17017 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
17018 var lodashFunc = lodash[methodName];
17020 var key = (lodashFunc.name + ''),
17021 names = realNames[key] || (realNames[key] = []);
17023 names.push({ 'name': methodName, 'func': lodashFunc });
17027 realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
17032 // Add methods to `LazyWrapper`.
17033 LazyWrapper.prototype.clone = lazyClone;
17034 LazyWrapper.prototype.reverse = lazyReverse;
17035 LazyWrapper.prototype.value = lazyValue;
17037 // Add chain sequence methods to the `lodash` wrapper.
17038 lodash.prototype.at = wrapperAt;
17039 lodash.prototype.chain = wrapperChain;
17040 lodash.prototype.commit = wrapperCommit;
17041 lodash.prototype.next = wrapperNext;
17042 lodash.prototype.plant = wrapperPlant;
17043 lodash.prototype.reverse = wrapperReverse;
17044 lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
17046 // Add lazy aliases.
17047 lodash.prototype.first = lodash.prototype.head;
17050 lodash.prototype[symIterator] = wrapperToIterator;
17055 /*--------------------------------------------------------------------------*/
17058 var _ = runInContext();
17060 // Some AMD build optimizers, like r.js, check for condition patterns like:
17061 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
17062 // Expose Lodash on the global object to prevent errors when Lodash is
17063 // loaded by a script tag in the presence of an AMD loader.
17064 // See http://requirejs.org/docs/errors.html#mismatch for more details.
17065 // Use `_.noConflict` to remove Lodash from the global object.
17068 // Define as an anonymous module so, through path mapping, it can be
17069 // referenced as the "underscore" module.
17070 define(function() {
17074 // Check for `exports` after `define` in case a build optimizer adds it.
17075 else if (freeModule) {
17076 // Export for Node.js.
17077 (freeModule.exports = _)._ = _;
17078 // Export for CommonJS support.
17082 // Export to the global object.
17085 }.call(commonjsGlobal));
17088 function osmIsInterestingTag(key) {
17089 return key !== 'attribution' &&
17090 key !== 'created_by' &&
17091 key !== 'source' &&
17093 key.indexOf('tiger:') !== 0;
17098 var osmOneWayTags = {
17100 'chair_lift': true,
17101 'mixed_lift': true,
17106 'magic_carpet': true,
17111 'motorway_link': true
17117 'piste:halfpipe': true
17131 var osmPavedTags = {
17142 var dataWikipedia = [
17259 "беларуская (тарашкевіца)",
17260 "беларуская (тарашкевіца)",
17300 "বিষ্ণুপ্রিয়া মণিপুরী",
17329 "Chavacano de Zamboanga",
17330 "Chavacano de Zamboanga",
17334 "Min Dong Chinese",
17375 "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ",
17395 "словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ",
17449 "Emiliano-Romagnolo",
17450 "emiliàn e rumagnòl",
17505 "Na Vosa Vakaviti",
17524 "Northern Frisian",
17575 "गोंयची कोंकणी / Gõychi Konknni",
17655 "Bahasa Indonesia",
17695 "ᐃᓄᒃᑎᑐᑦ/inuktitut",
17704 "Jamaican Creole English",
17780 "къарачай-малкъар",
17920 "Baso Minangkabau",
18019 "Norwegian Nynorsk",
18040 "Sesotho sa Leboa",
18104 "Pennsylvania German",
18119 "Norfuk / Pitkern",
18120 "Norfuk / Pitkern",
18245 "srpskohrvatski / српскохрватски",
18309 "Saterland Frisian",
18435 "ئۇيغۇرچە / Uyghurche",
18450 "oʻzbekcha/ўзбекча",
18544 "Classical Chinese",
18549 "Chinese (Min Nan)",
18565 var dataFeatureIcons = {
18566 "circle-stroked-24": {"x":0,"y":0,"width":24,"height":24},
18567 "circle-stroked-18": {"x":24,"y":0,"width":18,"height":18},
18568 "circle-stroked-12": {"x":42,"y":0,"width":12,"height":12},
18569 "circle-24": {"x":54,"y":0,"width":24,"height":24},
18570 "circle-18": {"x":78,"y":0,"width":18,"height":18},
18571 "circle-12": {"x":96,"y":0,"width":12,"height":12},
18572 "square-stroked-24": {"x":108,"y":0,"width":24,"height":24},
18573 "square-stroked-18": {"x":132,"y":0,"width":18,"height":18},
18574 "square-stroked-12": {"x":150,"y":0,"width":12,"height":12},
18575 "square-24": {"x":162,"y":0,"width":24,"height":24},
18576 "square-18": {"x":186,"y":0,"width":18,"height":18},
18577 "square-12": {"x":204,"y":0,"width":12,"height":12},
18578 "triangle-stroked-24": {"x":216,"y":0,"width":24,"height":24},
18579 "triangle-stroked-18": {"x":240,"y":0,"width":18,"height":18},
18580 "triangle-stroked-12": {"x":258,"y":0,"width":12,"height":12},
18581 "triangle-24": {"x":0,"y":24,"width":24,"height":24},
18582 "triangle-18": {"x":24,"y":24,"width":18,"height":18},
18583 "triangle-12": {"x":42,"y":24,"width":12,"height":12},
18584 "star-stroked-24": {"x":54,"y":24,"width":24,"height":24},
18585 "star-stroked-18": {"x":78,"y":24,"width":18,"height":18},
18586 "star-stroked-12": {"x":96,"y":24,"width":12,"height":12},
18587 "star-24": {"x":108,"y":24,"width":24,"height":24},
18588 "star-18": {"x":132,"y":24,"width":18,"height":18},
18589 "star-12": {"x":150,"y":24,"width":12,"height":12},
18590 "cross-24": {"x":162,"y":24,"width":24,"height":24},
18591 "cross-18": {"x":186,"y":24,"width":18,"height":18},
18592 "cross-12": {"x":204,"y":24,"width":12,"height":12},
18593 "marker-stroked-24": {"x":216,"y":24,"width":24,"height":24},
18594 "marker-stroked-18": {"x":240,"y":24,"width":18,"height":18},
18595 "marker-stroked-12": {"x":258,"y":24,"width":12,"height":12},
18596 "marker-24": {"x":0,"y":48,"width":24,"height":24},
18597 "marker-18": {"x":24,"y":48,"width":18,"height":18},
18598 "marker-12": {"x":42,"y":48,"width":12,"height":12},
18599 "religious-jewish-24": {"x":54,"y":48,"width":24,"height":24},
18600 "religious-jewish-18": {"x":78,"y":48,"width":18,"height":18},
18601 "religious-jewish-12": {"x":96,"y":48,"width":12,"height":12},
18602 "religious-christian-24": {"x":108,"y":48,"width":24,"height":24},
18603 "religious-christian-18": {"x":132,"y":48,"width":18,"height":18},
18604 "religious-christian-12": {"x":150,"y":48,"width":12,"height":12},
18605 "religious-muslim-24": {"x":162,"y":48,"width":24,"height":24},
18606 "religious-muslim-18": {"x":186,"y":48,"width":18,"height":18},
18607 "religious-muslim-12": {"x":204,"y":48,"width":12,"height":12},
18608 "cemetery-24": {"x":216,"y":48,"width":24,"height":24},
18609 "cemetery-18": {"x":240,"y":48,"width":18,"height":18},
18610 "cemetery-12": {"x":258,"y":48,"width":12,"height":12},
18611 "rocket-24": {"x":0,"y":72,"width":24,"height":24},
18612 "rocket-18": {"x":24,"y":72,"width":18,"height":18},
18613 "rocket-12": {"x":42,"y":72,"width":12,"height":12},
18614 "airport-24": {"x":54,"y":72,"width":24,"height":24},
18615 "airport-18": {"x":78,"y":72,"width":18,"height":18},
18616 "airport-12": {"x":96,"y":72,"width":12,"height":12},
18617 "heliport-24": {"x":108,"y":72,"width":24,"height":24},
18618 "heliport-18": {"x":132,"y":72,"width":18,"height":18},
18619 "heliport-12": {"x":150,"y":72,"width":12,"height":12},
18620 "rail-24": {"x":162,"y":72,"width":24,"height":24},
18621 "rail-18": {"x":186,"y":72,"width":18,"height":18},
18622 "rail-12": {"x":204,"y":72,"width":12,"height":12},
18623 "rail-metro-24": {"x":216,"y":72,"width":24,"height":24},
18624 "rail-metro-18": {"x":240,"y":72,"width":18,"height":18},
18625 "rail-metro-12": {"x":258,"y":72,"width":12,"height":12},
18626 "rail-light-24": {"x":0,"y":96,"width":24,"height":24},
18627 "rail-light-18": {"x":24,"y":96,"width":18,"height":18},
18628 "rail-light-12": {"x":42,"y":96,"width":12,"height":12},
18629 "bus-24": {"x":54,"y":96,"width":24,"height":24},
18630 "bus-18": {"x":78,"y":96,"width":18,"height":18},
18631 "bus-12": {"x":96,"y":96,"width":12,"height":12},
18632 "fuel-24": {"x":108,"y":96,"width":24,"height":24},
18633 "fuel-18": {"x":132,"y":96,"width":18,"height":18},
18634 "fuel-12": {"x":150,"y":96,"width":12,"height":12},
18635 "parking-24": {"x":162,"y":96,"width":24,"height":24},
18636 "parking-18": {"x":186,"y":96,"width":18,"height":18},
18637 "parking-12": {"x":204,"y":96,"width":12,"height":12},
18638 "parking-garage-24": {"x":216,"y":96,"width":24,"height":24},
18639 "parking-garage-18": {"x":240,"y":96,"width":18,"height":18},
18640 "parking-garage-12": {"x":258,"y":96,"width":12,"height":12},
18641 "airfield-24": {"x":0,"y":120,"width":24,"height":24},
18642 "airfield-18": {"x":24,"y":120,"width":18,"height":18},
18643 "airfield-12": {"x":42,"y":120,"width":12,"height":12},
18644 "roadblock-24": {"x":54,"y":120,"width":24,"height":24},
18645 "roadblock-18": {"x":78,"y":120,"width":18,"height":18},
18646 "roadblock-12": {"x":96,"y":120,"width":12,"height":12},
18647 "ferry-24": {"x":108,"y":120,"width":24,"height":24},
18648 "ferry-18": {"x":132,"y":120,"width":18,"height":18},
18649 "ferry-12": {"x":150,"y":120,"width":12,"height":12},
18650 "harbor-24": {"x":162,"y":120,"width":24,"height":24},
18651 "harbor-18": {"x":186,"y":120,"width":18,"height":18},
18652 "harbor-12": {"x":204,"y":120,"width":12,"height":12},
18653 "bicycle-24": {"x":216,"y":120,"width":24,"height":24},
18654 "bicycle-18": {"x":240,"y":120,"width":18,"height":18},
18655 "bicycle-12": {"x":258,"y":120,"width":12,"height":12},
18656 "park-24": {"x":0,"y":144,"width":24,"height":24},
18657 "park-18": {"x":24,"y":144,"width":18,"height":18},
18658 "park-12": {"x":42,"y":144,"width":12,"height":12},
18659 "park2-24": {"x":54,"y":144,"width":24,"height":24},
18660 "park2-18": {"x":78,"y":144,"width":18,"height":18},
18661 "park2-12": {"x":96,"y":144,"width":12,"height":12},
18662 "museum-24": {"x":108,"y":144,"width":24,"height":24},
18663 "museum-18": {"x":132,"y":144,"width":18,"height":18},
18664 "museum-12": {"x":150,"y":144,"width":12,"height":12},
18665 "lodging-24": {"x":162,"y":144,"width":24,"height":24},
18666 "lodging-18": {"x":186,"y":144,"width":18,"height":18},
18667 "lodging-12": {"x":204,"y":144,"width":12,"height":12},
18668 "monument-24": {"x":216,"y":144,"width":24,"height":24},
18669 "monument-18": {"x":240,"y":144,"width":18,"height":18},
18670 "monument-12": {"x":258,"y":144,"width":12,"height":12},
18671 "zoo-24": {"x":0,"y":168,"width":24,"height":24},
18672 "zoo-18": {"x":24,"y":168,"width":18,"height":18},
18673 "zoo-12": {"x":42,"y":168,"width":12,"height":12},
18674 "garden-24": {"x":54,"y":168,"width":24,"height":24},
18675 "garden-18": {"x":78,"y":168,"width":18,"height":18},
18676 "garden-12": {"x":96,"y":168,"width":12,"height":12},
18677 "campsite-24": {"x":108,"y":168,"width":24,"height":24},
18678 "campsite-18": {"x":132,"y":168,"width":18,"height":18},
18679 "campsite-12": {"x":150,"y":168,"width":12,"height":12},
18680 "theatre-24": {"x":162,"y":168,"width":24,"height":24},
18681 "theatre-18": {"x":186,"y":168,"width":18,"height":18},
18682 "theatre-12": {"x":204,"y":168,"width":12,"height":12},
18683 "art-gallery-24": {"x":216,"y":168,"width":24,"height":24},
18684 "art-gallery-18": {"x":240,"y":168,"width":18,"height":18},
18685 "art-gallery-12": {"x":258,"y":168,"width":12,"height":12},
18686 "pitch-24": {"x":0,"y":192,"width":24,"height":24},
18687 "pitch-18": {"x":24,"y":192,"width":18,"height":18},
18688 "pitch-12": {"x":42,"y":192,"width":12,"height":12},
18689 "soccer-24": {"x":54,"y":192,"width":24,"height":24},
18690 "soccer-18": {"x":78,"y":192,"width":18,"height":18},
18691 "soccer-12": {"x":96,"y":192,"width":12,"height":12},
18692 "america-football-24": {"x":108,"y":192,"width":24,"height":24},
18693 "america-football-18": {"x":132,"y":192,"width":18,"height":18},
18694 "america-football-12": {"x":150,"y":192,"width":12,"height":12},
18695 "tennis-24": {"x":162,"y":192,"width":24,"height":24},
18696 "tennis-18": {"x":186,"y":192,"width":18,"height":18},
18697 "tennis-12": {"x":204,"y":192,"width":12,"height":12},
18698 "basketball-24": {"x":216,"y":192,"width":24,"height":24},
18699 "basketball-18": {"x":240,"y":192,"width":18,"height":18},
18700 "basketball-12": {"x":258,"y":192,"width":12,"height":12},
18701 "baseball-24": {"x":0,"y":216,"width":24,"height":24},
18702 "baseball-18": {"x":24,"y":216,"width":18,"height":18},
18703 "baseball-12": {"x":42,"y":216,"width":12,"height":12},
18704 "golf-24": {"x":54,"y":216,"width":24,"height":24},
18705 "golf-18": {"x":78,"y":216,"width":18,"height":18},
18706 "golf-12": {"x":96,"y":216,"width":12,"height":12},
18707 "swimming-24": {"x":108,"y":216,"width":24,"height":24},
18708 "swimming-18": {"x":132,"y":216,"width":18,"height":18},
18709 "swimming-12": {"x":150,"y":216,"width":12,"height":12},
18710 "cricket-24": {"x":162,"y":216,"width":24,"height":24},
18711 "cricket-18": {"x":186,"y":216,"width":18,"height":18},
18712 "cricket-12": {"x":204,"y":216,"width":12,"height":12},
18713 "skiing-24": {"x":216,"y":216,"width":24,"height":24},
18714 "skiing-18": {"x":240,"y":216,"width":18,"height":18},
18715 "skiing-12": {"x":258,"y":216,"width":12,"height":12},
18716 "school-24": {"x":0,"y":240,"width":24,"height":24},
18717 "school-18": {"x":24,"y":240,"width":18,"height":18},
18718 "school-12": {"x":42,"y":240,"width":12,"height":12},
18719 "college-24": {"x":54,"y":240,"width":24,"height":24},
18720 "college-18": {"x":78,"y":240,"width":18,"height":18},
18721 "college-12": {"x":96,"y":240,"width":12,"height":12},
18722 "library-24": {"x":108,"y":240,"width":24,"height":24},
18723 "library-18": {"x":132,"y":240,"width":18,"height":18},
18724 "library-12": {"x":150,"y":240,"width":12,"height":12},
18725 "post-24": {"x":162,"y":240,"width":24,"height":24},
18726 "post-18": {"x":186,"y":240,"width":18,"height":18},
18727 "post-12": {"x":204,"y":240,"width":12,"height":12},
18728 "fire-station-24": {"x":216,"y":240,"width":24,"height":24},
18729 "fire-station-18": {"x":240,"y":240,"width":18,"height":18},
18730 "fire-station-12": {"x":258,"y":240,"width":12,"height":12},
18731 "town-hall-24": {"x":0,"y":264,"width":24,"height":24},
18732 "town-hall-18": {"x":24,"y":264,"width":18,"height":18},
18733 "town-hall-12": {"x":42,"y":264,"width":12,"height":12},
18734 "police-24": {"x":54,"y":264,"width":24,"height":24},
18735 "police-18": {"x":78,"y":264,"width":18,"height":18},
18736 "police-12": {"x":96,"y":264,"width":12,"height":12},
18737 "prison-24": {"x":108,"y":264,"width":24,"height":24},
18738 "prison-18": {"x":132,"y":264,"width":18,"height":18},
18739 "prison-12": {"x":150,"y":264,"width":12,"height":12},
18740 "embassy-24": {"x":162,"y":264,"width":24,"height":24},
18741 "embassy-18": {"x":186,"y":264,"width":18,"height":18},
18742 "embassy-12": {"x":204,"y":264,"width":12,"height":12},
18743 "beer-24": {"x":216,"y":264,"width":24,"height":24},
18744 "beer-18": {"x":240,"y":264,"width":18,"height":18},
18745 "beer-12": {"x":258,"y":264,"width":12,"height":12},
18746 "restaurant-24": {"x":0,"y":288,"width":24,"height":24},
18747 "restaurant-18": {"x":24,"y":288,"width":18,"height":18},
18748 "restaurant-12": {"x":42,"y":288,"width":12,"height":12},
18749 "cafe-24": {"x":54,"y":288,"width":24,"height":24},
18750 "cafe-18": {"x":78,"y":288,"width":18,"height":18},
18751 "cafe-12": {"x":96,"y":288,"width":12,"height":12},
18752 "shop-24": {"x":108,"y":288,"width":24,"height":24},
18753 "shop-18": {"x":132,"y":288,"width":18,"height":18},
18754 "shop-12": {"x":150,"y":288,"width":12,"height":12},
18755 "fast-food-24": {"x":162,"y":288,"width":24,"height":24},
18756 "fast-food-18": {"x":186,"y":288,"width":18,"height":18},
18757 "fast-food-12": {"x":204,"y":288,"width":12,"height":12},
18758 "bar-24": {"x":216,"y":288,"width":24,"height":24},
18759 "bar-18": {"x":240,"y":288,"width":18,"height":18},
18760 "bar-12": {"x":258,"y":288,"width":12,"height":12},
18761 "bank-24": {"x":0,"y":312,"width":24,"height":24},
18762 "bank-18": {"x":24,"y":312,"width":18,"height":18},
18763 "bank-12": {"x":42,"y":312,"width":12,"height":12},
18764 "grocery-24": {"x":54,"y":312,"width":24,"height":24},
18765 "grocery-18": {"x":78,"y":312,"width":18,"height":18},
18766 "grocery-12": {"x":96,"y":312,"width":12,"height":12},
18767 "cinema-24": {"x":108,"y":312,"width":24,"height":24},
18768 "cinema-18": {"x":132,"y":312,"width":18,"height":18},
18769 "cinema-12": {"x":150,"y":312,"width":12,"height":12},
18770 "pharmacy-24": {"x":162,"y":312,"width":24,"height":24},
18771 "pharmacy-18": {"x":186,"y":312,"width":18,"height":18},
18772 "pharmacy-12": {"x":204,"y":312,"width":12,"height":12},
18773 "hospital-24": {"x":216,"y":312,"width":24,"height":24},
18774 "hospital-18": {"x":240,"y":312,"width":18,"height":18},
18775 "hospital-12": {"x":258,"y":312,"width":12,"height":12},
18776 "danger-24": {"x":0,"y":336,"width":24,"height":24},
18777 "danger-18": {"x":24,"y":336,"width":18,"height":18},
18778 "danger-12": {"x":42,"y":336,"width":12,"height":12},
18779 "industrial-24": {"x":54,"y":336,"width":24,"height":24},
18780 "industrial-18": {"x":78,"y":336,"width":18,"height":18},
18781 "industrial-12": {"x":96,"y":336,"width":12,"height":12},
18782 "warehouse-24": {"x":108,"y":336,"width":24,"height":24},
18783 "warehouse-18": {"x":132,"y":336,"width":18,"height":18},
18784 "warehouse-12": {"x":150,"y":336,"width":12,"height":12},
18785 "commercial-24": {"x":162,"y":336,"width":24,"height":24},
18786 "commercial-18": {"x":186,"y":336,"width":18,"height":18},
18787 "commercial-12": {"x":204,"y":336,"width":12,"height":12},
18788 "building-24": {"x":216,"y":336,"width":24,"height":24},
18789 "building-18": {"x":240,"y":336,"width":18,"height":18},
18790 "building-12": {"x":258,"y":336,"width":12,"height":12},
18791 "place-of-worship-24": {"x":0,"y":360,"width":24,"height":24},
18792 "place-of-worship-18": {"x":24,"y":360,"width":18,"height":18},
18793 "place-of-worship-12": {"x":42,"y":360,"width":12,"height":12},
18794 "alcohol-shop-24": {"x":54,"y":360,"width":24,"height":24},
18795 "alcohol-shop-18": {"x":78,"y":360,"width":18,"height":18},
18796 "alcohol-shop-12": {"x":96,"y":360,"width":12,"height":12},
18797 "logging-24": {"x":108,"y":360,"width":24,"height":24},
18798 "logging-18": {"x":132,"y":360,"width":18,"height":18},
18799 "logging-12": {"x":150,"y":360,"width":12,"height":12},
18800 "oil-well-24": {"x":162,"y":360,"width":24,"height":24},
18801 "oil-well-18": {"x":186,"y":360,"width":18,"height":18},
18802 "oil-well-12": {"x":204,"y":360,"width":12,"height":12},
18803 "slaughterhouse-24": {"x":216,"y":360,"width":24,"height":24},
18804 "slaughterhouse-18": {"x":240,"y":360,"width":18,"height":18},
18805 "slaughterhouse-12": {"x":258,"y":360,"width":12,"height":12},
18806 "dam-24": {"x":0,"y":384,"width":24,"height":24},
18807 "dam-18": {"x":24,"y":384,"width":18,"height":18},
18808 "dam-12": {"x":42,"y":384,"width":12,"height":12},
18809 "water-24": {"x":54,"y":384,"width":24,"height":24},
18810 "water-18": {"x":78,"y":384,"width":18,"height":18},
18811 "water-12": {"x":96,"y":384,"width":12,"height":12},
18812 "wetland-24": {"x":108,"y":384,"width":24,"height":24},
18813 "wetland-18": {"x":132,"y":384,"width":18,"height":18},
18814 "wetland-12": {"x":150,"y":384,"width":12,"height":12},
18815 "disability-24": {"x":162,"y":384,"width":24,"height":24},
18816 "disability-18": {"x":186,"y":384,"width":18,"height":18},
18817 "disability-12": {"x":204,"y":384,"width":12,"height":12},
18818 "telephone-24": {"x":216,"y":384,"width":24,"height":24},
18819 "telephone-18": {"x":240,"y":384,"width":18,"height":18},
18820 "telephone-12": {"x":258,"y":384,"width":12,"height":12},
18821 "emergency-telephone-24": {"x":0,"y":408,"width":24,"height":24},
18822 "emergency-telephone-18": {"x":24,"y":408,"width":18,"height":18},
18823 "emergency-telephone-12": {"x":42,"y":408,"width":12,"height":12},
18824 "toilets-24": {"x":54,"y":408,"width":24,"height":24},
18825 "toilets-18": {"x":78,"y":408,"width":18,"height":18},
18826 "toilets-12": {"x":96,"y":408,"width":12,"height":12},
18827 "waste-basket-24": {"x":108,"y":408,"width":24,"height":24},
18828 "waste-basket-18": {"x":132,"y":408,"width":18,"height":18},
18829 "waste-basket-12": {"x":150,"y":408,"width":12,"height":12},
18830 "music-24": {"x":162,"y":408,"width":24,"height":24},
18831 "music-18": {"x":186,"y":408,"width":18,"height":18},
18832 "music-12": {"x":204,"y":408,"width":12,"height":12},
18833 "land-use-24": {"x":216,"y":408,"width":24,"height":24},
18834 "land-use-18": {"x":240,"y":408,"width":18,"height":18},
18835 "land-use-12": {"x":258,"y":408,"width":12,"height":12},
18836 "city-24": {"x":0,"y":432,"width":24,"height":24},
18837 "city-18": {"x":24,"y":432,"width":18,"height":18},
18838 "city-12": {"x":42,"y":432,"width":12,"height":12},
18839 "town-24": {"x":54,"y":432,"width":24,"height":24},
18840 "town-18": {"x":78,"y":432,"width":18,"height":18},
18841 "town-12": {"x":96,"y":432,"width":12,"height":12},
18842 "village-24": {"x":108,"y":432,"width":24,"height":24},
18843 "village-18": {"x":132,"y":432,"width":18,"height":18},
18844 "village-12": {"x":150,"y":432,"width":12,"height":12},
18845 "farm-24": {"x":162,"y":432,"width":24,"height":24},
18846 "farm-18": {"x":186,"y":432,"width":18,"height":18},
18847 "farm-12": {"x":204,"y":432,"width":12,"height":12},
18848 "bakery-24": {"x":216,"y":432,"width":24,"height":24},
18849 "bakery-18": {"x":240,"y":432,"width":18,"height":18},
18850 "bakery-12": {"x":258,"y":432,"width":12,"height":12},
18851 "dog-park-24": {"x":0,"y":456,"width":24,"height":24},
18852 "dog-park-18": {"x":24,"y":456,"width":18,"height":18},
18853 "dog-park-12": {"x":42,"y":456,"width":12,"height":12},
18854 "lighthouse-24": {"x":54,"y":456,"width":24,"height":24},
18855 "lighthouse-18": {"x":78,"y":456,"width":18,"height":18},
18856 "lighthouse-12": {"x":96,"y":456,"width":12,"height":12},
18857 "clothing-store-24": {"x":108,"y":456,"width":24,"height":24},
18858 "clothing-store-18": {"x":132,"y":456,"width":18,"height":18},
18859 "clothing-store-12": {"x":150,"y":456,"width":12,"height":12},
18860 "polling-place-24": {"x":162,"y":456,"width":24,"height":24},
18861 "polling-place-18": {"x":186,"y":456,"width":18,"height":18},
18862 "polling-place-12": {"x":204,"y":456,"width":12,"height":12},
18863 "playground-24": {"x":216,"y":456,"width":24,"height":24},
18864 "playground-18": {"x":240,"y":456,"width":18,"height":18},
18865 "playground-12": {"x":258,"y":456,"width":12,"height":12},
18866 "entrance-24": {"x":0,"y":480,"width":24,"height":24},
18867 "entrance-18": {"x":24,"y":480,"width":18,"height":18},
18868 "entrance-12": {"x":42,"y":480,"width":12,"height":12},
18869 "heart-24": {"x":54,"y":480,"width":24,"height":24},
18870 "heart-18": {"x":78,"y":480,"width":18,"height":18},
18871 "heart-12": {"x":96,"y":480,"width":12,"height":12},
18872 "london-underground-24": {"x":108,"y":480,"width":24,"height":24},
18873 "london-underground-18": {"x":132,"y":480,"width":18,"height":18},
18874 "london-underground-12": {"x":150,"y":480,"width":12,"height":12},
18875 "minefield-24": {"x":162,"y":480,"width":24,"height":24},
18876 "minefield-18": {"x":186,"y":480,"width":18,"height":18},
18877 "minefield-12": {"x":204,"y":480,"width":12,"height":12},
18878 "rail-underground-24": {"x":216,"y":480,"width":24,"height":24},
18879 "rail-underground-18": {"x":240,"y":480,"width":18,"height":18},
18880 "rail-underground-12": {"x":258,"y":480,"width":12,"height":12},
18881 "rail-above-24": {"x":0,"y":504,"width":24,"height":24},
18882 "rail-above-18": {"x":24,"y":504,"width":18,"height":18},
18883 "rail-above-12": {"x":42,"y":504,"width":12,"height":12},
18884 "camera-24": {"x":54,"y":504,"width":24,"height":24},
18885 "camera-18": {"x":78,"y":504,"width":18,"height":18},
18886 "camera-12": {"x":96,"y":504,"width":12,"height":12},
18887 "laundry-24": {"x":108,"y":504,"width":24,"height":24},
18888 "laundry-18": {"x":132,"y":504,"width":18,"height":18},
18889 "laundry-12": {"x":150,"y":504,"width":12,"height":12},
18890 "car-24": {"x":162,"y":504,"width":24,"height":24},
18891 "car-18": {"x":186,"y":504,"width":18,"height":18},
18892 "car-12": {"x":204,"y":504,"width":12,"height":12},
18893 "suitcase-24": {"x":216,"y":504,"width":24,"height":24},
18894 "suitcase-18": {"x":240,"y":504,"width":18,"height":18},
18895 "suitcase-12": {"x":258,"y":504,"width":12,"height":12},
18896 "hairdresser-24": {"x":0,"y":528,"width":24,"height":24},
18897 "hairdresser-18": {"x":24,"y":528,"width":18,"height":18},
18898 "hairdresser-12": {"x":42,"y":528,"width":12,"height":12},
18899 "chemist-24": {"x":54,"y":528,"width":24,"height":24},
18900 "chemist-18": {"x":78,"y":528,"width":18,"height":18},
18901 "chemist-12": {"x":96,"y":528,"width":12,"height":12},
18902 "mobilephone-24": {"x":108,"y":528,"width":24,"height":24},
18903 "mobilephone-18": {"x":132,"y":528,"width":18,"height":18},
18904 "mobilephone-12": {"x":150,"y":528,"width":12,"height":12},
18905 "scooter-24": {"x":162,"y":528,"width":24,"height":24},
18906 "scooter-18": {"x":186,"y":528,"width":18,"height":18},
18907 "scooter-12": {"x":204,"y":528,"width":12,"height":12},
18908 "gift-24": {"x":216,"y":528,"width":24,"height":24},
18909 "gift-18": {"x":240,"y":528,"width":18,"height":18},
18910 "gift-12": {"x":258,"y":528,"width":12,"height":12},
18911 "ice-cream-24": {"x":0,"y":552,"width":24,"height":24},
18912 "ice-cream-18": {"x":24,"y":552,"width":18,"height":18},
18913 "ice-cream-12": {"x":42,"y":552,"width":12,"height":12}
18916 var amenity = {"fuel":{"76":{"count":314},"Neste":{"count":189},"BP":{"count":2511},"Shell":{"count":8380},"Agip":{"count":2651},"Migrol":{"count":65},"Avia":{"count":897},"Texaco":{"count":680},"Total":{"count":2607},"Statoil":{"count":596},"Esso":{"count":3652},"Jet":{"count":441},"Avanti":{"count":90},"Sainsbury's":{"count":58},"OMV":{"count":701},"Aral":{"count":1339},"Tesco":{"count":197},"JET":{"count":180},"Morrisons":{"count":111},"United":{"count":91},"Canadian Tire":{"count":66},"Mobil":{"count":613},"Caltex":{"count":1001},"Sunoco":{"count":355},"Q8":{"count":1161},"ABC":{"count":79},"ARAL":{"count":375},"CEPSA":{"count":1018},"BFT":{"count":89},"Petron":{"count":878},"Intermarché":{"count":434},"Total Access":{"count":51},"Super U":{"count":124},"Auchan":{"count":53},"Elf":{"count":129},"Carrefour":{"count":205},"Station Service E. Leclerc":{"count":530},"Shell Express":{"count":131},"Hess":{"count":127},"Flying V":{"count":129},"bft":{"count":168},"Gulf":{"count":199},"PTT":{"count":191},"St1":{"count":100},"Teboil":{"count":115},"HEM":{"count":212},"GALP":{"count":626},"OK":{"count":163},"ÖMV":{"count":101},"Tinq":{"count":215},"OKQ8":{"count":186},"Repsol":{"count":424},"Westfalen":{"count":96},"Esso Express":{"count":98},"Raiffeisenbank":{"count":117},"Tamoil":{"count":866},"Engen":{"count":241},"Sasol":{"count":59},"Topaz":{"count":78},"LPG":{"count":174},"Coop":{"count":62},"Orlen":{"count":598},"Oilibya":{"count":68},"Tango":{"count":122},"Star":{"count":319},"Петрол":{"count":84},"Cepsa":{"count":96},"OIL!":{"count":63},"Ultramar":{"count":125},"Irving":{"count":87},"Lukoil":{"count":701},"Petro-Canada":{"count":489},"7-Eleven":{"count":488},"Agrola":{"count":69},"Husky":{"count":126},"Slovnaft":{"count":219},"Sheetz":{"count":134},"Mol":{"count":61},"Petronas":{"count":159},"Газпромнефть":{"count":748},"Лукойл":{"count":1477},"Elan":{"count":112},"Роснефть":{"count":638},"Turmöl":{"count":57},"Neste A24":{"count":55},"Marathon":{"count":189},"Valero":{"count":366},"Eni":{"count":236},"Chevron":{"count":954},"ТНК":{"count":520},"REPSOL":{"count":1603},"MOL":{"count":228},"Bliska":{"count":150},"Api":{"count":302},"Arco":{"count":179},"Pemex":{"count":423},"Exxon":{"count":506},"Coles Express":{"count":115},"Petrom":{"count":259},"PETRONOR":{"count":207},"Rompetrol":{"count":174},"Lotos":{"count":178},"ОМВ":{"count":60},"BR":{"count":129},"Copec":{"count":505},"Petrobras":{"count":270},"Liberty":{"count":55},"IP":{"count":871},"Erg":{"count":596},"Eneos":{"count":97},"Citgo":{"count":279},"Metano":{"count":208},"Сургутнефтегаз":{"count":61},"EKO":{"count":59},"Eko":{"count":58},"Indipend.":{"count":172},"IES":{"count":63},"TotalErg":{"count":89},"Cenex":{"count":115},"ПТК":{"count":82},"HP":{"count":79},"Phillips 66":{"count":216},"CARREFOUR":{"count":74},"ERG":{"count":76},"Speedway":{"count":148},"Benzina":{"count":96},"Татнефть":{"count":264},"Terpel":{"count":259},"WOG":{"count":189},"Seaoil":{"count":54},"АЗС":{"count":1077},"Kwik Trip":{"count":108},"Wawa":{"count":89},"Pertamina":{"count":186},"COSMO":{"count":64},"Z":{"count":76},"Indian Oil":{"count":183},"АГЗС":{"count":494},"INA":{"count":121},"JOMO":{"count":62},"Holiday":{"count":97},"YPF":{"count":70},"IDEMITSU":{"count":87},"ENEOS":{"count":736},"Bharat Petroleum":{"count":64},"CAMPSA":{"count":615},"Casey's General Store":{"count":190},"Башнефть":{"count":60},"Kangaroo":{"count":60},"コスモ石油 (COSMO)":{"count":136},"MEROIL":{"count":77},"1-2-3":{"count":71},"出光":{"count":228,"tags":{"name:en":"IDEMITSU"}},"НК Альянс":{"count":88},"Sinclair":{"count":100},"Conoco":{"count":189},"SPBU":{"count":54},"Макпетрол":{"count":109},"Circle K":{"count":166},"Posto Ipiranga":{"count":70},"Posto Shell":{"count":54},"Phoenix":{"count":144},"Ipiranga":{"count":119},"OKKO":{"count":85},"ОККО":{"count":119},"บางจาก":{"count":60},"QuikTrip":{"count":105},"Stewart's":{"count":63},"Posto BR":{"count":68},"ป ต ท":{"count":152},"ปตท":{"count":88},"ANP":{"count":80},"Kum & Go":{"count":80},"Petrolimex":{"count":55},"Sokimex":{"count":66},"Tela":{"count":154},"Posto":{"count":71},"H-E-B":{"count":182},"Укрнафта":{"count":58},"Татнефтепродукт":{"count":54},"Afriquia":{"count":88},"Murphy USA":{"count":67},"昭和シェル (Showa-shell)":{"count":94},"エネオス":{"count":53},"CNG":{"count":94}},"pub":{"Kings Arms":{"count":67},"The Ship":{"count":89},"The White Horse":{"count":204},"The White Hart":{"count":226},"Royal Oak":{"count":150},"The Red Lion":{"count":233},"The Kings Arms":{"count":58},"The Star":{"count":73},"The Anchor":{"count":64},"The Cross Keys":{"count":55},"The Wheatsheaf":{"count":117},"The Crown Inn":{"count":67},"The Kings Head":{"count":53},"The Castle":{"count":62},"The Railway":{"count":102},"The White Lion":{"count":118},"The Bell":{"count":121},"The Bull":{"count":68},"The Plough":{"count":179},"The George":{"count":110},"The Royal Oak":{"count":209},"The Fox":{"count":74},"Prince of Wales":{"count":77},"The Rising Sun":{"count":71},"The Prince of Wales":{"count":51},"The Crown":{"count":244},"The Chequers":{"count":66},"The Swan":{"count":152},"Rose and Crown":{"count":79},"The Victoria":{"count":67},"New Inn":{"count":90},"Royal Hotel":{"count":57},"Red Lion":{"count":207},"Cross Keys":{"count":61},"The Greyhound":{"count":96},"The Black Horse":{"count":94},"The New Inn":{"count":105},"Kings Head":{"count":59},"The Albion":{"count":51},"The Angel":{"count":52},"The Queens Head":{"count":52},"The Ship Inn":{"count":83},"Rose & Crown":{"count":51},"Queens Head":{"count":52},"Irish Pub":{"count":76}},"fast_food":{"Quick":{"count":484},"McDonald's":{"count":12376,"tags":{"cuisine":"burger"}},"Subway":{"count":5576,"tags":{"cuisine":"sandwich"}},"Burger King":{"count":3734,"tags":{"cuisine":"burger"}},"Ali Baba":{"count":61},"Hungry Jacks":{"count":173,"tags":{"cuisine":"burger"}},"Red Rooster":{"count":148},"KFC":{"count":3198,"tags":{"cuisine":"chicken"}},"Domino's Pizza":{"count":985,"tags":{"cuisine":"pizza"}},"Chowking":{"count":142},"Jollibee":{"count":396},"Hesburger":{"count":102},"肯德基":{"count":86},"Wendy's":{"count":1621,"tags":{"cuisine":"burger"}},"Tim Hortons":{"count":323},"Steers":{"count":151},"Hardee's":{"count":268,"tags":{"cuisine":"burger"}},"Arby's":{"count":782},"A&W":{"count":283},"Dairy Queen":{"count":791},"Hallo Pizza":{"count":76},"Fish & Chips":{"count":93},"Harvey's":{"count":90},"麥當勞":{"count":65},"Pizza Pizza":{"count":215},"Kotipizza":{"count":74},"Jack in the Box":{"count":546,"tags":{"cuisine":"burger"}},"Istanbul":{"count":56},"Kochlöffel":{"count":68},"Döner":{"count":228},"Telepizza":{"count":201},"Sibylla":{"count":61},"Carl's Jr.":{"count":298,"tags":{"cuisine":"burger"}},"Quiznos":{"count":266,"tags":{"cuisine":"sandwich"}},"Wimpy":{"count":141},"Sonic":{"count":566,"tags":{"cuisine":"burger"}},"Taco Bell":{"count":1423,"tags":{"cuisine":"mexican"}},"Pizza Nova":{"count":63},"Papa John's":{"count":304,"tags":{"cuisine":"pizza"}},"Nordsee":{"count":159},"Mr. Sub":{"count":103},"Макдоналдс":{"count":324,"tags":{"name:en":"McDonald's"}},"Asia Imbiss":{"count":111},"Chipotle":{"count":290,"tags":{"cuisine":"mexican"}},"マクドナルド":{"count":692,"tags":{"name:en":"McDonald's","cuisine":"burger"}},"In-N-Out Burger":{"count":65},"Jimmy John's":{"count":141},"Jamba Juice":{"count":68},"Робин Сдобин":{"count":82},"Baskin Robbins":{"count":74},"ケンタッキーフライドチキン":{"count":164,"tags":{"name:en":"KFC","cuisine":"chicken"}},"吉野家":{"count":191},"Taco Time":{"count":88},"松屋":{"count":281,"tags":{"name:en":"Matsuya"}},"Little Caesars":{"count":81},"El Pollo Loco":{"count":63},"Del Taco":{"count":141},"White Castle":{"count":80},"Boston Market":{"count":66},"Chick-fil-A":{"count":257,"tags":{"cuisine":"chicken"}},"Panda Express":{"count":238,"tags":{"cuisine":"chinese"}},"Whataburger":{"count":364},"Taco John's":{"count":78},"Теремок":{"count":68},"Culver's":{"count":425},"Five Guys":{"count":141},"Church's Chicken":{"count":95},"Popeye's":{"count":167,"tags":{"cuisine":"chicken"}},"Long John Silver's":{"count":93},"Pollo Campero":{"count":62},"Zaxby's":{"count":51},"すき家":{"count":276,"tags":{"name:en":"SUKIYA"}},"モスバーガー":{"count":257,"tags":{"name:en":"MOS BURGER"}},"Русский Аппетит":{"count":69},"なか卯":{"count":63}},"restaurant":{"Pizza Hut":{"count":1180,"tags":{"cuisine":"pizza"}},"Little Chef":{"count":64},"Adler":{"count":158},"Zur Krone":{"count":90},"Deutsches Haus":{"count":90},"Krone":{"count":171},"Akropolis":{"count":152},"Schützenhaus":{"count":124},"Kreuz":{"count":74},"Waldschänke":{"count":55},"La Piazza":{"count":69},"Lamm":{"count":66},"Zur Sonne":{"count":73},"Zur Linde":{"count":204},"Poseidon":{"count":110},"Shanghai":{"count":82},"Red Lobster":{"count":235},"Zum Löwen":{"count":84},"Swiss Chalet":{"count":107},"Olympia":{"count":74},"Wagamama":{"count":64},"Frankie & Benny's":{"count":66},"Hooters":{"count":103},"Sternen":{"count":78},"Hirschen":{"count":79},"Denny's":{"count":450},"Athen":{"count":68},"Sonne":{"count":126},"Hirsch":{"count":79},"Ratskeller":{"count":150},"La Cantina":{"count":56},"Gasthaus Krone":{"count":56},"El Greco":{"count":86},"Gasthof zur Post":{"count":79},"Nando's":{"count":246},"Löwen":{"count":112},"La Pataterie":{"count":51},"Bella Napoli":{"count":53},"Pizza Express":{"count":262},"Mandarin":{"count":65},"Hong Kong":{"count":83},"Zizzi":{"count":68},"Cracker Barrel":{"count":183},"Rhodos":{"count":81},"Lindenhof":{"count":79},"Milano":{"count":54},"Dolce Vita":{"count":77},"Kirchenwirt":{"count":81},"Kantine":{"count":52},"Ochsen":{"count":95},"Spur":{"count":62},"Mykonos":{"count":59},"Lotus":{"count":66},"Applebee's":{"count":531},"Flunch":{"count":72},"Zur Post":{"count":116},"China Town":{"count":76},"La Dolce Vita":{"count":73},"Waffle House":{"count":207},"Delphi":{"count":88},"Linde":{"count":103},"Outback Steakhouse":{"count":218},"Dionysos":{"count":69},"Kelsey's":{"count":57},"Boston Pizza":{"count":165},"Bella Italia":{"count":132},"Sizzler":{"count":53},"Grüner Baum":{"count":116},"Taj Mahal":{"count":104},"Rössli":{"count":68},"Wimpy":{"count":51},"Traube":{"count":65},"Adria":{"count":52},"Red Robin":{"count":185},"Roma":{"count":61},"San Marco":{"count":67},"Hellas":{"count":55},"La Perla":{"count":67},"Vips":{"count":53},"Panera Bread":{"count":218},"Da Vinci":{"count":54},"Hippopotamus":{"count":96},"Prezzo":{"count":75},"Courtepaille":{"count":106},"Hard Rock Cafe":{"count":70},"Panorama":{"count":61},"デニーズ":{"count":82},"Sportheim":{"count":65},"餃子の王将":{"count":57},"Bären":{"count":60},"Alte Post":{"count":60},"Pizzeria Roma":{"count":51},"China Garden":{"count":66},"Vapiano":{"count":82},"Mamma Mia":{"count":64},"Schwarzer Adler":{"count":57},"IHOP":{"count":317},"Chili's":{"count":328},"Asia":{"count":51},"Olive Garden":{"count":279},"TGI Friday's":{"count":159},"Friendly's":{"count":78},"Buffalo Grill":{"count":202},"Texas Roadhouse":{"count":110},"ガスト":{"count":230,"tags":{"name:en":"Gusto"}},"Sakura":{"count":75},"Mensa":{"count":99},"The Keg":{"count":53},"サイゼリヤ":{"count":93},"La Strada":{"count":52},"Village Inn":{"count":92},"Buffalo Wild Wings":{"count":176},"Peking":{"count":59},"Boston Market":{"count":61},"Round Table Pizza":{"count":53},"Jimmy John's":{"count":69},"California Pizza Kitchen":{"count":61},"Якитория":{"count":77},"Golden Corral":{"count":101},"Perkins":{"count":105},"Ruby Tuesday":{"count":162},"Shari's":{"count":65},"Bob Evans":{"count":129},"바다횟집 (Bada Fish Restaurant)":{"count":55},"Mang Inasal":{"count":84},"Евразия":{"count":102},"ジョナサン":{"count":59},"Longhorn Steakhouse":{"count":66}},"bank":{"Chase":{"count":721},"Commonwealth Bank":{"count":232},"Citibank":{"count":277},"HSBC":{"count":1102},"Barclays":{"count":965},"Westpac":{"count":208},"NAB":{"count":131},"ANZ":{"count":218},"Lloyds Bank":{"count":547},"Landbank":{"count":81},"Sparkasse":{"count":4555},"UCPB":{"count":92},"PNB":{"count":244},"Metrobank":{"count":269},"BDO":{"count":290},"Volksbank":{"count":2591},"BPI":{"count":415},"Postbank":{"count":443},"NatWest":{"count":628},"Raiffeisenbank":{"count":2119},"Yorkshire Bank":{"count":63},"ABSA":{"count":95},"Standard Bank":{"count":109},"FNB":{"count":97},"Deutsche Bank":{"count":855},"SEB":{"count":133},"Commerzbank":{"count":806},"Targobank":{"count":166},"ABN AMRO":{"count":130},"Handelsbanken":{"count":184},"Swedbank":{"count":223},"Kreissparkasse":{"count":600},"UniCredit Bank":{"count":408},"Monte dei Paschi di Siena":{"count":132},"Caja Rural":{"count":99},"Dresdner Bank":{"count":66},"Sparda-Bank":{"count":320},"VÚB":{"count":107},"Slovenská sporiteľňa":{"count":134},"Bank of Montreal":{"count":118},"KBC":{"count":203},"Royal Bank of Scotland":{"count":111},"TSB":{"count":80},"US Bank":{"count":256},"HypoVereinsbank":{"count":561},"Bank Austria":{"count":176},"ING":{"count":496},"Erste Bank":{"count":180},"CIBC":{"count":326},"Scotiabank":{"count":413},"Caisse d'Épargne":{"count":882},"Santander":{"count":1323},"Bank of Scotland":{"count":89},"TD Canada Trust":{"count":450},"BMO":{"count":169},"Danske Bank":{"count":131},"OTP":{"count":192},"Crédit Agricole":{"count":1239},"LCL":{"count":553},"VR-Bank":{"count":430},"ČSOB":{"count":160},"Česká spořitelna":{"count":212},"BNP":{"count":112},"Royal Bank":{"count":65},"Nationwide":{"count":209},"Halifax":{"count":225},"BAWAG PSK":{"count":102},"National Bank":{"count":84},"Nedbank":{"count":80},"First National Bank":{"count":85},"Nordea":{"count":319},"Rabobank":{"count":609},"Sparkasse KölnBonn":{"count":69},"Tatra banka":{"count":67},"Berliner Sparkasse":{"count":62},"Berliner Volksbank":{"count":77},"Wells Fargo":{"count":874},"Credit Suisse":{"count":71},"Société Générale":{"count":634},"Osuuspankki":{"count":75},"Sparkasse Aachen":{"count":56},"Hamburger Sparkasse":{"count":156},"Cassa di Risparmio del Veneto":{"count":68},"BNP Paribas":{"count":617},"Banque Populaire":{"count":433},"BNP Paribas Fortis":{"count":209},"Banco Popular":{"count":291},"Bancaja":{"count":55},"Banesto":{"count":208},"La Caixa":{"count":583},"Santander Consumer Bank":{"count":88},"BRD":{"count":191},"BCR":{"count":143},"Banca Transilvania":{"count":141},"BW-Bank":{"count":97},"Komerční banka":{"count":132},"Banco Pastor":{"count":64},"Stadtsparkasse":{"count":86},"Ulster Bank":{"count":86},"Sberbank":{"count":58},"CIC":{"count":427},"Bancpost":{"count":56},"Caja Madrid":{"count":115},"Maybank":{"count":94},"中国银行":{"count":85},"Unicredit Banca":{"count":243},"Crédit Mutuel":{"count":690},"BBVA":{"count":647},"Intesa San Paolo":{"count":69},"TD Bank":{"count":206},"Belfius":{"count":231},"Bank of America":{"count":924},"RBC":{"count":230},"Alpha Bank":{"count":123},"Сбербанк":{"count":4794},"Россельхозбанк":{"count":201},"Crédit du Nord":{"count":96},"BancoEstado":{"count":80},"Millennium Bank":{"count":414},"State Bank of India":{"count":151},"Беларусбанк":{"count":242},"ING Bank Śląski":{"count":67},"Caixa Geral de Depósitos":{"count":129},"Kreissparkasse Köln":{"count":65},"Banco BCI":{"count":51},"Banco de Chile":{"count":98},"ВТБ24":{"count":326},"UBS":{"count":134},"PKO BP":{"count":265},"Chinabank":{"count":55},"PSBank":{"count":59},"Union Bank":{"count":124},"China Bank":{"count":66},"RCBC":{"count":122},"Unicaja":{"count":83},"BBK":{"count":79},"Ibercaja":{"count":69},"RBS":{"count":143},"Commercial Bank of Ceylon PLC":{"count":79},"Bank of Ireland":{"count":109},"BNL":{"count":87},"Banco Santander":{"count":138},"Banco Itaú":{"count":111},"AIB":{"count":72},"BZ WBK":{"count":77},"Banco do Brasil":{"count":557},"Caixa Econômica Federal":{"count":184},"Fifth Third Bank":{"count":84},"Banca Popolare di Vicenza":{"count":81},"Wachovia":{"count":58},"OLB":{"count":53},"みずほ銀行":{"count":78},"BES":{"count":72},"ICICI Bank":{"count":91},"HDFC Bank":{"count":91},"La Banque Postale":{"count":67},"Pekao SA":{"count":56},"Oberbank":{"count":90},"Bradesco":{"count":295},"Oldenburgische Landesbank":{"count":56},"Bendigo Bank":{"count":93},"Argenta":{"count":86},"AXA":{"count":68},"Axis Bank":{"count":61},"Banco Nación":{"count":67},"GE Money Bank":{"count":72},"Альфа-Банк":{"count":185},"Белагропромбанк":{"count":70},"Caja Círculo":{"count":65},"Banco Galicia":{"count":51},"Eurobank":{"count":97},"Banca Intesa":{"count":62},"Canara Bank":{"count":92},"Cajamar":{"count":77},"Banamex":{"count":149},"Crédit Mutuel de Bretagne":{"count":335},"Davivienda":{"count":83},"Bank Spółdzielczy":{"count":159},"Credit Agricole":{"count":157},"Bankinter":{"count":59},"Banque Nationale":{"count":63},"Bank of the West":{"count":96},"Key Bank":{"count":155},"Western Union":{"count":88},"Citizens Bank":{"count":115},"ПриватБанк":{"count":513},"Security Bank":{"count":78},"Millenium":{"count":60},"Bankia":{"count":149},"三菱東京UFJ銀行":{"count":159},"Caixa":{"count":117},"Banco de Costa Rica":{"count":63},"SunTrust Bank":{"count":73},"Itaú":{"count":338},"PBZ":{"count":52},"中国工商银行":{"count":51},"Bancolombia":{"count":89},"Райффайзен Банк Аваль":{"count":64},"Bancomer":{"count":115},"Banorte":{"count":80},"Alior Bank":{"count":81},"BOC":{"count":51},"Банк Москвы":{"count":118},"ВТБ":{"count":59},"Getin Bank":{"count":55},"Caja Duero":{"count":57},"Regions Bank":{"count":62},"Росбанк":{"count":177},"Banco Estado":{"count":72},"BCI":{"count":68},"SunTrust":{"count":68},"PNC Bank":{"count":254},"신한은행":{"count":217,"tags":{"name:en":"Sinhan Bank"}},"우리은행":{"count":291,"tags":{"name:en":"Uri Bank"}},"국민은행":{"count":165,"tags":{"name:en":"Gungmin Bank"}},"중소기업은행":{"count":52,"tags":{"name:en":"Industrial Bank of Korea"}},"광주은행":{"count":51,"tags":{"name:en":"Gwangju Bank"}},"Газпромбанк":{"count":100},"M&T Bank":{"count":92},"Caja de Burgos":{"count":51},"Santander Totta":{"count":69},"УкрСиббанк":{"count":192},"Ощадбанк":{"count":364},"Уралсиб":{"count":85},"りそな銀行":{"count":225,"tags":{"name:en":"Mizuho Bank"}},"Ecobank":{"count":66},"Cajero Automatico Bancared":{"count":145},"Промсвязьбанк":{"count":93},"三井住友銀行":{"count":129},"Banco Provincia":{"count":67},"BB&T":{"count":147},"Возрождение":{"count":59},"Capital One":{"count":59},"横浜銀行":{"count":51},"Bank Mandiri":{"count":62},"Banco de la Nación":{"count":92},"Banco G&T Continental":{"count":62},"Peoples Bank":{"count":60},"工商银行":{"count":51},"Совкомбанк":{"count":55},"Provincial":{"count":56},"Banco de Desarrollo Banrural":{"count":73},"Banco Bradesco":{"count":65},"Bicentenario":{"count":182},"ლიბერთი ბანკი":{"count":54,"tags":{"name:en":"Liberty Bank"}},"Banesco":{"count":108},"Mercantil":{"count":75},"Bank BRI":{"count":53},"Del Tesoro":{"count":91},"하나은행":{"count":77},"CityCommerce Bank":{"count":71},"De Venezuela":{"count":117}},"car_rental":{"Europcar":{"count":291},"Budget":{"count":92},"Sixt":{"count":161},"Avis":{"count":282},"Hertz":{"count":293},"Enterprise":{"count":199},"stadtmobil CarSharing-Station":{"count":148}},"pharmacy":{"Rowlands Pharmacy":{"count":71},"Boots":{"count":840},"Marien-Apotheke":{"count":314},"Mercury Drug":{"count":426},"Löwen-Apotheke":{"count":356},"Superdrug":{"count":117},"Sonnen-Apotheke":{"count":311},"Rathaus-Apotheke":{"count":132},"Engel-Apotheke":{"count":123},"Hirsch-Apotheke":{"count":83},"Stern-Apotheke":{"count":67},"Lloyds Pharmacy":{"count":295},"Rosen-Apotheke":{"count":208},"Stadt-Apotheke":{"count":302},"Markt-Apotheke":{"count":164},"Аптека":{"count":1989},"Pharmasave":{"count":64},"Brunnen-Apotheke":{"count":53},"Shoppers Drug Mart":{"count":430},"Apotheke am Markt":{"count":60},"Alte Apotheke":{"count":88},"Neue Apotheke":{"count":109},"Gintarinė vaistinė":{"count":101},"Rats-Apotheke":{"count":84},"Adler Apotheke":{"count":313},"Pharmacie Centrale":{"count":64},"Walgreens":{"count":1619},"Rite Aid":{"count":745},"Apotheke":{"count":165},"Linden-Apotheke":{"count":211},"Bahnhof-Apotheke":{"count":66},"Burg-Apotheke":{"count":55},"Jean Coutu":{"count":62},"Pharmaprix":{"count":60},"Farmacias Ahumada":{"count":104},"Farmacia Comunale":{"count":113},"Farmacias Cruz Verde":{"count":86},"Cruz Verde":{"count":99},"Hubertus Apotheke":{"count":52},"CVS":{"count":1560},"Farmacias SalcoBrand":{"count":133},"Фармация":{"count":120},"Bären-Apotheke":{"count":74},"Clicks":{"count":113},"セイジョー":{"count":53},"マツモトキヨシ":{"count":115},"Dr. Max":{"count":51},"Вита":{"count":106},"Радуга":{"count":70},"サンドラッグ":{"count":61},"Apteka":{"count":366},"Первая помощь":{"count":74},"Ригла":{"count":113},"Имплозия":{"count":63},"Kinney Drugs":{"count":68},"Классика":{"count":67},"Ljekarna":{"count":53},"SalcoBrand":{"count":88},"Аптека 36,6":{"count":224},"Фармакор":{"count":75},"スギ薬局":{"count":84},"Аптечный пункт":{"count":148},"Невис":{"count":60},"トモズ (Tomod's)":{"count":83},"Eurovaistinė":{"count":65},"Farmacity":{"count":68},"аптека":{"count":96},"The Generics Pharmacy":{"count":95},"Farmatodo":{"count":123},"Duane Reade":{"count":61},"H-E-B":{"count":262},"Фармленд":{"count":82},"ドラッグてらしま (Drug Terashima)":{"count":96},"Арніка":{"count":125},"ავერსი (Aversi)":{"count":62},"Farmahorro":{"count":58}},"cafe":{"Starbucks":{"count":4238,"tags":{"cuisine":"coffee_shop"}},"Cafeteria":{"count":115},"Costa":{"count":618},"Caffè Nero":{"count":169},"Кафе":{"count":226},"Café Central":{"count":61},"Second Cup":{"count":193},"Dunkin Donuts":{"count":428,"tags":{"cuisine":"donut"}},"Espresso House":{"count":53},"Segafredo":{"count":69},"Coffee Time":{"count":94},"Cafe Coffee Day":{"count":120},"Eiscafe Venezia":{"count":180},"スターバックス":{"count":251,"tags":{"name:en":"Starbucks"}},"Шоколадница":{"count":145},"Pret A Manger":{"count":119},"Столовая":{"count":391},"Jamba Juice":{"count":53},"ドトール":{"count":164,"tags":{"name:en":"DOUTOR"}},"Tchibo":{"count":100},"Кофе Хауз":{"count":104},"Caribou Coffee":{"count":100},"Уют":{"count":51},"Шашлычная":{"count":58},"คาเฟ่ อเมซอน":{"count":62},"Traveler's Coffee":{"count":60},"カフェ・ド・クリエ":{"count":67,"tags":{"name:en":"Cafe de CRIE"}},"Cafe Amazon":{"count":65}}};
18917 var shop = {"supermarket":{"Budgens":{"count":88},"Morrisons":{"count":411},"Interspar":{"count":142},"Merkur":{"count":107},"Sainsbury's":{"count":547},"Lidl":{"count":7130},"Edeka":{"count":2293},"Coles":{"count":400},"Iceland":{"count":315},"Coop":{"count":2100},"Tesco":{"count":1297},"Woolworths":{"count":541},"Zielpunkt":{"count":239},"Nahkauf":{"count":170},"Billa":{"count":1432},"Kaufland":{"count":1004},"Plus":{"count":120},"ALDI":{"count":5172},"Checkers":{"count":128},"Tesco Metro":{"count":137},"NP":{"count":153},"Penny":{"count":1759},"Norma":{"count":1068},"Asda":{"count":225},"Netto":{"count":4379},"Rewe":{"count":2645},"Aldi Süd":{"count":594},"Real":{"count":246},"Tesco Express":{"count":406},"King Soopers":{"count":72},"Kiwi":{"count":167},"Pick n Pay":{"count":241},"ICA":{"count":192},"Tengelmann":{"count":188},"Carrefour":{"count":1640},"Waitrose":{"count":258},"Spar":{"count":2386},"Hofer":{"count":442},"M-Preis":{"count":76},"tegut":{"count":210},"Sainsbury's Local":{"count":118},"E-Center":{"count":66},"Aldi Nord":{"count":210},"nahkauf":{"count":84},"Meijer":{"count":76},"Safeway":{"count":410},"Costco":{"count":152},"Albert":{"count":185},"Jumbo":{"count":194},"Shoprite":{"count":244},"MPreis":{"count":54},"Penny Market":{"count":429},"Tesco Extra":{"count":123},"Albert Heijn":{"count":476},"IGA":{"count":363},"Super U":{"count":488},"Metro":{"count":260},"Neukauf":{"count":77},"Migros":{"count":459},"Marktkauf":{"count":121},"Delikatesy Centrum":{"count":59},"C1000":{"count":307},"Hoogvliet":{"count":53},"Food Basics":{"count":75},"Casino":{"count":264},"Penny Markt":{"count":466},"Giant":{"count":191},"COOP Jednota":{"count":73},"Rema 1000":{"count":368},"Kaufpark":{"count":96},"ALDI SÜD":{"count":113},"Simply Market":{"count":330},"Konzum":{"count":230},"Carrefour Express":{"count":353},"Eurospar":{"count":270},"Mercator":{"count":125},"Famila":{"count":130},"Hemköp":{"count":82},"real,-":{"count":81},"Markant":{"count":88},"Volg":{"count":135},"Leader Price":{"count":267},"Treff 3000":{"count":94},"SuperBrugsen":{"count":67},"Kaiser's":{"count":256},"K+K":{"count":106},"Unimarkt":{"count":86},"Carrefour City":{"count":126},"Sobeys":{"count":122},"S-Market":{"count":109},"Combi":{"count":55},"Denner":{"count":276},"Konsum":{"count":133},"Franprix":{"count":312},"Monoprix":{"count":198},"Diska":{"count":69},"PENNY":{"count":79},"Dia":{"count":835},"Giant Eagle":{"count":85},"NORMA":{"count":115},"AD Delhaize":{"count":63},"Auchan":{"count":152},"Mercadona":{"count":769},"Consum":{"count":130},"Carrefour Market":{"count":80},"Whole Foods":{"count":210,"tags":{"shop":"supermarket"}},"Pam":{"count":56},"sky":{"count":105},"Despar":{"count":146},"Eroski":{"count":208},"Costcutter":{"count":63},"Maxi":{"count":108},"Colruyt":{"count":180},"The Co-operative":{"count":64},"Intermarché":{"count":1210},"Delhaize":{"count":207},"CBA":{"count":176},"Shopi":{"count":53},"Walmart":{"count":644},"Kroger":{"count":317},"Albertsons":{"count":242},"Trader Joe's":{"count":235},"Feneberg":{"count":58},"denn's Biomarkt":{"count":52},"dm":{"count":114},"Kvickly":{"count":55},"Makro":{"count":140},"Dico":{"count":53},"Nah & Frisch":{"count":73},"Champion":{"count":59},"ICA Supermarket":{"count":51},"Fakta":{"count":235},"Магнит":{"count":1760},"Caprabo":{"count":103},"Famiglia Cooperativa":{"count":64},"Народная 7Я семьЯ":{"count":154},"Esselunga":{"count":85},"Maxima":{"count":102},"Petit Casino":{"count":111},"Wasgau":{"count":60},"Pingo Doce":{"count":253},"Match":{"count":140},"Profi":{"count":60},"Lider":{"count":65},"Unimarc":{"count":177},"The Co-operative Food":{"count":190},"Santa Isabel":{"count":128},"Седьмой континент":{"count":79},"HIT":{"count":59},"Rimi":{"count":106},"Conad":{"count":304},"Фуршет":{"count":76},"Willys":{"count":56},"Farmfoods":{"count":64},"U Express":{"count":51},"Фора":{"count":52},"Dunnes Stores":{"count":73},"Сільпо":{"count":125},"マルエツ":{"count":59},"Piggly Wiggly":{"count":57},"Crai":{"count":54},"El Árbol":{"count":73},"Centre Commercial E. Leclerc":{"count":549},"Foodland":{"count":100},"Super Brugsen":{"count":67},"Дикси":{"count":683},"Пятёрочка":{"count":1344},"Publix":{"count":339},"Føtex":{"count":66},"coop":{"count":73},"Fressnapf":{"count":69},"Coop Konsum":{"count":79},"Carrefour Contact":{"count":83},"No Frills":{"count":105},"Plodine":{"count":52},"ADEG":{"count":68},"Minipreço":{"count":111},"Biedronka":{"count":1335},"Eurospin":{"count":155},"Семья":{"count":62},"Gadis":{"count":53},"Евроопт":{"count":68},"Centra":{"count":51},"Квартал":{"count":82},"New World":{"count":69},"Countdown":{"count":95},"Reliance Fresh":{"count":61},"Stokrotka":{"count":98},"Coop Jednota":{"count":74},"Fred Meyer":{"count":64},"Irma":{"count":58},"Continente":{"count":75},"Price Chopper":{"count":99},"Game":{"count":52},"Soriana":{"count":93},"Alimerka":{"count":64},"Piotr i Paweł":{"count":53},"Перекресток":{"count":312},"Maxima X":{"count":117},"Карусель":{"count":55},"ALDI Nord":{"count":51},"Condis":{"count":67},"Sam's Club":{"count":138},"Копейка":{"count":87},"Géant Casino":{"count":54},"ASDA":{"count":180},"Intermarche":{"count":115},"Stop & Shop":{"count":66},"Food Lion":{"count":216},"Harris Teeter":{"count":92},"Foodworks":{"count":62},"Polo Market":{"count":86},"Лента":{"count":51},"西友 (SEIYU)":{"count":58},"H-E-B":{"count":293},"Атак":{"count":53},"Полушка":{"count":139},"Extra":{"count":82},"Lewiatan":{"count":94},"Sigma":{"count":51},"АТБ":{"count":322},"Społem":{"count":55},"Bodega Aurrera":{"count":82},"Tesco Lotus":{"count":77},"Мария-Ра":{"count":108},"Магнолия":{"count":72},"Магазин":{"count":120},"Монетка":{"count":174},"Hy-Vee":{"count":75},"Walmart Supercenter":{"count":133},"Hannaford":{"count":57},"Wegmans":{"count":83},"業務スーパー":{"count":61},"Norfa XL":{"count":55},"ヨークマート (YorkMart)":{"count":64},"Leclerc Drive":{"count":76}},"electronics":{"Media Markt":{"count":285},"Maplin":{"count":65},"Best Buy":{"count":345},"Future Shop":{"count":73},"Saturn":{"count":134},"Currys":{"count":80},"Radio Shack":{"count":269},"Euronics":{"count":115},"Expert":{"count":123},"Эльдорадо":{"count":184},"Darty":{"count":74},"М.Видео":{"count":89},"ヤマダ電機":{"count":51}},"convenience":{"Shell":{"count":255},"Spar":{"count":1119},"McColl's":{"count":100},"Tesco Express":{"count":426},"Sainsbury's Local":{"count":104},"Aral":{"count":56},"One Stop":{"count":146},"The Co-operative Food":{"count":115},"Londis":{"count":352},"7-Eleven":{"count":4440},"CBA":{"count":135},"Coop":{"count":678},"Sale":{"count":80},"Statoil":{"count":69},"Sheetz":{"count":54},"Konzum":{"count":173},"Siwa":{"count":216},"Mercator":{"count":57},"Esso":{"count":67},"COOP Jednota":{"count":181},"Mac's":{"count":152},"Alepa":{"count":62},"Hasty Market":{"count":54},"K-Market":{"count":54},"Costcutter":{"count":292},"Valintatalo":{"count":62},"Casino":{"count":90},"Franprix":{"count":61},"Circle K":{"count":289},"セブンイレブン":{"count":3011,"tags":{"name:en":"7-Eleven"}},"ローソン":{"count":1596,"tags":{"name:en":"LAWSON"}},"BP":{"count":163},"Tesco":{"count":55},"Petit Casino":{"count":233},"Volg":{"count":116},"Mace":{"count":115},"Mini Market":{"count":272},"Nisa Local":{"count":77},"Dorfladen":{"count":75},"Продукты":{"count":4285},"Mini Stop":{"count":228},"LAWSON":{"count":419},"デイリーヤマザキ":{"count":141},"Biedronka":{"count":83},"Надежда":{"count":56},"Mobil":{"count":66},"Nisa":{"count":51},"Premier":{"count":129},"ABC":{"count":152},"ミニストップ":{"count":316,"tags":{"name:en":"MINISTOP"}},"サンクス":{"count":560,"tags":{"name:en":"sunkus"}},"スリーエフ":{"count":88},"8 à Huit":{"count":61},"Tchibo":{"count":56},"Żabka":{"count":546},"Almacen":{"count":229},"Vival":{"count":194},"FamilyMart":{"count":529},"ファミリーマート":{"count":1608,"tags":{"name:en":"FamilyMart"}},"Carrefour City":{"count":57},"Sunkus":{"count":62},"Casey's General Store":{"count":95},"セブンイレブン(Seven-Eleven)":{"count":65},"Jednota":{"count":58},"Магазин":{"count":915},"Гастроном":{"count":152},"Centra":{"count":111},"Магнит":{"count":701},"サークルK":{"count":538,"tags":{"name:en":"Circle K"}},"Wawa":{"count":135},"Proxi":{"count":123},"Универсам":{"count":78},"Перекресток":{"count":51},"Groszek":{"count":65},"Select":{"count":62},"Večerka":{"count":51},"Potraviny":{"count":249},"Смак":{"count":78},"Эконом":{"count":55},"Березка":{"count":77},"Społem":{"count":93},"Carrefour Express":{"count":84},"Cumberland Farms":{"count":63},"Chevron":{"count":59},"Coop Jednota":{"count":66},"Tesco Lotus Express":{"count":67},"Kiosk":{"count":55},"Sklep spożywczy":{"count":130},"24 часа":{"count":58},"Минимаркет":{"count":102},"Oxxo":{"count":669},"Пятёрочка":{"count":398},"abc":{"count":74},"7/11":{"count":51},"Stewart's":{"count":255},"Продукти":{"count":171},"ローソンストア100 (LAWSON STORE 100)":{"count":85},"Дикси":{"count":119},"Радуга":{"count":86},"ローソンストア100":{"count":76},"เซเว่นอีเลฟเว่น":{"count":185},"Delikatesy Centrum":{"count":53},"Citgo":{"count":62},"Фортуна":{"count":51},"Kum & Go":{"count":59},"Мария-Ра":{"count":76},"Picard":{"count":57},"Four Square":{"count":52},"Визит":{"count":57},"Авоська":{"count":55},"Dollar General":{"count":127},"Studenac":{"count":76},"Central Convenience Store":{"count":55},"Монетка":{"count":62},"продукты":{"count":114},"Теремок":{"count":56},"Kwik Trip":{"count":69},"Кулинария":{"count":55},"全家":{"count":90},"Мечта":{"count":54},"Epicerie":{"count":102},"Кировский":{"count":67},"Food Mart":{"count":117},"Delikatesy":{"count":81},"ポプラ":{"count":54},"Lewiatan":{"count":135},"Продуктовый магазин":{"count":149},"Продуктовый":{"count":84},"セイコーマート (Seicomart)":{"count":72},"Виктория":{"count":70},"Весна":{"count":57},"Mini Market Non-Stop":{"count":60},"QuikTrip":{"count":75},"Копеечка":{"count":51},"Royal Farms":{"count":51},"Alfamart":{"count":103},"Indomaret":{"count":141},"магазин":{"count":171},"全家便利商店":{"count":156},"Boutique":{"count":59},"მარკეტი (Market)":{"count":144},"Stores":{"count":61}},"chemist":{"dm":{"count":939},"Müller":{"count":212},"Schlecker":{"count":187},"Etos":{"count":467},"Bipa":{"count":289},"Rossmann":{"count":1669},"DM Drogeriemarkt":{"count":55},"Ihr Platz":{"count":73},"Douglas":{"count":62},"Kruidvat":{"count":123}},"car_repair":{"Peugeot":{"count":83},"Kwik Fit":{"count":128},"ATU":{"count":261},"Midas":{"count":202},"Feu Vert":{"count":113},"Norauto":{"count":152},"Speedy":{"count":115},"Автозапчасти":{"count":212},"Renault":{"count":171},"Pit Stop":{"count":58},"Jiffy Lube":{"count":198},"Шиномонтаж":{"count":1157},"СТО":{"count":395},"O'Reilly Auto Parts":{"count":81},"Carglass":{"count":112},"шиномонтаж":{"count":62},"Citroen":{"count":51},"Euromaster":{"count":87},"Firestone":{"count":88},"Автосервис":{"count":361},"Advance Auto Parts":{"count":52},"Roady":{"count":56}},"furniture":{"IKEA":{"count":169},"Jysk":{"count":109},"Roller":{"count":78},"Dänisches Bettenlager":{"count":309},"Conforama":{"count":99},"Matratzen Concord":{"count":52},"Мебель":{"count":210},"But":{"count":63}},"doityourself":{"Hornbach":{"count":123},"B&Q":{"count":225},"Hubo":{"count":77},"Mr Bricolage":{"count":88},"Gamma":{"count":111},"OBI":{"count":422},"Lowes":{"count":1152},"Wickes":{"count":123},"Hagebau":{"count":59},"Max Bahr":{"count":79},"Castorama":{"count":153},"Rona":{"count":61},"Home Depot":{"count":865},"Toom Baumarkt":{"count":71},"Homebase":{"count":225},"Baumax":{"count":95},"Lagerhaus":{"count":79},"Bauhaus":{"count":186},"Canadian Tire":{"count":97},"Leroy Merlin":{"count":209},"Hellweg":{"count":58},"Brico":{"count":98},"Bricomarché":{"count":235},"Toom":{"count":67},"Hagebaumarkt":{"count":107},"Praktiker":{"count":122},"Menards":{"count":70},"Weldom":{"count":73},"Bunnings Warehouse":{"count":91},"Ace Hardware":{"count":147},"Home Hardware":{"count":72},"Хозтовары":{"count":86},"Стройматериалы":{"count":197},"Bricorama":{"count":60},"Point P":{"count":59}},"stationery":{"Staples":{"count":299},"McPaper":{"count":83},"Office Depot":{"count":98},"Канцтовары":{"count":63}},"car":{"Skoda":{"count":97},"BMW":{"count":149},"Citroen":{"count":277},"Renault":{"count":382},"Mercedes-Benz":{"count":235},"Volvo":{"count":96},"Ford":{"count":239},"Volkswagen":{"count":217},"Mazda":{"count":105},"Mitsubishi":{"count":73},"Fiat":{"count":93},"Автозапчасти":{"count":277},"Opel":{"count":165},"Audi":{"count":121},"Toyota":{"count":271},"Nissan":{"count":189},"Suzuki":{"count":75},"Honda":{"count":157},"Peugeot":{"count":308},"Шиномонтаж":{"count":259},"Hyundai":{"count":166},"Subaru":{"count":58},"Chevrolet":{"count":86},"Автомагазин":{"count":72}},"clothes":{"Matalan":{"count":90},"KiK":{"count":1219},"H&M":{"count":658},"Urban Outfitters":{"count":63},"Vögele":{"count":132},"Zeeman":{"count":121},"Takko":{"count":515},"Adler":{"count":55},"C&A":{"count":506},"Zara":{"count":217},"Vero Moda":{"count":95},"NKD":{"count":486},"Ernsting's family":{"count":312},"Winners":{"count":65},"River Island":{"count":59},"Next":{"count":176},"Gap":{"count":81},"Adidas":{"count":92},"Woolworths":{"count":117},"Mr Price":{"count":88},"Jet":{"count":61},"Pep":{"count":134},"Edgars":{"count":110},"Ackermans":{"count":91},"Truworths":{"count":65},"Ross":{"count":93},"Burton":{"count":51},"Dorothy Perkins":{"count":53},"Deichmann":{"count":61},"Lindex":{"count":73},"s.Oliver":{"count":56},"Cecil":{"count":51},"Dress Barn":{"count":52},"Old Navy":{"count":174},"Jack & Jones":{"count":52},"Pimkie":{"count":73},"Esprit":{"count":231},"Primark":{"count":92},"Bonita":{"count":155},"Mexx":{"count":67},"Gerry Weber":{"count":71},"Tally Weijl":{"count":70},"Mango":{"count":133},"TK Maxx":{"count":84},"Benetton":{"count":101},"Ulla Popken":{"count":61},"AWG":{"count":66},"Tommy Hilfiger":{"count":75},"New Yorker":{"count":180},"Orsay":{"count":73},"Jeans Fritz":{"count":51},"Charles Vögele":{"count":69},"New Look":{"count":126},"Lacoste":{"count":78},"Etam":{"count":53},"Kiabi":{"count":148},"Jack Wolfskin":{"count":60},"American Apparel":{"count":57},"Men's Wearhouse":{"count":54},"Intimissimi":{"count":52},"United Colors of Benetton":{"count":96},"Jules":{"count":63},"Second Hand":{"count":53},"AOKI":{"count":57},"Calzedonia":{"count":68},"洋服の青山":{"count":100},"Levi's":{"count":63},"Celio":{"count":74},"TJ Maxx":{"count":57},"Promod":{"count":82},"Street One":{"count":72},"ユニクロ":{"count":59},"Banana Republic":{"count":57},"Одежда":{"count":75},"Marshalls":{"count":56},"La Halle":{"count":62},"Peacocks":{"count":89},"しまむら":{"count":60}},"books":{"Bruna":{"count":58},"Waterstones":{"count":90},"Libro":{"count":57},"Barnes & Noble":{"count":267},"Weltbild":{"count":74},"Thalia":{"count":121},"Книги":{"count":112}},"department_store":{"Debenhams":{"count":67},"Canadian Tire":{"count":75},"Karstadt":{"count":64},"Walmart":{"count":517},"Kmart":{"count":143},"Target":{"count":574},"Galeria Kaufhof":{"count":61},"Marks & Spencer":{"count":66},"Big W":{"count":57},"Woolworth":{"count":78},"Универмаг":{"count":72},"Sears":{"count":235},"Walmart Supercenter":{"count":101},"Kohl's":{"count":153},"Macy's":{"count":147},"Sam's Club":{"count":54},"JCPenney":{"count":66}},"alcohol":{"Alko":{"count":145},"The Beer Store":{"count":150},"Systembolaget":{"count":210},"LCBO":{"count":239},"Ароматный мир":{"count":62},"Bargain Booze":{"count":62},"Nicolas":{"count":119},"BWS":{"count":70},"Botilleria":{"count":77},"SAQ":{"count":72},"Gall & Gall":{"count":512},"Живое пиво":{"count":70}},"bakery":{"Kamps":{"count":252},"Banette":{"count":52},"Bäckerei Schmidt":{"count":57},"Anker":{"count":73},"Hofpfisterei":{"count":111},"Greggs":{"count":276},"Oebel":{"count":57},"Boulangerie":{"count":266},"Stadtbäckerei":{"count":57},"Steinecke":{"count":145},"Ihle":{"count":76},"Goldilocks":{"count":59},"Dat Backhus":{"count":67},"K&U":{"count":61},"Der Beck":{"count":96},"Thürmann":{"count":54},"Backwerk":{"count":95},"Schäfer's":{"count":51},"Panaderia":{"count":168},"Goeken backen":{"count":51},"Stadtbäckerei Junge":{"count":51},"Boulangerie Patisserie":{"count":119},"Paul":{"count":81},"Хлеб":{"count":89},"Пекарня":{"count":52},"Кулиничи":{"count":51}},"sports":{"Sports Direct":{"count":57},"Decathlon":{"count":309},"Intersport":{"count":283},"Sports Authority":{"count":75},"Спортмастер":{"count":87},"Sport 2000":{"count":90},"Dick's Sporting Goods":{"count":77}},"variety_store":{"Tedi":{"count":157},"Dollarama":{"count":103},"Family Dollar":{"count":61},"Dollar Tree":{"count":110},"Dollar General":{"count":80}},"pet":{"Fressnapf":{"count":318},"PetSmart":{"count":177},"Das Futterhaus":{"count":69},"Pets at Home":{"count":62},"Petco":{"count":101},"Зоомагазин":{"count":100}},"shoes":{"Deichmann":{"count":622},"Reno":{"count":183},"Ecco":{"count":55},"Clarks":{"count":109},"La Halle aux Chaussures":{"count":69},"Brantano":{"count":71},"Geox":{"count":51},"Salamander":{"count":51},"Обувь":{"count":100},"Payless Shoe Source":{"count":67},"Famous Footwear":{"count":59},"Quick Schuh":{"count":72},"Shoe Zone":{"count":55},"Foot Locker":{"count":82},"Bata":{"count":101},"ЦентрОбувь":{"count":51}},"toys":{"La Grande Récré":{"count":56},"Toys R Us":{"count":151,"tags":{"shop":"toys"}},"Intertoys":{"count":57},"Детский мир":{"count":86},"Игрушки":{"count":58}},"travel_agency":{"Flight Centre":{"count":92},"Thomas Cook":{"count":119}},"jewelry":{"Bijou Brigitte":{"count":57},"Christ":{"count":57},"Swarovski":{"count":74}},"optician":{"Fielmann":{"count":232},"Apollo Optik":{"count":150},"Vision Express":{"count":58},"Оптика":{"count":182},"Optic 2000":{"count":98},"Alain Afflelou":{"count":73},"Specsavers":{"count":124},"Krys":{"count":77},"Atol":{"count":55}},"video":{"Blockbuster":{"count":184},"World of Video":{"count":64}},"mobile_phone":{"Билайн":{"count":128},"ソフトバンクショップ (SoftBank shop)":{"count":255},"Vodafone":{"count":355},"O2":{"count":208},"Carphone Warehouse":{"count":127},"Orange":{"count":246},"Verizon Wireless":{"count":125},"Sprint":{"count":109},"T-Mobile":{"count":175},"МТС":{"count":352},"Евросеть":{"count":506},"Bell":{"count":190},"The Phone House":{"count":83},"SFR":{"count":71},"Связной":{"count":439},"Мегафон":{"count":251},"AT&T":{"count":124},"ドコモショップ (docomo shop)":{"count":114},"au":{"count":65},"Movistar":{"count":77},"Bitė":{"count":72}},"hifi":{},"computer":{"PC World":{"count":55},"DNS":{"count":128}},"hairdresser":{"Klier":{"count":119},"Supercuts":{"count":106},"Hairkiller":{"count":51},"Great Clips":{"count":182},"Парикмахерская":{"count":510},"Стиль":{"count":51},"Franck Provost":{"count":70},"Салон красоты":{"count":70}},"hardware":{"1000 мелочей":{"count":61},"Хозтовары":{"count":151},"Стройматериалы":{"count":54}},"motorcycle":{"Yamaha":{"count":67},"Honda":{"count":69}}};
18918 var dataSuggestions = {
18923 var dataAddressFormats = [{"format":[["housenumber","street"],["city","postcode"]]},{"countryCodes":["gb"],"format":[["housename"],["housenumber","street"],["city","postcode"]]},{"countryCodes":["ie"],"format":[["housename"],["housenumber","street"],["city"],["postcode"]]},{"countryCodes":["ad","at","ba","be","ch","cz","de","dk","es","fi","gr","hr","is","it","li","nl","no","pl","pt","se","si","sk","sm","va"],"format":[["street","housenumber"],["postcode","city"]]},{"countryCodes":["fr","lu","mo"],"format":[["housenumber","street"],["postcode","city"]]},{"countryCodes":["br"],"format":[["street"],["housenumber","suburb"],["city","postcode"]]},{"countryCodes":["vn"],"format":[["housenumber","street"],["subdistrict"],["district"],["city"],["province","postcode"]]},{"countryCodes":["us"],"format":[["housenumber","street"],["city","state","postcode"]]},{"countryCodes":["ca"],"format":[["housenumber","street"],["city","province","postcode"]]},{"countryCodes":["tw"],"format":[["postcode","city","district"],["place","street"],["housenumber","floor"]]}];
18925 var dataDeprecated = [{"old":{"amenity":"firepit"},"replace":{"leisure":"firepit"}},{"old":{"barrier":"wire_fence"},"replace":{"barrier":"fence","fence_type":"chain"}},{"old":{"barrier":"wood_fence"},"replace":{"barrier":"fence","fence_type":"wood"}},{"old":{"highway":"ford"},"replace":{"ford":"yes"}},{"old":{"highway":"stile"},"replace":{"barrier":"stile"}},{"old":{"highway":"incline"},"replace":{"highway":"road","incline":"up"}},{"old":{"highway":"incline_steep"},"replace":{"highway":"road","incline":"up"}},{"old":{"highway":"unsurfaced"},"replace":{"highway":"road","incline":"unpaved"}},{"old":{"landuse":"wood"},"replace":{"landuse":"forest","natural":"wood"}},{"old":{"natural":"marsh"},"replace":{"natural":"wetland","wetland":"marsh"}},{"old":{"power_source":"*"},"replace":{"generator:source":"$1"}},{"old":{"power_rating":"*"},"replace":{"generator:output":"$1"}},{"old":{"shop":"organic"},"replace":{"shop":"supermarket","organic":"only"}}];
18927 var dataDiscarded = ["created_by","odbl","odbl:note","tiger:upload_uuid","tiger:tlid","tiger:source","tiger:separated","geobase:datasetName","geobase:uuid","sub_sea:type","KSJ2:ADS","KSJ2:ARE","KSJ2:AdminArea","KSJ2:COP_label","KSJ2:DFD","KSJ2:INT","KSJ2:INT_label","KSJ2:LOC","KSJ2:LPN","KSJ2:OPC","KSJ2:PubFacAdmin","KSJ2:RAC","KSJ2:RAC_label","KSJ2:RIC","KSJ2:RIN","KSJ2:WSC","KSJ2:coordinate","KSJ2:curve_id","KSJ2:curve_type","KSJ2:filename","KSJ2:lake_id","KSJ2:lat","KSJ2:long","KSJ2:river_id","yh:LINE_NAME","yh:LINE_NUM","yh:STRUCTURE","yh:TOTYUMONO","yh:TYPE","yh:WIDTH","yh:WIDTH_RANK","SK53_bulk:load"];
18929 var dataLocales = {"af":{"rtl":false},"ar":{"rtl":true},"ar-AA":{"rtl":true},"ast":{"rtl":false},"bg-BG":{"rtl":false},"bn":{"rtl":false},"bs":{"rtl":false},"ca":{"rtl":false},"cs":{"rtl":false},"da":{"rtl":false},"de":{"rtl":false},"el":{"rtl":false},"en-GB":{"rtl":false},"eo":{"rtl":false},"es":{"rtl":false},"et":{"rtl":false},"fa":{"rtl":true},"fi":{"rtl":false},"fr":{"rtl":false},"gl":{"rtl":false},"gu":{"rtl":false},"hi":{"rtl":false},"hr":{"rtl":false},"hu":{"rtl":false},"hy":{"rtl":false},"id":{"rtl":false},"is":{"rtl":false},"it":{"rtl":false},"ja":{"rtl":false},"kn":{"rtl":false},"ko":{"rtl":false},"ku":{"rtl":false},"lij":{"rtl":false},"lt":{"rtl":false},"lv":{"rtl":false},"ml":{"rtl":false},"nl":{"rtl":false},"no":{"rtl":false},"pl":{"rtl":false},"pt":{"rtl":false},"pt-BR":{"rtl":false},"ro":{"rtl":false},"ru":{"rtl":false},"sc":{"rtl":false},"si":{"rtl":false},"sk":{"rtl":false},"sl":{"rtl":false},"sq":{"rtl":false},"sr":{"rtl":false},"sv":{"rtl":false},"ta":{"rtl":false},"te":{"rtl":false},"th":{"rtl":false},"tl":{"rtl":false},"tr":{"rtl":false},"uk":{"rtl":false},"vi":{"rtl":false},"yue":{"rtl":false},"zh":{"rtl":false},"zh-CN":{"rtl":false},"zh-HK":{"rtl":false},"zh-TW":{"rtl":false}};
18931 var dataPhoneFormats = {"us":"+1-202-555-1234","ca":"+1-226-555-1234","bs":"+1-242-555-1234","bb":"+1-246-555-1234","ai":"+1-264-555-1234","ag":"+1-268-555-1234","vg":"+1-284-555-1234","vi":"+1-340-555-1234","ky":"+1-345-555-1234","bm":"+1-441-555-1234","gd":"+1-473-555-1234","tc":"+1-649-555-1234","ms":"+1-664-555-1234","mp":"+1-670-555-1234","gu":"+1-671-555-1234","as":"+1-684-555-1234","sx":"+1-721-555-1234","lc":"+1-758-555-1234","dm":"+1-767-555-1234","vc":"+1-784-555-1234","pr":"+1-787-555-1234","do":"+1-809-555-1234","tt":"+1-868-555-1234","kn":"+1-869-555-1234","jm":"+1-876-555-1234","za":"+27 11 907 1111","nl":"+31 42 123 4567","fr":"+33 1 23 45 67 89","es":"+34 989 12 34 56","pt":"+351 211 123456","fi":"+358 40 123 4567","hu":"+36 1 123 45 67","hr":"+385 01 123 4567","si":"+386 31 123 4567","it":"+39 01 123 456","va":"+39 01 123 456","gb":"+44 207 123456","gg":"+44 207 123456","im":"+44 207 123456","je":"+44 207 123456","se":"+46 31 123 4567","no":"+47 22 12 34 56","sj":"+47 22 12 34 56","pl":"+48 42 123 4567","de":"+49 89 1234567","br":"+55 11 0982 1098","ru":"+7 495 1234567","kz":"+7 495 1234567","vn":"+84 1 234 5678","hk":"+852 12345678"};
18933 var type = "FeatureCollection";
18934 var features = [{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[1.97754,51.13111],[1.8457,63.45051],[-10.45898,57.01681],[-6.82251,55.26503],[-7.25583,55.06525],[-7.26546,55.0665],[-7.26992,55.06419],[-7.2725,55.06346],[-7.27818,55.05362],[-7.2893,55.04735],[-7.29939,55.0561],[-7.31835,55.04475],[-7.3447,55.05079],[-7.38831,55.02389],[-7.40547,55.00292],[-7.39157,54.99507],[-7.40075,54.98892],[-7.40706,54.98291],[-7.40363,54.97963],[-7.40633,54.97813],[-7.39835,54.97013],[-7.40745,54.96357],[-7.40178,54.95961],[-7.40727,54.95515],[-7.3944,54.94376],[-7.44444,54.93858],[-7.45216,54.89793],[-7.44204,54.87532],[-7.4713,54.83431],[-7.48092,54.83093],[-7.49216,54.82185],[-7.55121,54.79054],[-7.5443,54.78609],[-7.54958,54.75653],[-7.5349,54.74917],[-7.54881,54.74068],[-7.55941,54.74556],[-7.57894,54.74221],[-7.57507,54.7494],[-7.58606,54.75039],[-7.58872,54.74377],[-7.60031,54.74603],[-7.60632,54.74405],[-7.61662,54.74459],[-7.63593,54.75108],[-7.68854,54.72968],[-7.72064,54.72155],[-7.75094,54.70469],[-7.79094,54.71942],[-7.8051,54.71932],[-7.83497,54.73632],[-7.85419,54.72745],[-7.91496,54.67582],[-7.90174,54.66182],[-7.83832,54.63401],[-7.7433,54.6188],[-7.70863,54.63485],[-7.70682,54.6189],[-7.69386,54.6188],[-7.69631,54.61125],[-7.75845,54.59509],[-7.78708,54.58],[-7.79446,54.58141],[-7.79969,54.57704],[-7.79673,54.56915],[-7.8184,54.56315],[-7.83334,54.55227],[-7.82737,54.54299],[-7.85007,54.53363],[-7.90741,54.53722],[-7.93213,54.53388],[-8.00487,54.54568],[-8.03727,54.51162],[-8.04285,54.48759],[-8.08027,54.48829],[-8.09988,54.48395],[-8.09126,54.4765],[-8.111,54.47807],[-8.11512,54.46904],[-8.16542,54.46914],[-8.1776,54.46485],[-8.14293,54.45003],[-8.16284,54.4413],[-8.08731,54.4002],[-8.06062,54.37051],[-8.03289,54.35711],[-8.00054,54.34835],[-7.93333,54.30561],[-7.85849,54.29151],[-7.87067,54.28794],[-7.87265,54.26648],[-7.86123,54.25931],[-7.85917,54.21256],[-7.71043,54.20307],[-7.70193,54.20776],[-7.68828,54.202],[-7.67644,54.18906],[-7.66082,54.1871],[-7.62554,54.16545],[-7.62541,54.15319],[-7.61026,54.14353],[-7.57421,54.14142],[-7.57181,54.13287],[-7.56228,54.12704],[-7.51379,54.12998],[-7.47944,54.122],[-7.47169,54.12665],[-7.47075,54.13318],[-7.44684,54.15168],[-7.40792,54.156],[-7.42579,54.14092],[-7.41903,54.13629],[-7.3744,54.14172],[-7.37234,54.13881],[-7.39509,54.12624],[-7.39182,54.12017],[-7.36341,54.13157],[-7.34518,54.11577],[-7.32471,54.12123],[-7.32003,54.11379],[-7.3078,54.11718],[-7.30548,54.12347],[-7.31591,54.12697],[-7.31213,54.13162],[-7.3187,54.13411],[-7.31857,54.13745],[-7.32222,54.13836],[-7.32737,54.13544],[-7.3399,54.14585],[-7.30827,54.16716],[-7.30024,54.16625],[-7.29029,54.1715],[-7.28158,54.16839],[-7.2863,54.14919],[-7.29874,54.14904],[-7.30162,54.14411],[-7.28411,54.13971],[-7.29192,54.13071],[-7.29737,54.133],[-7.30883,54.13242],[-7.30333,54.12251],[-7.29218,54.11929],[-7.27844,54.12282],[-7.27707,54.12986],[-7.26613,54.13624],[-7.2566,54.16354],[-7.24015,54.17125],[-7.2575,54.17678],[-7.2581,54.19257],[-7.25179,54.19403],[-7.23608,54.1935],[-7.23338,54.19792],[-7.24317,54.20076],[-7.24892,54.1977],[-7.25183,54.20201],[-7.24119,54.20623],[-7.23094,54.20578],[-7.23269,54.20912],[-7.22188,54.21607],[-7.20643,54.2117],[-7.18506,54.22485],[-7.17055,54.21742],[-7.14721,54.22488],[-7.14633,54.23008],[-7.15051,54.23165],[-7.14613,54.23983],[-7.15802,54.24434],[-7.13985,54.25298],[-7.15255,54.26235],[-7.16064,54.27405],[-7.17991,54.27144],[-7.17201,54.28627],[-7.21252,54.2985],[-7.19888,54.31117],[-7.17918,54.30946],[-7.1812,54.3397],[-7.15339,54.33514],[-7.10253,54.35811],[-7.10811,54.36677],[-7.06927,54.3899],[-7.05593,54.41056],[-7.02898,54.42135],[-7.00198,54.40832],[-6.98683,54.40829],[-6.97562,54.40014],[-6.96774,54.40145],[-6.90682,54.36966],[-6.89772,54.35075],[-6.87527,54.33853],[-6.86512,54.32568],[-6.85163,54.29137],[-6.87452,54.28677],[-6.87791,54.27918],[-6.86673,54.27522],[-6.85177,54.26489],[-6.83693,54.26658],[-6.82165,54.24346],[-6.81633,54.22299],[-6.80045,54.22108],[-6.80122,54.21338],[-6.77599,54.19965],[-6.75573,54.1987],[-6.74316,54.18258],[-6.73406,54.18566],[-6.72445,54.18127],[-6.70295,54.20036],[-6.69166,54.20018],[-6.68673,54.19398],[-6.669,54.19584],[-6.65248,54.18102],[-6.6433,54.17801],[-6.63467,54.16449],[-6.63179,54.14766],[-6.64081,54.14238],[-6.63935,54.13599],[-6.66149,54.1205],[-6.6481,54.10153],[-6.66119,54.0934],[-6.66458,54.06629],[-6.64681,54.05873],[-6.62501,54.03737],[-6.59291,54.04755],[-6.58905,54.05808],[-6.5597,54.0481],[-6.52897,54.05888],[-6.50442,54.05566],[-6.47824,54.07004],[-6.47919,54.07762],[-6.43601,54.05959],[-6.36314,54.07057],[-6.36589,54.09338],[-6.36293,54.09758],[-6.37104,54.11497],[-6.3522,54.11084],[-6.34242,54.1114],[-6.33589,54.10833],[-6.33636,54.09469],[-6.31808,54.09096],[-6.30903,54.10463],[-6.29165,54.11235],[-6.28246,54.11145],[-6.26272,54.09786],[-5.35583,53.72597],[-7.0752,49.23912],[-1.83472,49.02346],[-2.12036,49.94415],[1.97754,51.13111]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-65.2,18.7],[-65,16.3],[-63.7,19.2],[-65.2,18.7]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-63,-50.5],[-55,-51],[-60,-54],[-63,-50.5]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-139.19952,60.08402],[-141,60.30621],[-141,76],[-169,68.63655],[-169,65.20147],[-180,61],[-180,-4],[-154,9],[-133.76404,54.54021],[-130.73868,54.71986],[-129.96277,55.29163],[-130.15228,55.7758],[-130.01787,55.90688],[-130.00362,56.00798],[-130.10284,56.12336],[-130.24498,56.09656],[-130.42625,56.14249],[-131.87439,56.79787],[-135.02884,59.56285],[-135.11759,59.62306],[-135.15827,59.6261],[-135.47928,59.79822],[-136.28677,59.57955],[-136.30531,59.46462],[-136.36836,59.44898],[-136.47697,59.46558],[-137.19727,59.01935],[-139.19952,60.08402]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-111.96064,48.99841],[-121.22623,49.00049],[-122.26513,49.00246],[-122.7565,49.00208],[-123.32218,49.00218],[-122.97821,48.76524],[-123.2666,48.69821],[-123.21991,48.21186],[-125.80444,48.60749],[-124.32129,31.54109],[-117.125,32.53429],[-116.82417,32.55996],[-115.88036,32.63735],[-115.49738,32.66486],[-114.71984,32.71877],[-114.7649,32.64602],[-114.80885,32.60959],[-114.81481,32.49451],[-112.81743,31.88004],[-111.07481,31.33224],[-109.56051,31.33402],[-108.20847,31.33384],[-108.20838,31.78363],[-106.52847,31.78391],[-106.52781,31.78086],[-106.52249,31.77501],[-106.51249,31.76933],[-106.50988,31.7612],[-106.50709,31.76123],[-106.48896,31.74806],[-106.48473,31.74769],[-106.4719,31.75101],[-106.46816,31.75897],[-106.45434,31.76466],[-106.45035,31.76426],[-106.43516,31.75492],[-106.41484,31.75101],[-106.37864,31.73021],[-106.37225,31.71174],[-106.34924,31.69633],[-106.33289,31.66178],[-106.3068,31.62459],[-106.28079,31.56179],[-106.24775,31.54226],[-106.2329,31.49982],[-106.2105,31.46857],[-106.08201,31.39863],[-106.00554,31.39233],[-105.76401,31.17051],[-105.58548,31.06117],[-105.56419,30.98526],[-104.99153,30.6639],[-104.97162,30.60896],[-104.90639,30.57822],[-104.83772,30.38117],[-104.70177,30.20567],[-104.68048,29.92399],[-104.57611,29.77838],[-104.51157,29.63674],[-104.39758,29.57047],[-104.39278,29.55293],[-104.05769,29.32173],[-103.79883,29.2581],[-103.78196,29.26555],[-103.76759,29.22799],[-103.14102,28.93666],[-102.86087,29.2217],[-102.65076,29.79418],[-101.41068,29.73457],[-101.26511,29.51372],[-101.05997,29.452],[-101.04083,29.38038],[-100.96303,29.34735],[-100.94406,29.34369],[-100.94071,29.33351],[-100.92775,29.32663],[-100.89814,29.30957],[-100.87818,29.28086],[-100.80076,29.2238],[-100.76437,29.15981],[-100.67047,29.08663],[-100.6412,28.91299],[-100.63236,28.90255],[-100.61296,28.89939],[-100.534,28.75622],[-100.51495,28.74531],[-100.50705,28.7143],[-100.51203,28.70666],[-100.51014,28.69127],[-100.50048,28.66186],[-100.45547,28.6381],[-100.44697,28.60743],[-100.35599,28.45239],[-100.34946,28.39653],[-100.29488,28.31315],[-100.29591,28.27324],[-100.17197,28.17493],[-99.93645,27.9568],[-99.87722,27.80173],[-99.79671,27.73338],[-99.772,27.72532],[-99.74556,27.69979],[-99.71947,27.65981],[-99.5957,27.59974],[-99.54094,27.60537],[-99.53055,27.57973],[-99.52034,27.55782],[-99.52802,27.49773],[-99.50141,27.49986],[-99.48755,27.49518],[-99.47897,27.48421],[-99.48661,27.46453],[-99.49534,27.44861],[-99.48927,27.40941],[-99.53957,27.31565],[-99.43588,27.19678],[-99.46404,27.01968],[-99.16698,26.56039],[-99.17474,26.53939],[-99.12698,26.51958],[-99.1135,26.42954],[-99.08355,26.39625],[-99.06007,26.39737],[-99.03634,26.41255],[-99.02042,26.40598],[-99.01291,26.39364],[-98.95686,26.38641],[-98.9566,26.37365],[-98.94523,26.36949],[-98.90013,26.36419],[-98.89905,26.35454],[-98.80305,26.36626],[-98.78254,26.30511],[-98.66667,26.23457],[-98.58496,26.24647],[-98.57951,26.23434],[-98.56519,26.23987],[-98.56294,26.22464],[-98.50599,26.20858],[-98.44806,26.21236],[-98.38617,26.15721],[-98.34176,26.15278],[-98.33579,26.1388],[-98.30626,26.10003],[-98.28841,26.10512],[-98.26524,26.0914],[-98.19898,26.06411],[-98.09577,26.05698],[-98.07568,26.06667],[-98.08302,26.03396],[-97.9771,26.04136],[-97.9532,26.06179],[-97.81643,26.04475],[-97.77017,26.02439],[-97.73884,26.02902],[-97.5289,25.90648],[-97.52151,25.88625],[-97.50615,25.89031],[-97.49851,25.89903],[-97.49637,25.89641],[-97.49748,25.88008],[-97.49422,25.87981],[-97.48847,25.88564],[-97.46409,25.88174],[-97.42607,25.842],[-97.36856,25.8396],[-97.26231,25.94724],[-80.81543,24.00633],[-66.87378,44.77794],[-67.16148,45.16715],[-67.2286,45.16739],[-67.26246,45.18797],[-67.28311,45.19175],[-67.28959,45.18784],[-67.29332,45.17568],[-67.29049,45.17317],[-67.3001,45.16776],[-67.3025,45.16122],[-67.29761,45.14766],[-67.33975,45.1255],[-67.40524,45.16122],[-67.40387,45.17139],[-67.4818,45.27682],[-67.42172,45.38543],[-67.45262,45.41008],[-67.50498,45.4889],[-67.41623,45.50105],[-67.42219,45.55661],[-67.42902,45.56833],[-67.42331,45.57154],[-67.42498,45.57836],[-67.45193,45.60323],[-67.77981,45.6738],[-67.79019,47.06776],[-67.88006,47.1067],[-67.91319,47.14793],[-67.92598,47.15418],[-67.95181,47.1875],[-68.02374,47.23915],[-68.13017,47.29309],[-68.17669,47.32893],[-68.24046,47.35354],[-68.32809,47.36005],[-68.36363,47.35476],[-68.38054,47.34167],[-68.38509,47.30321],[-68.37367,47.28796],[-68.4377,47.28232],[-68.47916,47.29623],[-68.51074,47.29885],[-68.54593,47.28441],[-68.58408,47.28482],[-68.59777,47.27134],[-68.59271,47.25762],[-68.61889,47.24148],[-68.68936,47.24125],[-68.71768,47.23676],[-68.80128,47.21423],[-68.89629,47.17676],[-69.05354,47.24847],[-69.04924,47.41798],[-69.22425,47.45961],[-69.99729,46.69558],[-70.0569,46.4149],[-70.25551,46.10871],[-70.29001,46.09431],[-70.39919,45.80667],[-70.83229,45.40062],[-70.80794,45.37878],[-70.82663,45.2367],[-70.87538,45.23453],[-70.92138,45.28099],[-70.90645,45.30918],[-71.0109,45.34798],[-71.08429,45.30556],[-71.1454,45.24226],[-71.20525,45.25278],[-71.28925,45.30097],[-71.41405,45.23513],[-71.43044,45.12381],[-71.49692,45.06991],[-71.50623,45.04878],[-71.49284,45.03629],[-71.50027,45.01372],[-71.79359,45.01075],[-72.08774,45.00581],[-72.14155,45.00568],[-72.15282,45.00609],[-72.17142,45.00584],[-72.25847,45.00436],[-72.38795,45.00626],[-72.4496,45.00863],[-72.5356,45.00936],[-72.66257,45.01523],[-72.82537,45.01642],[-73.08466,45.01561],[-73.45219,45.00875],[-74.14699,44.99145],[-74.33753,44.9923],[-74.50786,44.99798],[-74.66158,44.99949],[-74.71244,44.99734],[-74.75887,44.98708],[-74.76368,45.00632],[-74.78977,45.00365],[-74.82376,45.01773],[-74.94186,44.98229],[-75.30098,44.83883],[-75.30304,44.82836],[-75.59418,44.6457],[-75.97269,44.33502],[-75.97295,44.34595],[-76.00059,44.34797],[-76.17645,44.2865],[-76.18744,44.22158],[-76.88782,43.82759],[-79.16851,43.32168],[-79.05487,43.25371],[-79.05092,43.169],[-79.04603,43.16093],[-79.04208,43.13942],[-79.07002,43.12038],[-79.06015,43.114],[-79.0568,43.10474],[-79.0774,43.07861],[-78.9996,43.05484],[-79.02311,43.02071],[-79.02552,42.99473],[-78.96235,42.9573],[-78.91188,42.9426],[-78.90398,42.89181],[-82.42767,41.47978],[-83.14316,42.03807],[-83.12805,42.23843],[-83.09715,42.29052],[-83.07252,42.31515],[-82.94575,42.34332],[-82.59676,42.5479],[-82.51368,42.61785],[-82.5108,42.66464],[-82.4675,42.76415],[-82.48055,42.80573],[-82.45497,42.9284],[-82.41334,42.97099],[-82.42596,42.99536],[-82.15851,43.39507],[-83.53729,46.098],[-83.96301,46.05036],[-84.11021,46.23851],[-84.09794,46.25656],[-84.11613,46.26878],[-84.11905,46.31516],[-84.10721,46.3218],[-84.14394,46.41076],[-84.11682,46.51576],[-84.13536,46.53218],[-84.16162,46.5284],[-84.21621,46.53891],[-84.26994,46.49189],[-84.36092,46.50997],[-84.55284,46.4407],[-84.95178,46.77185],[-89.59179,48.00307],[-89.67547,48.00371],[-90.87204,48.25943],[-91.41312,48.06753],[-92.99377,48.62474],[-93.34877,48.62604],[-93.35529,48.61124],[-93.37074,48.60584],[-93.39812,48.60369],[-93.40542,48.61089],[-93.43846,48.59478],[-93.46859,48.59205],[-93.45735,48.56667],[-93.46533,48.54593],[-93.64763,48.51751],[-93.80625,48.51888],[-93.80642,48.58047],[-93.83328,48.62582],[-93.84865,48.63064],[-93.93388,48.6326],[-94.01327,48.64471],[-94.16176,48.64697],[-94.25025,48.65463],[-94.24931,48.67827],[-94.26046,48.69816],[-94.30578,48.71073],[-94.32758,48.70433],[-94.36123,48.70478],[-94.38406,48.71135],[-94.41629,48.71067],[-94.44294,48.69266],[-94.53615,48.7024],[-94.55031,48.71419],[-94.58894,48.71928],[-94.69425,48.77938],[-94.70129,48.83376],[-94.68996,48.83953],[-94.68395,48.99914],[-111.96064,48.99841]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[180,55],[170,53],[180,49],[180,55]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[143,22],[147,22],[147,12],[143,12],[143,22]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-171.5,-10],[-171,-15],[-167,-15],[-171.5,-10]]]}}];
18935 var dataImperial = {
18940 var type$1 = "FeatureCollection";
18941 var features$1 = [{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[113.573,22.186],[114,22.5],[114.05534,22.503],[114.0595,22.51422],[114.07345,22.51934],[114.0786,22.53012],[114.08512,22.53228],[114.09034,22.53717],[114.09611,22.53486],[114.10602,22.53472],[114.1115,22.52929],[114.11522,22.5308],[114.11649,22.53418],[114.11979,22.53511],[114.1244,22.5393],[114.12729,22.53947],[114.13018,22.54132],[114.13807,22.5432],[114.14429,22.54176],[114.14441,22.54114],[114.14846,22.54179],[114.14855,22.54397],[114.15042,22.54593],[114.14964,22.54954],[114.15166,22.55168],[114.15192,22.55438],[114.15642,22.55495],[114.15841,22.55909],[114.16032,22.56153],[114.16162,22.56187],[114.1634,22.55931],[114.16553,22.5593],[114.16733,22.56119],[114.16934,22.56093],[114.17061,22.5597],[114.17702,22.56],[114.17798,22.55546],[114.18401,22.5552],[114.18673,22.55468],[114.1878,22.55545],[114.18979,22.55446],[114.1955,22.55564],[114.19674,22.55691],[114.20005,22.55717],[114.20376,22.55623],[114.20884,22.55672],[114.22438,22.55055],[114.2264,22.5476],[114.22545,22.54528],[114.22661,22.54339],[114.32,22.576],[114.45,22.43],[114.45,22.14],[113.9,22.14],[113.75,22.22],[113.553,22.095],[113.54678,22.1207],[113.5456,22.1207],[113.54076,22.12373],[113.54016,22.13618],[113.54701,22.13651],[113.5475,22.14583],[113.52456,22.17978],[113.53623,22.20191],[113.53299,22.21232],[113.53497,22.21351],[113.53735,22.21377],[113.54156,22.21315],[113.54385,22.21709],[113.55849,22.21565],[113.573,22.186]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-75,18],[-80,20.5],[-83,19],[-77,16],[-75,18]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-64.33594,32.86113],[-79.39819,27.21067],[-80.63965,23.71998],[-73.39966,20.40642],[-65.1709,19.20743],[-65.09399,16.23577],[-59.13391,16.80454],[-62.64404,15.16228],[-59.43054,14.85985],[-62.83081,13.64599],[-61.80359,10.73752],[-62.08649,10.04729],[-61.06201,9.85522],[-59.81369,8.31274],[-59.8027,8.27469],[-59.83498,8.22712],[-59.94141,8.21149],[-59.99771,8.15576],[-59.97986,8.13265],[-59.99771,8.12041],[-60.00183,8.07147],[-60.05127,8.02524],[-60.09933,8.03747],[-60.12268,8.02388],[-60.14053,7.98988],[-60.36163,7.83345],[-60.53467,7.81713],[-60.5896,7.6375],[-60.72144,7.54493],[-60.5896,7.31888],[-60.63904,7.24532],[-60.54703,7.12542],[-60.46875,7.20309],[-60.37262,7.18401],[-60.29984,7.1445],[-60.2916,7.06819],[-60.39871,6.95097],[-60.66513,6.83235],[-60.71869,6.75053],[-60.91232,6.81735],[-60.94254,6.72053],[-61.14441,6.72326],[-61.23093,6.5773],[-61.1554,6.45314],[-61.14441,6.20199],[-61.39709,5.95619],[-60.71045,5.20036],[-60.21606,5.23319],[-59.99634,5.06906],[-60.13916,4.51071],[-59.69971,4.40118],[-59.5459,3.93002],[-59.87549,3.56825],[-59.7876,3.37086],[-60.01831,2.83332],[-59.90845,2.38335],[-59.69971,2.2626],[-59.77661,1.87833],[-59.65302,1.85087],[-59.69147,1.75754],[-59.61456,1.71361],[-59.55139,1.73283],[-59.36188,1.49123],[-59.26575,1.39238],[-58.92242,1.30726],[-58.83728,1.17271],[-58.71918,1.23037],[-58.71094,1.29902],[-58.49121,1.26058],[-58.461,1.37591],[-58.50494,1.38689],[-58.51044,1.46102],[-58.38135,1.4775],[-58.32642,1.57359],[-58.00507,1.49946],[-57.99133,1.65321],[-57.79907,1.69165],[-57.70844,1.71087],[-57.54364,1.68341],[-57.41455,1.94421],[-57.10693,1.97715],[-56.8103,1.85636],[-56.48071,1.92225],[-55.90942,1.81244],[-55.90942,2.04302],[-56.14014,2.26534],[-55.94788,2.53701],[-55.70892,2.39981],[-55.37933,2.43274],[-55.19257,2.53976],[-54.98108,2.57268],[-54.88495,2.43548],[-54.71191,2.46293],[-54.69543,2.34767],[-54.58832,2.32846],[-54.43451,2.43548],[-54.20654,2.76748],[-54.17358,3.12955],[-53.96484,3.57921],[-54.33838,4.00674],[-54.44412,4.52577],[-54.46884,4.91036],[-54.36653,5.13061],[-54.27727,5.26191],[-54.19968,5.3084],[-54.01222,5.54457],[-54.0239,5.64605],[-53.86322,5.94936],[-64.33594,32.86113]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-14.5,-6],[11.79657,-17.27197],[12.03415,-17.14866],[12.38159,-17.22213],[12.58484,-17.22476],[13.01193,-16.97405],[13.24951,-17.00098],[13.38135,-16.98522],[13.93341,-17.38734],[18.42476,-17.38996],[18.47763,-17.46857],[18.62663,-17.64599],[18.79211,-17.76177],[18.92944,-17.82061],[19.33044,-17.84806],[19.66278,-17.8644],[19.74792,-17.90557],[19.85161,-17.87486],[20.10361,-17.90296],[20.18394,-17.88401],[20.34737,-17.88466],[20.44693,-17.91733],[20.51697,-17.96698],[20.83008,-18.03032],[20.95711,-17.97285],[21.16997,-17.93497],[21.42677,-18.0264],[23.45032,-17.63879],[22.00012,-16.38866],[21.99944,-13.00523],[24.03809,-12.99118],[24.03809,-10.91962],[24.43359,-11.09217],[24.45557,-11.48002],[25.37842,-11.19996],[25.42236,-11.60919],[26.96045,-11.97484],[27.18018,-11.60919],[28.125,-12.42048],[29.11377,-13.36824],[29.1687,-13.43771],[29.55872,-13.19716],[29.68506,-13.2239],[29.62463,-13.41099],[29.80591,-13.44305],[29.81415,-12.14809],[29.31152,-12.55456],[28.41064,-11.78133],[28.63037,-10.70379],[28.65234,-9.73071],[28.37219,-9.24309],[28.89748,-8.47916],[30.78644,-8.26857],[29.39941,-6.05316],[29.4873,-4.45595],[29.75922,-4.46759],[29.81415,-4.36421],[29.88007,-4.36832],[30.04074,-4.26699],[30.07919,-4.1629],[30.18356,-4.08311],[30.1918,-4.05126],[30.21566,-4.04595],[30.22923,-4.01136],[30.21326,-3.99612],[30.25978,-3.88755],[30.29274,-3.86288],[30.34424,-3.77245],[30.39848,-3.79095],[30.40878,-3.76765],[30.39548,-3.7304],[30.39054,-3.72821],[30.3896,-3.71918],[30.39093,-3.7101],[30.39514,-3.70444],[30.42028,-3.64963],[30.46886,-3.53501],[30.67108,-3.41335],[30.63297,-3.34892],[30.84206,-3.25535],[30.84549,-3.16108],[30.83485,-3.09698],[30.7933,-3.06235],[30.82111,-3.02258],[30.84515,-2.9739],[30.74764,-2.99618],[30.7037,-2.97013],[30.66422,-2.98967],[30.57632,-2.90738],[30.49393,-2.94441],[30.41016,-2.87172],[30.52002,-2.39432],[30.77545,-2.38883],[30.8606,-2.31199],[30.84961,-2.19398],[30.89081,-2.07322],[30.81116,-1.96068],[30.83862,-1.6587],[30.73425,-1.4418],[30.56259,-1.33884],[30.4541,-1.05737],[30.35797,-1.06287],[30.34149,-1.13152],[30.16571,-1.34296],[29.91852,-1.48024],[29.83887,-1.31824],[29.58344,-1.39238],[29.729,0.05493],[29.96796,0.5136],[29.9707,0.8569],[30.22339,0.92281],[30.24536,1.15349],[30.47745,1.20772],[31.30966,2.15693],[31.20255,2.22211],[31.20255,2.29278],[31.16409,2.27906],[31.13937,2.28318],[31.13113,2.26534],[31.07826,2.30033],[31.0714,2.34767],[31.00479,2.4005],[30.97183,2.40461],[30.94711,2.38746],[30.94849,2.36276],[30.9375,2.33532],[30.88531,2.34012],[30.83038,2.42176],[30.74112,2.43274],[30.76035,2.5864],[30.90179,2.88132],[30.76447,3.04178],[30.93613,3.40239],[30.94059,3.50588],[30.85236,3.48601],[30.90866,3.5936],[30.95055,3.63918],[30.94677,3.65391],[30.9866,3.70187],[31.00582,3.70701],[31.02058,3.69708],[31.16547,3.7954],[31.28838,3.79643],[31.52699,3.66282],[31.7038,3.72449],[31.82671,3.82794],[31.96198,3.65596],[31.95854,3.57099],[32.04987,3.59155],[32.07733,3.57099],[32.0842,3.53672],[32.20093,3.50657],[32.21672,3.56448],[32.19578,3.59977],[32.41516,3.74504],[32.72055,3.76782],[32.89307,3.81219],[33.02782,3.89371],[33.18146,3.7793],[33.51173,3.75258],[33.98758,4.23309],[34.05762,4.28342],[34.38721,4.61065],[35.94452,4.62023],[35.95688,4.53467],[36.04134,4.44568],[36.89621,4.4491],[38.14728,3.62992],[38.55927,3.62033],[38.92181,3.51068],[39.56039,3.43392],[39.87076,3.87522],[40.76752,4.28753],[41.16371,3.94372],[41.89774,3.97797],[41.31271,3.14463],[40.98896,2.82869],[40.99548,-0.84042],[41.7,-1.8],[41.7,-49],[-27,-60],[-65.7,-52.5],[-14.5,-6]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[31.33301,35.47856],[33.0249,33.75175],[35.44189,36.02245],[31.33301,35.47856]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[14,36.5],[15,36],[14,35],[14,36.5]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[0,62],[2.5,51.3],[-2,50],[-1.9,49],[-20,53],[0,62]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[180,-35],[161,-19],[167,-12],[180,-22],[180,4],[170,3.7],[127,5.7],[118,2.7],[119.5,5.4],[117.2,7.5],[102.6,8],[102.9158,11.74099],[102.76268,12.07357],[102.70226,12.17158],[102.74139,12.46474],[102.53128,12.68857],[102.49557,12.9256],[102.49763,13.0064],[102.4597,13.08199],[102.43412,13.09026],[102.39155,13.16407],[102.35481,13.29341],[102.35893,13.30945],[102.34503,13.34837],[102.35928,13.39797],[102.3567,13.48095],[102.36168,13.50582],[102.33559,13.53787],[102.33971,13.56023],[102.35498,13.5649],[102.36511,13.5785],[102.40047,13.5679],[102.42537,13.56891],[102.44614,13.56123],[102.48047,13.57091],[102.53849,13.56757],[102.5699,13.58526],[102.57806,13.60486],[102.62501,13.60845],[102.62132,13.61295],[102.60767,13.61562],[102.57231,13.63331],[102.56922,13.64082],[102.54879,13.658],[102.56252,13.68552],[102.5972,13.70803],[102.67084,13.74472],[102.68818,13.75172],[102.7014,13.7684],[102.73161,13.77082],[102.76543,13.85541],[102.78397,13.93207],[102.80388,13.94406],[102.81607,13.96639],[102.90705,14.02119],[102.89726,14.0535],[102.90095,14.0838],[102.92421,14.10744],[102.92378,14.12838],[102.94147,14.15035],[102.92953,14.17952],[103.17535,14.33774],[103.19939,14.32992],[103.68553,14.44],[103.94508,14.34157],[104.05756,14.34589],[104.06636,14.3419],[104.26025,14.37749],[104.50058,14.36984],[104.57817,14.36019],[104.6422,14.42387],[104.66632,14.40234],[104.68357,14.39877],[104.71138,14.43169],[104.72305,14.42188],[104.71687,14.40043],[104.75344,14.40459],[104.80408,14.43867],[104.83429,14.41573],[104.99239,14.3838],[105.05402,14.19783],[105.47905,14.49186],[105.60883,15.0005],[105.46703,15.13005],[105.48866,15.20237],[105.59269,15.2716],[105.58617,15.32823],[105.50308,15.31912],[105.46703,15.33948],[105.49175,15.37921],[105.59372,15.42869],[105.59372,15.50927],[105.60986,15.54871],[105.62616,15.56492],[105.62702,15.59129],[105.63518,15.62742],[105.63612,15.66056],[105.5975,15.72088],[105.49965,15.76681],[105.46291,15.74517],[105.43819,15.75459],[105.40489,15.79424],[105.34241,15.92039],[105.37811,15.98344],[105.39167,15.99136],[105.41931,15.98608],[105.42652,15.99764],[105.41468,16.01661],[105.21263,16.05076],[105.04955,16.10552],[105.01316,16.24401],[104.88235,16.37812],[104.8391,16.45782],[104.77936,16.49041],[104.73919,16.53287],[104.74228,16.62205],[104.76391,16.70953],[104.73953,16.80323],[104.76425,16.85088],[104.73782,16.90968],[104.744,17.0128],[104.81266,17.21853],[104.79841,17.39274],[104.70348,17.52833],[104.46384,17.65515],[104.34368,17.83564],[104.27776,17.8559],[104.22661,17.98069],[104.1116,18.10735],[104.06525,18.21174],[103.97392,18.33823],[103.9286,18.33237],[103.88809,18.29456],[103.85582,18.28673],[103.83659,18.32715],[103.79128,18.3467],[103.70201,18.34214],[103.60931,18.40405],[103.57292,18.40437],[103.51593,18.42978],[103.45963,18.42587],[103.41568,18.44802],[103.30479,18.43206],[103.24265,18.37082],[103.24333,18.34133],[103.29123,18.32357],[103.28899,18.29521],[103.23595,18.28299],[103.16608,18.25511],[103.02429,17.98135],[102.6535,17.83237],[102.40631,17.99963],[102.10968,18.22413],[101.548,17.81538],[101.30493,17.64991],[101.14563,17.46595],[100.95886,17.61654],[101.01757,17.88858],[101.18752,18.05121],[101.16863,18.10409],[101.18134,18.33595],[101.08727,18.38287],[101.05499,18.43988],[101.23215,18.73015],[101.35265,19.04524],[101.25927,19.12733],[101.2373,19.32637],[101.25824,19.58438],[101.11954,19.56836],[101.08898,19.58777],[101.08624,19.59715],[101.03165,19.6185],[100.89844,19.62125],[100.77827,19.49249],[100.63751,19.56432],[100.58258,19.49313],[100.47478,19.5944],[100.42929,19.67152],[100.43341,19.7024],[100.4147,19.7255],[100.40525,19.7646],[100.43907,19.80345],[100.45555,19.84843],[100.50636,19.87264],[100.51709,19.93027],[100.58653,20.1599],[100.56576,20.1757],[100.54945,20.17473],[100.52731,20.14379],[100.51065,20.14895],[100.48697,20.17956],[100.46774,20.196],[100.45246,20.20147],[100.45521,20.22129],[100.44783,20.23546],[100.41607,20.25286],[100.40594,20.28184],[100.38397,20.31082],[100.37556,20.35187],[100.36165,20.35638],[100.35736,20.37408],[100.33195,20.39902],[100.27805,20.40224],[100.25917,20.39677],[100.2475,20.37263],[100.22535,20.35509],[100.22346,20.31839],[100.16579,20.29988],[100.17162,20.24545],[100.10845,20.25221],[100.09266,20.2696],[100.09798,20.31485],[100.07961,20.3678],[99.9567,20.46417],[99.91636,20.44925],[99.90765,20.44977],[99.89121,20.44511],[99.87276,20.44406],[99.86212,20.44326],[99.80186,20.33948],[99.46472,20.3884],[99.56085,20.20035],[99.43691,20.08882],[99.27727,20.11623],[99.06921,20.1101],[98.97789,19.74538],[98.24387,19.68656],[97.85934,19.57014],[97.76733,18.57336],[97.39655,18.47179],[97.62451,18.30238],[97.73849,17.97743],[97.66502,17.87943],[97.90947,17.56745],[98.52951,16.82557],[98.51303,16.69276],[98.69293,16.26873],[98.87421,16.43609],[98.93394,16.3353],[98.84743,16.13356],[98.74512,16.12037],[98.58307,16.07287],[98.5762,15.79754],[98.54736,15.37557],[98.17383,15.15167],[98.3606,14.63674],[99.08295,13.89208],[99.16534,13.72204],[99.18182,13.00723],[99.39331,12.56797],[99.64153,11.78973],[99.32156,11.30266],[98.77859,10.67849],[98.80597,10.47642],[98.76657,10.40459],[98.74924,10.34194],[96.85547,6.40265],[92.42523,20.54794],[92.2728,20.96272],[92.187,21.16],[92.26,21.36],[92.27,21.4328],[92.62,21.43],[92.6,22],[93.22,22.25],[93.4,23.7],[93.34,23.95],[94.155,23.847],[94.17,23.92],[94.25171,24.07405],[94.28,24.23],[94.30175,24.2371],[94.3256,24.2731],[94.6,24.7],[94.78,25.47],[95.2,26],[95.1,26.6],[97.3,27.9],[96.14,29.38],[95.4,29.1],[94.8,29.2],[92.5,27.8],[91.64,27.76],[91.4,28],[89.58,28.18],[88.9,27.32],[88.74,27.47],[88.9,27.86],[88.7,28.1],[88.1,27.87],[85.93,27.942],[81.6,30.5],[81.2,30],[78.73,31.5],[78.77,31.99],[78.4,32.5],[79.3,32.5],[79,34.3],[78.3,34.6],[78,35.5],[76.1,35.8],[76,36.55],[75.15,37],[72.5,36.9],[71.1,36.1],[71.65,35.44],[71.45,35],[70.985,34.54],[71.18,34.36],[71.092,34.118],[70.88,33.97],[70.5,33.94],[69.908,34.04],[69.869,33.96],[70,33.75],[70.13,33.73],[70.34,33.34],[70.013,33.14],[69.57,33.09],[69.24,32.45],[69.3,31.9],[68.1,31.6],[66.393,30.934],[66.2,29.8],[62.5,29.4],[60.87,29.86],[61.53,29.0165],[61.66,28.77],[61.96,28.54],[62.43,28.42],[62.6,28.25],[62.795,28.28],[62.86,27.25],[63.24,27.25],[63.327,27.13],[63.25,27.1],[63.25,26.84],[63.18,26.83],[63.18,26.65],[62.3,26.5],[62.2,26.28],[61.85,26.22],[61.84,25.75],[61.68,25.67],[56.5,-21],[180,-65],[180,-35]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[138.7,46.7],[145.5,44.5],[145.2,43.7],[146,43.3],[142,18],[122,24.3],[138.7,46.7]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-180,7],[-148,7],[-151,-12],[-171.5,-10.75],[-171,-16],[-152,-19],[-180,-55],[-180,7]]]}}];
18942 var dataDriveLeft = {
18944 features: features$1
18947 var en = {"modes":{"add_area":{"title":"Area","description":"Add parks, buildings, lakes or other areas to the map.","tail":"Click on the map to start drawing an area, like a park, lake, or building."},"add_line":{"title":"Line","description":"Add highways, streets, pedestrian paths, canals or other lines to the map.","tail":"Click on the map to start drawing a road, path, or route."},"add_point":{"title":"Point","description":"Add restaurants, monuments, postal boxes or other points to the map.","tail":"Click on the map to add a point."},"browse":{"title":"Browse","description":"Pan and zoom the map."},"draw_area":{"tail":"Click to add nodes to your area. Click the first node to finish the area."},"draw_line":{"tail":"Click to add more nodes to the line. Click on other lines to connect to them, and double-click to end the line."}},"operations":{"add":{"annotation":{"point":"Added a point.","vertex":"Added a node to a way.","relation":"Added a relation."}},"start":{"annotation":{"line":"Started a line.","area":"Started an area."}},"continue":{"key":"A","title":"Continue","description":"Continue this line.","not_eligible":"No line can be continued here.","multiple":"Several lines can be continued here. To choose a line, press the Shift key and click on it to select it.","annotation":{"line":"Continued a line.","area":"Continued an area."}},"cancel_draw":{"annotation":"Canceled drawing."},"change_role":{"annotation":"Changed the role of a relation member."},"change_tags":{"annotation":"Changed tags."},"circularize":{"title":"Circularize","description":{"line":"Make this line circular.","area":"Make this area circular."},"key":"O","annotation":{"line":"Made a line circular.","area":"Made an area circular."},"not_closed":"This can't be made circular because it's not a loop.","too_large":"This can't be made circular because not enough of it is currently visible.","connected_to_hidden":"This can't be made circular because it is connected to a hidden feature."},"orthogonalize":{"title":"Square","description":{"line":"Square the corners of this line.","area":"Square the corners of this area."},"key":"S","annotation":{"line":"Squared the corners of a line.","area":"Squared the corners of an area."},"not_squarish":"This can't be made square because it is not squarish.","too_large":"This can't be made square because not enough of it is currently visible.","connected_to_hidden":"This can't be made square because it is connected to a hidden feature."},"straighten":{"title":"Straighten","description":"Straighten this line.","key":"S","annotation":"Straightened a line.","too_bendy":"This can't be straightened because it bends too much.","connected_to_hidden":"This line can't be straightened because it is connected to a hidden feature."},"delete":{"title":"Delete","description":"Delete object permanently.","annotation":{"point":"Deleted a point.","vertex":"Deleted a node from a way.","line":"Deleted a line.","area":"Deleted an area.","relation":"Deleted a relation.","multiple":"Deleted {n} objects."},"incomplete_relation":"This feature can't be deleted because it hasn't been fully downloaded.","part_of_relation":"This feature can't be deleted because it's part of a larger relation. You must remove it from the relation first.","connected_to_hidden":"This can't be deleted because it is connected to a hidden feature."},"add_member":{"annotation":"Added a member to a relation."},"delete_member":{"annotation":"Removed a member from a relation."},"connect":{"annotation":{"point":"Connected a way to a point.","vertex":"Connected a way to another.","line":"Connected a way to a line.","area":"Connected a way to an area."}},"disconnect":{"title":"Disconnect","description":"Disconnect these lines/areas from each other.","key":"D","annotation":"Disconnected lines/areas.","not_connected":"There aren't enough lines/areas here to disconnect.","connected_to_hidden":"This can't be disconnected because it is connected to a hidden feature.","relation":"This can't be disconnected because it connects members of a relation."},"merge":{"title":"Merge","description":"Merge these features.","key":"C","annotation":"Merged {n} features.","not_eligible":"These features can't be merged.","not_adjacent":"These features can't be merged because they aren't connected.","restriction":"These features can't be merged because at least one is a member of a \"{relation}\" relation.","incomplete_relation":"These features can't be merged because at least one hasn't been fully downloaded.","conflicting_tags":"These features can't be merged because some of their tags have conflicting values."},"move":{"title":"Move","description":"Move this to a different location.","key":"M","annotation":{"point":"Moved a point.","vertex":"Moved a node in a way.","line":"Moved a line.","area":"Moved an area.","multiple":"Moved multiple objects."},"incomplete_relation":"This feature can't be moved because it hasn't been fully downloaded.","too_large":"This can't be moved because not enough of it is currently visible.","connected_to_hidden":"This can't be moved because it is connected to a hidden feature."},"rotate":{"title":"Rotate","description":"Rotate this object around its center point.","key":"R","annotation":{"line":"Rotated a line.","area":"Rotated an area."},"too_large":"This can't be rotated because not enough of it is currently visible.","connected_to_hidden":"This can't be rotated because it is connected to a hidden feature."},"reverse":{"title":"Reverse","description":"Make this line go in the opposite direction.","key":"V","annotation":"Reversed a line."},"split":{"title":"Split","description":{"line":"Split this line into two at this node.","area":"Split the boundary of this area into two.","multiple":"Split the lines/area boundaries at this node into two."},"key":"X","annotation":{"line":"Split a line.","area":"Split an area boundary.","multiple":"Split {n} lines/area boundaries."},"not_eligible":"Lines can't be split at their beginning or end.","multiple_ways":"There are too many lines here to split.","connected_to_hidden":"This can't be split because it is connected to a hidden feature."},"restriction":{"help":{"select":"Click to select a road segment.","toggle":"Click to toggle turn restrictions.","toggle_on":"Click to add a \"{restriction}\" restriction.","toggle_off":"Click to remove the \"{restriction}\" restriction."},"annotation":{"create":"Added a turn restriction","delete":"Deleted a turn restriction"}}},"undo":{"tooltip":"Undo: {action}","nothing":"Nothing to undo."},"redo":{"tooltip":"Redo: {action}","nothing":"Nothing to redo."},"tooltip_keyhint":"Shortcut:","browser_notice":"This editor is supported in Firefox, Chrome, Safari, Opera, and Internet Explorer 11 and above. Please upgrade your browser or use Potlatch 2 to edit the map.","translate":{"translate":"Translate","localized_translation_label":"Multilingual name","localized_translation_language":"Choose language","localized_translation_name":"Name"},"zoom_in_edit":"Zoom in to Edit","login":"login","logout":"logout","loading_auth":"Connecting to OpenStreetMap...","report_a_bug":"Report a bug","help_translate":"Help translate","feature_info":{"hidden_warning":"{count} hidden features","hidden_details":"These features are currently hidden: {details}"},"status":{"error":"Unable to connect to API.","offline":"The API is offline. Please try editing later.","readonly":"The API is read-only. You will need to wait to save your changes.","rateLimit":"The API is limiting anonymous connections. You can fix this by logging in."},"commit":{"title":"Save Changes","description_placeholder":"Brief description of your contributions (required)","message_label":"Changeset comment","upload_explanation":"The changes you upload will be visible on all maps that use OpenStreetMap data.","upload_explanation_with_user":"The changes you upload as {user} will be visible on all maps that use OpenStreetMap data.","save":"Save","cancel":"Cancel","changes":"{count} Changes","warnings":"Warnings","modified":"Modified","deleted":"Deleted","created":"Created","about_changeset_comments":"About changeset comments","about_changeset_comments_link":"//wiki.openstreetmap.org/wiki/Good_changeset_comments","google_warning":"You mentioned Google in this comment: remember that copying from Google Maps is strictly forbidden.","google_warning_link":"http://www.openstreetmap.org/copyright"},"contributors":{"list":"Edits by {users}","truncated_list":"Edits by {users} and {count} others"},"infobox":{"selected":"{n} selected","geometry":"Geometry","closed":"closed","center":"Center","perimeter":"Perimeter","length":"Length","area":"Area","centroid":"Centroid","location":"Location","metric":"Metric","imperial":"Imperial"},"geometry":{"point":"point","vertex":"vertex","line":"line","area":"area","relation":"relation"},"geocoder":{"search":"Search worldwide...","no_results_visible":"No results in visible map area","no_results_worldwide":"No results found"},"geolocate":{"title":"Show My Location","locating":"Locating, please wait..."},"inspector":{"no_documentation_combination":"There is no documentation available for this tag combination","no_documentation_key":"There is no documentation available for this key","documentation_redirect":"This documentation has been redirected to a new page","show_more":"Show More","view_on_osm":"View on openstreetmap.org","all_fields":"All fields","all_tags":"All tags","all_members":"All members","all_relations":"All relations","new_relation":"New relation...","role":"Role","choose":"Select feature type","results":"{n} results for {search}","reference":"View on OpenStreetMap Wiki","back_tooltip":"Change feature","remove":"Remove","search":"Search","multiselect":"Selected items","unknown":"Unknown","incomplete":"<not downloaded>","feature_list":"Search features","edit":"Edit feature","check":{"yes":"Yes","no":"No"},"add":"Add","none":"None","node":"Node","way":"Way","relation":"Relation","location":"Location","add_fields":"Add field:"},"background":{"title":"Background","description":"Background settings","percent_brightness":"{opacity}% brightness","none":"None","best_imagery":"Best known imagery source for this location","switch":"Switch back to this background","custom":"Custom","custom_button":"Edit custom background","custom_prompt":"Enter a tile URL template. Valid tokens are {zoom}, {x}, {y} for Z/X/Y scheme and {u} for quadtile scheme.","fix_misalignment":"Adjust imagery offset","imagery_source_faq":"Where does this imagery come from?","reset":"reset","offset":"Drag anywhere in the gray area below to adjust the imagery offset, or enter the offset values in meters.","minimap":{"description":"Minimap","tooltip":"Show a zoomed out map to help locate the area currently displayed."}},"map_data":{"title":"Map Data","description":"Map Data","data_layers":"Data Layers","fill_area":"Fill Areas","map_features":"Map Features","autohidden":"These features have been automatically hidden because too many would be shown on the screen. You can zoom in to edit them."},"feature":{"points":{"description":"Points","tooltip":"Points of Interest"},"traffic_roads":{"description":"Traffic Roads","tooltip":"Highways, Streets, etc."},"service_roads":{"description":"Service Roads","tooltip":"Service Roads, Parking Aisles, Tracks, etc."},"paths":{"description":"Paths","tooltip":"Sidewalks, Foot Paths, Cycle Paths, etc."},"buildings":{"description":"Buildings","tooltip":"Buildings, Shelters, Garages, etc."},"landuse":{"description":"Landuse Features","tooltip":"Forests, Farmland, Parks, Residential, Commercial, etc."},"boundaries":{"description":"Boundaries","tooltip":"Administrative Boundaries"},"water":{"description":"Water Features","tooltip":"Rivers, Lakes, Ponds, Basins, etc."},"rail":{"description":"Rail Features","tooltip":"Railways"},"power":{"description":"Power Features","tooltip":"Power Lines, Power Plants, Substations, etc."},"past_future":{"description":"Past/Future","tooltip":"Proposed, Construction, Abandoned, Demolished, etc."},"others":{"description":"Others","tooltip":"Everything Else"}},"area_fill":{"wireframe":{"description":"No Fill (Wireframe)","tooltip":"Enabling wireframe mode makes it easy to see the background imagery."},"partial":{"description":"Partial Fill","tooltip":"Areas are drawn with fill only around their inner edges. (Recommended for beginner mappers)"},"full":{"description":"Full Fill","tooltip":"Areas are drawn fully filled."}},"restore":{"heading":"You have unsaved changes","description":"Do you wish to restore unsaved changes from a previous editing session?","restore":"Restore","reset":"Reset"},"save":{"title":"Save","help":"Save changes to OpenStreetMap, making them visible to other users.","no_changes":"No changes to save.","error":"Errors occurred while trying to save","status_code":"Server returned status code {code}","unknown_error_details":"Please ensure you are connected to the internet.","uploading":"Uploading changes to OpenStreetMap.","unsaved_changes":"You have unsaved changes","conflict":{"header":"Resolve conflicting edits","count":"Conflict {num} of {total}","previous":"< Previous","next":"Next >","keep_local":"Keep mine","keep_remote":"Use theirs","restore":"Restore","delete":"Leave Deleted","download_changes":"Or download your changes.","done":"All conflicts resolved!","help":"Another user changed some of the same map features you changed.\nClick on each item below for more details about the conflict, and choose whether to keep\nyour changes or the other user's changes.\n"}},"merge_remote_changes":{"conflict":{"deleted":"This object has been deleted by {user}.","location":"This object was moved by both you and {user}.","nodelist":"Nodes were changed by both you and {user}.","memberlist":"Relation members were changed by both you and {user}.","tags":"You changed the <b>{tag}</b> tag to \"{local}\" and {user} changed it to \"{remote}\"."}},"success":{"edited_osm":"Edited OSM!","just_edited":"You just edited OpenStreetMap!","view_on_osm":"View on OSM","facebook":"Share on Facebook","twitter":"Share on Twitter","google":"Share on Google+","help_html":"Your changes should appear in the \"Standard\" layer in a few minutes. Other layers, and certain features, may take longer.","help_link_text":"Details","help_link_url":"https://wiki.openstreetmap.org/wiki/FAQ#I_have_just_made_some_changes_to_the_map._How_do_I_get_to_see_my_changes.3F"},"confirm":{"okay":"Okay","cancel":"Cancel"},"splash":{"welcome":"Welcome to the iD OpenStreetMap editor","text":"iD is a friendly but powerful tool for contributing to the world's best free world map. This is version {version}. For more information see {website} and report bugs at {github}.","walkthrough":"Start the Walkthrough","start":"Edit Now"},"source_switch":{"live":"live","lose_changes":"You have unsaved changes. Switching the map server will discard them. Are you sure you want to switch servers?","dev":"dev"},"tag_reference":{"description":"Description","on_wiki":"{tag} on wiki.osm.org","used_with":"used with {type}"},"validations":{"untagged_point":"Untagged point","untagged_line":"Untagged line","untagged_area":"Untagged area","many_deletions":"You're deleting {n} objects. Are you sure you want to do this? This will delete them from the map that everyone else sees on openstreetmap.org.","tag_suggests_area":"The tag {tag} suggests line should be area, but it is not an area","untagged_point_tooltip":"Select a feature type that describes what this point is.","untagged_line_tooltip":"Select a feature type that describes what this line is.","untagged_area_tooltip":"Select a feature type that describes what this area is.","deprecated_tags":"Deprecated tags: {tags}"},"zoom":{"in":"Zoom In","out":"Zoom Out"},"cannot_zoom":"Cannot zoom out further in current mode.","full_screen":"Toggle Full Screen","gpx":{"local_layer":"Local GPX file","drag_drop":"Drag and drop a .gpx file on the page, or click the button to the right to browse","zoom":"Zoom to GPX track","browse":"Browse for a .gpx file"},"mapillary_images":{"tooltip":"Street-level photos from Mapillary","title":"Photo Overlay (Mapillary)"},"mapillary_signs":{"tooltip":"Traffic signs from Mapillary (must enable Photo Overlay)","title":"Traffic Sign Overlay (Mapillary)"},"mapillary":{"view_on_mapillary":"View this image on Mapillary"},"help":{"title":"Help","help":"# Help\n\nThis is an editor for [OpenStreetMap](http://www.openstreetmap.org/), the\nfree and editable map of the world. You can use it to add and update\ndata in your area, making an open-source and open-data map of the world\nbetter for everyone.\n\nEdits that you make on this map will be visible to everyone who uses\nOpenStreetMap. In order to make an edit, you'll need to\n[log in](https://www.openstreetmap.org/login).\n\nThe [iD editor](http://ideditor.com/) is a collaborative project with [source\ncode available on GitHub](https://github.com/openstreetmap/iD).\n","editing_saving":"# Editing & Saving\n\nThis editor is designed to work primarily online, and you're accessing\nit through a website right now.\n\n### Selecting Features\n\nTo select a map feature, like a road or point of interest, click\non it on the map. This will highlight the selected feature, open a panel with\ndetails about it, and show a menu of things you can do with the feature.\n\nTo select multiple features, hold down the 'Shift' key. Then either click\non the features you want to select, or drag on the map to draw a rectangle.\nThis will draw a box and select all the points within it.\n\n### Saving Edits\n\nWhen you make changes like editing roads, buildings, and places, these are\nstored locally until you save them to the server. Don't worry if you make\na mistake - you can undo changes by clicking the undo button, and redo\nchanges by clicking the redo button.\n\nClick 'Save' to finish a group of edits - for instance, if you've completed\nan area of town and would like to start on a new area. You'll have a chance\nto review what you've done, and the editor supplies helpful suggestions\nand warnings if something doesn't seem right about the changes.\n\nIf everything looks good, you can enter a short comment explaining the change\nyou made, and click 'Save' again to post the changes\nto [OpenStreetMap.org](http://www.openstreetmap.org/), where they are visible\nto all other users and available for others to build and improve upon.\n\nIf you can't finish your edits in one sitting, you can leave the editor\nwindow and come back (on the same browser and computer), and the\neditor application will offer to restore your work.\n\n### Using the editor\n\nA list of available keyboard shortcuts can be found [here](http://wiki.openstreetmap.org/wiki/ID/Shortcuts).\n","roads":"# Roads\n\nYou can create, fix, and delete roads with this editor. Roads can be all\nkinds: paths, highways, trails, cycleways, and more - any often-crossed\nsegment should be mappable.\n\n### Selecting\n\nClick on a road to select it. An outline should become visible, along\nwith a small tools menu on the map and a sidebar showing more information\nabout the road.\n\n### Modifying\n\nOften you'll see roads that aren't aligned to the imagery behind them\nor to a GPS track. You can adjust these roads so they are in the correct\nplace.\n\nFirst click on the road you want to change. This will highlight it and show\ncontrol points along it that you can drag to better locations. If\nyou want to add new control points for more detail, double-click a part\nof the road without a node, and one will be added.\n\nIf the road connects to another road, but doesn't properly connect on\nthe map, you can drag one of its control points onto the other road in\norder to join them. Having roads connect is important for the map\nand essential for providing driving directions.\n\nYou can also click the 'Move' tool or press the `M` shortcut key to move the entire road at\none time, and then click again to save that movement.\n\n### Deleting\n\nIf a road is entirely incorrect - you can see that it doesn't exist in satellite\nimagery and ideally have confirmed locally that it's not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the road could simply be newly built.\n\nYou can delete a road by clicking on it to select it, then clicking the\ntrash can icon or pressing the 'Delete' key.\n\n### Creating\n\nFound somewhere there should be a road but there isn't? Click the 'Line'\nicon in the top-left of the editor or press the shortcut key `2` to start drawing\na line.\n\nClick on the start of the road on the map to start drawing. If the road\nbranches off from an existing road, start by clicking on the place where they connect.\n\nThen click on points along the road so that it follows the right path, according\nto satellite imagery or GPS. If the road you are drawing crosses another road, connect\nit by clicking on the intersection point. When you're done drawing, double-click\nor press 'Return' or 'Enter' on your keyboard.\n","gps":"# GPS\n\nCollected GPS traces are one valuable source of data for OpenStreetMap. This editor\nsupports local traces - `.gpx` files on your local computer. You can collect\nthis kind of GPS trace with a number of smartphone applications as well as\npersonal GPS hardware.\n\nFor information on how to perform a GPS survey, read\n[Mapping with a smartphone, GPS, or paper](http://learnosm.org/en/mobile-mapping/).\n\nTo use a GPX track for mapping, drag and drop the GPX file onto the map\neditor. If it's recognized, it will be added to the map as a bright purple\nline. Click on the 'Map Data' menu on the right side to enable,\ndisable, or zoom to this new GPX-powered layer.\n\nThe GPX track isn't directly uploaded to OpenStreetMap - the best way to\nuse it is to draw on the map, using it as a guide for the new features that\nyou add, and also to [upload it to OpenStreetMap](http://www.openstreetmap.org/trace/create)\nfor other users to use.\n","imagery":"# Imagery\n\nAerial imagery is an important resource for mapping. A combination of\nairplane flyovers, satellite views, and freely-compiled sources are available\nin the editor under the 'Background Settings' menu on the right.\n\nBy default a [Bing Maps](http://www.bing.com/maps/) satellite layer is\npresented in the editor, but as you pan and zoom the map to new geographical\nareas, new sources will become available. Some countries, like the United\nStates, France, and Denmark have very high-quality imagery available for some areas.\n\nImagery is sometimes offset from the map data because of a mistake on the\nimagery provider's side. If you see a lot of roads shifted from the background,\ndon't immediately move them all to match the background. Instead you can adjust\nthe imagery so that it matches the existing data by clicking 'Fix alignment' at\nthe bottom of the Background Settings UI.\n","addresses":"# Addresses\n\nAddresses are some of the most useful information for the map.\n\nAlthough addresses are often represented as parts of streets, in OpenStreetMap\nthey're recorded as attributes of buildings and places along streets.\n\nYou can add address information to places mapped as building outlines\nas well as those mapped as single points. The optimal source of address\ndata is from an on-the-ground survey or personal knowledge - as with any\nother feature, copying from commercial sources like Google Maps is strictly\nforbidden.\n","inspector":"# Using the Inspector\n\nThe inspector is the section on the left side of the page that allows you to\nedit the details of the selected feature.\n\n### Selecting a Feature Type\n\nAfter you add a point, line, or area, you can choose what type of feature it\nis, like whether it's a highway or residential road, supermarket or cafe.\nThe inspector will display buttons for common feature types, and you can\nfind others by typing what you're looking for in the search box.\n\nClick the 'i' in the bottom-right-hand corner of a feature type button to\nlearn more about it. Click a button to choose that type.\n\n### Using Forms and Editing Tags\n\nAfter you choose a feature type, or when you select a feature that already\nhas a type assigned, the inspector will display fields with details about\nthe feature like its name and address.\n\nBelow the fields you see, you can click the 'Add field' dropdown to add\nother details, like a Wikipedia link, wheelchair access, and more.\n\nAt the bottom of the inspector, click 'Additional tags' to add arbitrary\nother tags to the element. [Taginfo](http://taginfo.openstreetmap.org/) is a\ngreat resource for learn more about popular tag combinations.\n\nChanges you make in the inspector are automatically applied to the map.\nYou can undo them at any time by clicking the 'Undo' button.\n","buildings":"# Buildings\n\nOpenStreetMap is the world's largest database of buildings. You can create\nand improve this database.\n\n### Selecting\n\nYou can select a building by clicking on its border. This will highlight the\nbuilding and open a small tools menu and a sidebar showing more information\nabout the building.\n\n### Modifying\n\nSometimes buildings are incorrectly placed or have incorrect tags.\n\nTo move an entire building, select it, then click the 'Move' tool. Move your\nmouse to shift the building, and click when it's correctly placed.\n\nTo fix the specific shape of a building, click and drag the nodes that form\nits border into better places.\n\n### Creating\n\nOne of the main questions around adding buildings to the map is that\nOpenStreetMap records buildings both as shapes and points. The rule of thumb\nis to _map a building as a shape whenever possible_, and map companies, homes,\namenities, and other things that operate out of buildings as points placed\nwithin the building shape.\n\nStart drawing a building as a shape by clicking the 'Area' button in the top\nleft of the interface, and end it either by pressing 'Return' on your keyboard\nor clicking on the first node drawn to close the shape.\n\n### Deleting\n\nIf a building is entirely incorrect - you can see that it doesn't exist in satellite\nimagery and ideally have confirmed locally that it's not present - you can delete\nit, which removes it from the map. Be cautious when deleting features -\nlike any other edit, the results are seen by everyone and satellite imagery\nis often out of date, so the building could simply be newly built.\n\nYou can delete a building by clicking on it to select it, then clicking the\ntrash can icon or pressing the 'Delete' key.\n","relations":"# Relations\n\nA relation is a special type of feature in OpenStreetMap that groups together\nother features. For example, two common types of relations are *route relations*,\nwhich group together sections of road that belong to a specific freeway or\nhighway, and *multipolygons*, which group together several lines that define\na complex area (one with several pieces or holes in it like a donut).\n\nThe group of features in a relation are called *members*. In the sidebar, you can\nsee which relations a feature is a member of, and click on a relation there\nto select the it. When the relation is selected, you can see all of its\nmembers listed in the sidebar and highlighted on the map.\n\nFor the most part, iD will take care of maintaining relations automatically\nwhile you edit. The main thing you should be aware of is that if you delete a\nsection of road to redraw it more accurately, you should make sure that the\nnew section is a member of the same relations as the original.\n\n## Editing Relations\n\nIf you want to edit relations, here are the basics.\n\nTo add a feature to a relation, select the feature, click the \"+\" button in the\n\"All relations\" section of the sidebar, and select or type the name of the relation.\n\nTo create a new relation, select the first feature that should be a member,\nclick the \"+\" button in the \"All relations\" section, and select \"New relation...\".\n\nTo remove a feature from a relation, select the feature and click the trash\nbutton next to the relation you want to remove it from.\n\nYou can create multipolygons with holes using the \"Merge\" tool. Draw two areas (inner\nand outer), hold the Shift key and click on each of them to select them both, and then\nclick the \"Merge\" (+) button.\n"},"intro":{"done":"done","graph":{"city_hall":"Three Rivers City Hall","fire_department":"Three Rivers Fire Department","memory_isle_park":"Memory Isle Park","riverwalk_trail":"Riverwalk Trail","w_michigan_ave":"West Michigan Avenue","e_michigan_ave":"East Michigan Avenue","spring_st":"Spring Street","scidmore_park":"Scidmore Park","petting_zoo":"Scidmore Park Petting Zoo","n_andrews_st":"North Andrews Street","s_andrews_st":"South Andrews Street","n_constantine_st":"North Constantine Street","s_constantine_st":"South Constantine Street","rocky_river":"Rocky River","railroad_dr":"Railroad Drive","conrail_rr":"Conrail Railroad","st_joseph_river":"Saint Joseph River","n_main_st":"North Main Street","s_main_st":"South Main Street","water_st":"Water Street","foster_st":"Foster Street","portage_river":"Portage River","flower_st":"Flower Street","elm_st":"Elm Street","walnut_st":"Walnut Street","morris_ave":"Morris Avenue","east_st":"East Street","portage_ave":"Portage Avenue"},"navigation":{"title":"Navigation","drag":"The main map area shows OpenStreetMap data on top of a background. You can navigate by dragging and scrolling, just like any web map. **Drag the map!**","select":"Map features are represented three ways: using points, lines or areas. All features can be selected by clicking on them. **Click on the point to select it.**","pane":"When a feature is selected, the feature editor is displayed. The header shows us the feature type and the main pane shows the feature's attributes, such as its name and address. **Close the feature editor by pressing the {button} button in the top right.**","search":"You can also search for features in the current view, or worldwide. **Search for '{name}'**","choose":"**Choose {name} from the list to select it.**","chosen":"Great! {name} is now selected. **Close the feature editor by pressing the {button} button.**"},"points":{"title":"Points","add":"Points can be used to represent features such as shops, restaurants, and monuments. They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**","place":"The point can be placed by clicking on the map. **Click the map to place the new point on top of the building.**","search":"There are many different features that can be represented by points. The point you just added is a Cafe. **Search for '{name}'**","choose":"**Choose Cafe from the list.**","describe":"The point is now marked as a cafe. Using the feature editor, we can add more information about the feature. **Add a name**","close":"The feature editor will remember all of your changes automatically. When you change a feature, the close button will change to a checkmark. **Click the {button} button to close the feature editor**","reselect":"Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Click to select the point you just created.**","fixname":"**Change the name, then click the {button} button to close the feature editor.**","reselect_delete":"All features on the map can be deleted. **Click to select the point you created.**","delete":"The menu around the point contains operations that can be performed on it, including delete. **Click on the {button} button to delete the point.**"},"areas":{"title":"Areas","add":"Areas are used to show the boundaries of features like lakes, buildings, and residential areas. They can be also be used for more detailed mapping of many features you might normally map as points. **Click the {button} Area button to add a new area.**","corner":"Areas are drawn by placing nodes that mark the boundary of the area. **Click to place a starting node on one of the corners of the playground.**","place":"Draw the area by placing more nodes. Finish the area by clicking on the starting node. **Draw an area for the playground.**","search":"**Search for '{name}'.**","choose":"**Choose Playground from the list.**","describe":"**Add a name, then click the {button} button to close the feature editor**"},"lines":{"title":"Lines","add":"Lines are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**","start":"**Start the line by clicking on the end of the road.**","intersect":"Click to add more nodes to the line. You can drag the map while drawing if necessary. Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**","finish":"Lines can be finished by clicking on the last node again. **Finish drawing the road.**","road":"**Select Road from the list**","residential":"There are different types of roads, the most common of which is Residential. **Choose the Residential road type**","describe":"**Name the road, then click the {button} button to close the feature editor.**","restart":"The road needs to intersect {name}.","wrong_preset":"You didn't select the Residential road type. **Click here to choose again**"},"startediting":{"title":"Start Editing","help":"You can replay this walkthrough or view more documentation by clicking the {button} Help button.","save":"Don't forget to regularly save your changes!","start":"Start mapping!"}},"presets":{"categories":{"category-barrier":{"name":"Barrier Features"},"category-building":{"name":"Building Features"},"category-golf":{"name":"Golf Features"},"category-landuse":{"name":"Land Use Features"},"category-path":{"name":"Path Features"},"category-rail":{"name":"Rail Features"},"category-restriction":{"name":"Restriction Features"},"category-road":{"name":"Road Features"},"category-route":{"name":"Route Features"},"category-water-area":{"name":"Water Features"},"category-water-line":{"name":"Water Features"}},"fields":{"access_simple":{"label":"Allowed Access"},"access_toilets":{"label":"Access"},"access":{"label":"Allowed Access","placeholder":"Not Specified","types":{"access":"All","foot":"Foot","motor_vehicle":"Motor Vehicles","bicycle":"Bicycles","horse":"Horses"},"options":{"yes":{"title":"Allowed","description":"Access permitted by law; a right of way"},"no":{"title":"Prohibited","description":"Access not permitted to the general public"},"permissive":{"title":"Permissive","description":"Access permitted until such time as the owner revokes the permission"},"private":{"title":"Private","description":"Access permitted only with permission of the owner on an individual basis"},"designated":{"title":"Designated","description":"Access permitted according to signs or specific local laws"},"destination":{"title":"Destination","description":"Access permitted only to reach a destination"},"dismount":{"title":"Dismount","description":"Access permitted but rider must dismount"}}},"address":{"label":"Address","placeholders":{"city":"City","conscriptionnumber":"123","country":"Country","district":"District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","place":"Place","postcode":"Postcode","province":"Province","state":"State","street":"Street","subdistrict":"Subdistrict","suburb":"Suburb"}},"admin_level":{"label":"Admin Level"},"aerialway":{"label":"Type"},"aerialway/access":{"label":"Access","options":{"entry":"Entry","exit":"Exit","both":"Both"}},"aerialway/bubble":{"label":"Bubble"},"aerialway/capacity":{"label":"Capacity (per hour)","placeholder":"500, 2500, 5000..."},"aerialway/duration":{"label":"Duration (minutes)","placeholder":"1, 2, 3..."},"aerialway/heating":{"label":"Heated"},"aerialway/occupancy":{"label":"Occupancy","placeholder":"2, 4, 8..."},"aerialway/summer/access":{"label":"Access (summer)","options":{"entry":"Entry","exit":"Exit","both":"Both"}},"aeroway":{"label":"Type"},"amenity":{"label":"Type"},"area/highway":{"label":"Type"},"artist":{"label":"Artist"},"artwork_type":{"label":"Type"},"atm":{"label":"ATM"},"backrest":{"label":"Backrest"},"barrier":{"label":"Type"},"bath/open_air":{"label":"Open Air"},"bath/sand_bath":{"label":"Sand Bath"},"bath/type":{"label":"Specialty","options":{"onsen":"Japanese Onsen","foot_bath":"Foot Bath","hot_spring":"Hot Spring"}},"beauty":{"label":"Shop Type"},"bench":{"label":"Bench"},"bicycle_parking":{"label":"Type"},"bin":{"label":"Waste Bin"},"blood_components":{"label":"Blood Components","options":{"whole":"whole blood","plasma":"plasma","platelets":"platelets","stemcells":"stem cell samples"}},"board_type":{"label":"Type"},"boundary":{"label":"Type"},"brand":{"label":"Brand"},"building_area":{"label":"Building"},"building":{"label":"Building"},"camera/direction":{"label":"Direction (Degrees Clockwise)","placeholder":"45, 90, 180, 270"},"camera/mount":{"label":"Camera Mount"},"camera/type":{"label":"Camera Type","options":{"fixed":"Fixed","panning":"Panning","dome":"Dome"}},"capacity":{"label":"Capacity","placeholder":"50, 100, 200..."},"cardinal_direction":{"label":"Direction","options":{"N":"North","E":"East","S":"South","W":"West","NE":"Northeast","SE":"Southeast","SW":"Southwest","NW":"Northwest","NNE":"North-northeast","ENE":"East-northeast","ESE":"East-southeast","SSE":"South-southeast","SSW":"South-southwest","WSW":"West-southwest","WNW":"West-northwest","NNW":"North-northwest"}},"clock_direction":{"label":"Direction","options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}},"collection_times":{"label":"Collection Times"},"construction":{"label":"Type"},"contact/webcam":{"label":"Webcam URL","placeholder":"http://example.com/"},"content":{"label":"Contents"},"country":{"label":"Country"},"covered":{"label":"Covered"},"craft":{"label":"Type"},"crop":{"label":"Crop"},"crossing":{"label":"Type"},"cuisine":{"label":"Cuisine"},"currency_multi":{"label":"Currency Types"},"cycle_network":{"label":"Network"},"cycleway":{"label":"Bike Lanes","placeholder":"none","types":{"cycleway:left":"Left side","cycleway:right":"Right side"},"options":{"none":{"title":"None","description":"No bike lane"},"lane":{"title":"Standard bike lane","description":"A bike lane separated from auto traffic by a painted line"},"shared_lane":{"title":"Shared bike lane","description":"A bike lane with no separation from auto traffic"},"track":{"title":"Bike track","description":"A bike lane separated from traffic by a physical barrier"},"share_busway":{"title":"Bike lane shared with bus","description":"A bike lane shared with a bus lane"},"opposite_lane":{"title":"Opposite bike lane","description":"A bike lane that travels in the opposite direction of traffic"},"opposite":{"title":"Contraflow bike lane","description":"A bike lane that travels in both directions on a one-way street"}}},"date":{"label":"Date"},"delivery":{"label":"Delivery"},"denomination":{"label":"Denomination"},"denotation":{"label":"Denotation"},"description":{"label":"Description"},"diaper":{"label":"Diaper Changing Available"},"display":{"label":"Display"},"dock":{"label":"Type"},"drive_through":{"label":"Drive-Through"},"electrified":{"label":"Electrification","placeholder":"Contact Line, Electrified Rail...","options":{"contact_line":"Contact Line","rail":"Electrified Rail","yes":"Yes (unspecified)","no":"No"}},"elevation":{"label":"Elevation"},"emergency":{"label":"Emergency"},"entrance":{"label":"Type"},"except":{"label":"Exceptions"},"fax":{"label":"Fax","placeholder":"+31 42 123 4567"},"fee":{"label":"Fee"},"fence_type":{"label":"Type"},"fire_hydrant/type":{"label":"Type","options":{"pillar":"Pillar/Aboveground","underground":"Underground","wall":"Wall","pond":"Pond"}},"fixme":{"label":"Fix Me"},"fuel_multi":{"label":"Fuel Types"},"fuel":{"label":"Fuel"},"gauge":{"label":"Gauge"},"gender":{"label":"Gender","placeholder":"Unknown","options":{"male":"Male","female":"Female","unisex":"Unisex"}},"generator/method":{"label":"Method"},"generator/source":{"label":"Source"},"generator/type":{"label":"Type"},"golf_hole":{"label":"Reference","placeholder":"Hole number (1-18)"},"handicap":{"label":"Handicap","placeholder":"1-18"},"handrail":{"label":"Handrail"},"height":{"label":"Height (Meters)"},"highway":{"label":"Type"},"historic":{"label":"Type"},"hoops":{"label":"Hoops","placeholder":"1, 2, 4..."},"iata":{"label":"IATA"},"icao":{"label":"ICAO"},"incline_steps":{"label":"Incline","options":{"up":"Up","down":"Down"}},"incline":{"label":"Incline"},"indoor":{"label":"Indoor"},"information":{"label":"Type"},"internet_access":{"label":"Internet Access","options":{"yes":"Yes","no":"No","wlan":"Wifi","wired":"Wired","terminal":"Terminal"}},"internet_access/fee":{"label":"Internet Access Fee"},"internet_access/ssid":{"label":"SSID (Network Name)"},"kerb":{"label":"Curb Ramp"},"lamp_type":{"label":"Type"},"landuse":{"label":"Type"},"lanes":{"label":"Lanes","placeholder":"1, 2, 3..."},"layer":{"label":"Layer"},"leaf_cycle_singular":{"label":"Leaf Cycle","options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous"}},"leaf_cycle":{"label":"Leaf Cycle","options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous","mixed":"Mixed"}},"leaf_type_singular":{"label":"Leaf Type","options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","leafless":"Leafless"}},"leaf_type":{"label":"Leaf Type","options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","mixed":"Mixed","leafless":"Leafless"}},"leisure":{"label":"Type"},"length":{"label":"Length (Meters)"},"level":{"label":"Level"},"levels":{"label":"Levels","placeholder":"2, 4, 6..."},"lit":{"label":"Lit"},"location":{"label":"Location"},"man_made":{"label":"Type"},"map_size":{"label":"Coverage"},"map_type":{"label":"Type"},"maxheight":{"label":"Max Height","placeholder":"4, 4.5, 5, 14'0\", 14'6\", 15'0\""},"maxspeed":{"label":"Speed Limit","placeholder":"40, 50, 60..."},"maxstay":{"label":"Max Stay"},"mtb/scale":{"label":"Mountain Biking Difficulty","placeholder":"0, 1, 2, 3...","options":{"0":"0: Solid gravel/packed earth, no obstacles, wide curves","1":"1: Some loose surface, small obstacles, wide curves","2":"2: Much loose surface, large obstacles, easy hairpins","3":"3: Slippery surface, large obstacles, tight hairpins","4":"4: Loose surface or boulders, dangerous hairpins","5":"5: Maximum difficulty, boulder fields, landslides","6":"6: Not rideable except by the very best mountain bikers"}},"mtb/scale/imba":{"label":"IMBA Trail Difficulty","placeholder":"Easy, Medium, Difficult...","options":{"0":"Easiest (white circle)","1":"Easy (green circle)","2":"Medium (blue square)","3":"Difficult (black diamond)","4":"Extremely Difficult (double black diamond)"}},"mtb/scale/uphill":{"label":"Mountain Biking Uphill Difficulty","placeholder":"0, 1, 2, 3...","options":{"0":"0: Avg. incline <10%, gravel/packed earth, no obstacles","1":"1: Avg. incline <15%, gravel/packed earth, few small objects","2":"2: Avg. incline <20%, stable surface, fistsize rocks/roots","3":"3: Avg. incline <25%, variable surface, fistsize rocks/branches","4":"4: Avg. incline <30%, poor condition, big rocks/branches","5":"5: Very steep, bike generally needs to be pushed or carried"}},"name":{"label":"Name","placeholder":"Common name (if any)"},"natural":{"label":"Natural"},"network_bicycle":{"label":"Network Type","placeholder":"Local, Regional, National, International","options":{"lcn":"Local","rcn":"Regional","ncn":"National","icn":"International"}},"network_foot":{"label":"Network Type","placeholder":"Local, Regional, National, International","options":{"lwn":"Local","rwn":"Regional","nwn":"National","iwn":"International"}},"network_horse":{"label":"Network Type","placeholder":"Local, Regional, National, International","options":{"lhn":"Local","rhn":"Regional","nhn":"National","ihn":"International"}},"network_road":{"label":"Network"},"network":{"label":"Network"},"note":{"label":"Note"},"office":{"label":"Type"},"oneway_yes":{"label":"One Way","options":{"undefined":"Assumed to be Yes","yes":"Yes","no":"No"}},"oneway":{"label":"One Way","options":{"undefined":"Assumed to be No","yes":"Yes","no":"No"}},"opening_hours":{"label":"Hours"},"operator":{"label":"Operator"},"outdoor_seating":{"label":"Outdoor Seating"},"par":{"label":"Par","placeholder":"3, 4, 5..."},"parallel_direction":{"label":"Direction","options":{"forward":"Forward","backward":"Backward"}},"park_ride":{"label":"Park and Ride"},"parking":{"label":"Type","options":{"surface":"Surface","multi-storey":"Multilevel","underground":"Underground","sheds":"Sheds","carports":"Carports","garage_boxes":"Garage Boxes","lane":"Roadside Lane"}},"payment_multi":{"label":"Payment Types"},"phone":{"label":"Phone","placeholder":"+31 42 123 4567"},"piste/difficulty":{"label":"Difficulty","placeholder":"Easy, Intermediate, Advanced...","options":{"novice":"Novice (instructional)","easy":"Easy (green circle)","intermediate":"Intermediate (blue square)","advanced":"Advanced (black diamond)","expert":"Expert (double black diamond)","freeride":"Freeride (off-piste)","extreme":"Extreme (climbing equipment required)"}},"piste/grooming":{"label":"Grooming","options":{"classic":"Classic","mogul":"Mogul","backcountry":"Backcountry","classic+skating":"Classic and Skating","scooter":"Scooter/Snowmobile","skating":"Skating"}},"piste/type":{"label":"Type","options":{"downhill":"Downhill","nordic":"Nordic","skitour":"Skitour","sled":"Sled","hike":"Hike","sleigh":"Sleigh","ice_skate":"Ice Skate","snow_park":"Snow Park","playground":"Playground"}},"place":{"label":"Type"},"population":{"label":"Population"},"power_supply":{"label":"Power Supply"},"power":{"label":"Type"},"railway":{"label":"Type"},"recycling_accepts":{"label":"Accepts"},"recycling_type":{"label":"Recycling Type","options":{"container":"Container","centre":"Recycling Center"}},"ref":{"label":"Reference"},"relation":{"label":"Type"},"religion":{"label":"Religion"},"restriction":{"label":"Type"},"restrictions":{"label":"Turn Restrictions"},"rooms":{"label":"Rooms"},"route_master":{"label":"Type"},"route":{"label":"Type"},"sac_scale":{"label":"Hiking Difficulty","placeholder":"Mountain Hiking, Alpine Hiking...","options":{"hiking":"T1: Hiking","mountain_hiking":"T2: Mountain Hiking","demanding_mountain_hiking":"T3: Demanding Mountain Hiking","alpine_hiking":"T4: Alpine Hiking","demanding_alpine_hiking":"T5: Demanding Alpine Hiking","difficult_alpine_hiking":"T6: Difficult Alpine Hiking"}},"sanitary_dump_station":{"label":"Toilet Disposal"},"seasonal":{"label":"Seasonal"},"second_hand":{"label":"Sells Used","placeholder":"Yes, No, Only","options":{"yes":"Yes","no":"No","only":"Only"}},"service_rail":{"label":"Service Type","options":{"spur":"Spur","yard":"Yard","siding":"Siding","crossover":"Crossover"}},"service":{"label":"Type"},"service/bicycle":{"label":"Services"},"shelter_type":{"label":"Type"},"shelter":{"label":"Shelter"},"shop":{"label":"Type"},"site":{"label":"Type"},"smoking":{"label":"Smoking","placeholder":"No, Separated, Yes...","options":{"no":"No smoking anywhere","separated":"In smoking areas, not physically isolated","isolated":"In smoking areas, physically isolated","outside":"Allowed outside","yes":"Allowed everywhere","dedicated":"Dedicated to smokers (e.g. smokers' club)"}},"smoothness":{"label":"Smoothness","placeholder":"Thin Rollers, Wheels, Off-Road...","options":{"excellent":"Thin Rollers: rollerblade, skateboard","good":"Thin Wheels: racing bike","intermediate":"Wheels: city bike, wheelchair, scooter","bad":"Robust Wheels: trekking bike, car, rickshaw","very_bad":"High Clearance: light duty off-road vehicle","horrible":"Off-Road: heavy duty off-road vehicle","very_horrible":"Specialized off-road: tractor, ATV","impassable":"Impassable / No wheeled vehicle"}},"social_facility_for":{"label":"People served","placeholder":"Homeless, Disabled, Child, etc"},"source":{"label":"Source"},"sport_ice":{"label":"Sport"},"sport_racing":{"label":"Sport"},"sport":{"label":"Sport"},"stars":{"label":"Stars"},"stop":{"label":"Stop Type","options":{"all":"All Ways","minor":"Minor Road"}},"structure":{"label":"Structure","placeholder":"Unknown","options":{"bridge":"Bridge","tunnel":"Tunnel","embankment":"Embankment","cutting":"Cutting","ford":"Ford"}},"studio":{"label":"Type"},"substation":{"label":"Type"},"supervised":{"label":"Supervised"},"support":{"label":"Support"},"surface":{"label":"Surface"},"surveillance":{"label":"Surveillance Kind"},"surveillance/type":{"label":"Surveillance Type","options":{"camera":"Camera","guard":"Guard","ALPR":"Automatic License Plate Reader"}},"surveillance/zone":{"label":"Surveillance Zone"},"tactile_paving":{"label":"Tactile Paving"},"takeaway":{"label":"Takeaway","placeholder":"Yes, No, Takeaway Only...","options":{"yes":"Yes","no":"No","only":"Takeaway Only"}},"toilets/disposal":{"label":"Disposal","options":{"flush":"Flush","pitlatrine":"Pit/Latrine","chemical":"Chemical","bucket":"Bucket"}},"tourism":{"label":"Type"},"tower/construction":{"label":"Construction","placeholder":"Guyed, Lattice, Concealed, ..."},"tower/type":{"label":"Type"},"tracktype":{"label":"Track Type","placeholder":"Solid, Mostly Solid, Soft...","options":{"grade1":"Solid: paved or heavily compacted hardcore surface","grade2":"Mostly Solid: gravel/rock with some soft material mixed in","grade3":"Even mixture of hard and soft materials","grade4":"Mostly Soft: soil/sand/grass with some hard material mixed in","grade5":"Soft: soil/sand/grass"}},"traffic_calming":{"label":"Type"},"traffic_signals":{"label":"Type"},"trail_visibility":{"label":"Trail Visibility","placeholder":"Excellent, Good, Bad...","options":{"excellent":"Excellent: unambiguous path or markers everywhere","good":"Good: markers visible, sometimes require searching","intermediate":"Intermediate: few markers, path mostly visible","bad":"Bad: no markers, path sometimes invisible/pathless","horrible":"Horrible: often pathless, some orientation skills required","no":"No: pathless, excellent orientation skills required"}},"trees":{"label":"Trees"},"tunnel":{"label":"Tunnel"},"vending":{"label":"Type of Goods"},"visibility":{"label":"Visibility","options":{"house":"Up to 5m (16ft)","street":"5 to 20m (16 to 65ft)","area":"Over 20m (65ft)"}},"wall":{"label":"Type"},"water_point":{"label":"Water Point"},"water":{"label":"Type"},"waterway":{"label":"Type"},"website":{"label":"Website","placeholder":"http://example.com/"},"wetland":{"label":"Type"},"wheelchair":{"label":"Wheelchair Access"},"width":{"label":"Width (Meters)"},"wikipedia":{"label":"Wikipedia"}},"presets":{"aerialway":{"name":"Aerialway","terms":"ski lift,funifor,funitel"},"aeroway":{"name":"Aeroway","terms":""},"amenity":{"name":"Amenity","terms":""},"highway":{"name":"Highway","terms":""},"place":{"name":"Place","terms":""},"power":{"name":"Power","terms":""},"railway":{"name":"Railway","terms":""},"roundabout":{"name":"Roundabout","terms":""},"waterway":{"name":"Waterway","terms":""},"address":{"name":"Address","terms":""},"advertising/billboard":{"name":"Billboard","terms":""},"aerialway/cable_car":{"name":"Cable Car","terms":"tramway,ropeway"},"aerialway/chair_lift":{"name":"Chair Lift","terms":""},"aerialway/gondola":{"name":"Gondola","terms":""},"aerialway/magic_carpet":{"name":"Magic Carpet Lift","terms":""},"aerialway/platter":{"name":"Platter Lift","terms":"button lift,poma lift"},"aerialway/pylon":{"name":"Aerialway Pylon","terms":""},"aerialway/rope_tow":{"name":"Rope Tow Lift","terms":"handle tow,bugel lift"},"aerialway/station":{"name":"Aerialway Station","terms":""},"aerialway/t-bar":{"name":"T-bar Lift","terms":""},"aeroway/aerodrome":{"name":"Airport","terms":"airplane,airport,aerodrome"},"aeroway/apron":{"name":"Apron","terms":"ramp"},"aeroway/gate":{"name":"Airport gate","terms":""},"aeroway/hangar":{"name":"Hangar","terms":""},"aeroway/helipad":{"name":"Helipad","terms":"helicopter,helipad,heliport"},"aeroway/runway":{"name":"Runway","terms":"landing strip"},"aeroway/taxiway":{"name":"Taxiway","terms":""},"aeroway/terminal":{"name":"Airport terminal","terms":"airport,aerodrome"},"amenity/register_office":{"name":"Register Office","terms":""},"amenity/swimming_pool":{"name":"Swimming Pool","terms":""},"amenity/arts_centre":{"name":"Arts Center","terms":""},"amenity/atm":{"name":"ATM","terms":"money,cash,machine"},"amenity/bank":{"name":"Bank","terms":"credit union,check,deposit,fund,investment,repository,reserve,safe,savings,stock,treasury,trust,vault"},"amenity/bar":{"name":"Bar","terms":"dive,beer,bier,booze"},"amenity/bbq":{"name":"Barbecue/Grill","terms":"bbq,grill"},"amenity/bench":{"name":"Bench","terms":"seat"},"amenity/bicycle_parking":{"name":"Bicycle Parking","terms":"bike"},"amenity/bicycle_rental":{"name":"Bicycle Rental","terms":"bike"},"amenity/bicycle_repair_station":{"name":"Bicycle Repair Tool Stand","terms":"bike,repair,chain,pump"},"amenity/biergarten":{"name":"Beer Garden","terms":"beer,bier,booze"},"amenity/boat_rental":{"name":"Boat Rental","terms":""},"amenity/bureau_de_change":{"name":"Currency Exchange","terms":"bureau de change,money changer"},"amenity/bus_station":{"name":"Bus Station","terms":""},"amenity/cafe":{"name":"Cafe","terms":"bistro,coffee,tea"},"amenity/car_rental":{"name":"Car Rental","terms":""},"amenity/car_sharing":{"name":"Car Sharing","terms":""},"amenity/car_wash":{"name":"Car Wash","terms":""},"amenity/casino":{"name":"Casino","terms":"gambling,roulette,craps,poker,blackjack"},"amenity/charging_station":{"name":"Charging Station","terms":"EV,Electric Vehicle,Supercharger"},"amenity/childcare":{"name":"Nursery/Childcare","terms":"daycare,orphanage,playgroup"},"amenity/cinema":{"name":"Cinema","terms":"drive-in,film,flick,movie,theater,picture,show,screen"},"amenity/clinic":{"name":"Clinic","terms":"medical,urgentcare"},"amenity/clock":{"name":"Clock","terms":""},"amenity/college":{"name":"College Grounds","terms":"university"},"amenity/community_centre":{"name":"Community Center","terms":"event,hall"},"amenity/compressed_air":{"name":"Compressed Air","terms":""},"amenity/courthouse":{"name":"Courthouse","terms":""},"amenity/coworking_space":{"name":"Coworking Space","terms":"coworking,office"},"amenity/crematorium":{"name":"Crematorium","terms":"cemetery,funeral"},"amenity/dentist":{"name":"Dentist","terms":"tooth,teeth"},"amenity/doctors":{"name":"Doctor","terms":"medic*"},"amenity/dojo":{"name":"Dojo / Martial Arts Academy","terms":"martial arts,dojang"},"amenity/drinking_water":{"name":"Drinking Water","terms":"fountain,potable"},"amenity/embassy":{"name":"Embassy","terms":""},"amenity/fast_food":{"name":"Fast Food","terms":"restaurant,takeaway"},"amenity/ferry_terminal":{"name":"Ferry Terminal","terms":""},"amenity/fire_station":{"name":"Fire Station","terms":""},"amenity/food_court":{"name":"Food Court","terms":"fast food,restaurant,food"},"amenity/fountain":{"name":"Fountain","terms":""},"amenity/fuel":{"name":"Gas Station","terms":"petrol,fuel,gasoline,propane,diesel,lng,cng,biodiesel"},"amenity/grave_yard":{"name":"Graveyard","terms":""},"amenity/grit_bin":{"name":"Grit Bin","terms":"salt,sand"},"amenity/hospital":{"name":"Hospital Grounds","terms":"clinic,doctor,emergency room,health service,hospice,infirmary,institution,nursing home,sanatorium,sanitarium,sick,surgery,ward"},"amenity/hunting_stand":{"name":"Hunting Stand","terms":"game,lookout,shoot,wild,watch"},"amenity/ice_cream":{"name":"Ice Cream Shop","terms":"gelato,sorbet,sherbet,frozen,yogurt"},"amenity/internet_cafe":{"name":"Internet Cafe","terms":"cybercafe,taxiphone,teleboutique,coffee,cafe,net,lanhouse"},"amenity/kindergarten":{"name":"Preschool/Kindergarten Grounds","terms":"kindergarden,pre-school"},"amenity/library":{"name":"Library","terms":"book"},"amenity/marketplace":{"name":"Marketplace","terms":""},"amenity/motorcycle_parking":{"name":"Motorcycle Parking","terms":""},"amenity/nightclub":{"name":"Nightclub","terms":"disco*,night club,dancing,dance club"},"amenity/parking_entrance":{"name":"Parking Garage Entrance/Exit","terms":""},"amenity/parking_space":{"name":"Parking Space","terms":""},"amenity/parking":{"name":"Car Parking","terms":""},"amenity/pharmacy":{"name":"Pharmacy","terms":"drug*,med*,prescription"},"amenity/place_of_worship":{"name":"Place of Worship","terms":"abbey,basilica,bethel,cathedral,chancel,chantry,chapel,church,fold,house of God,house of prayer,house of worship,minster,mission,mosque,oratory,parish,sacellum,sanctuary,shrine,synagogue,tabernacle,temple"},"amenity/place_of_worship/buddhist":{"name":"Buddhist Temple","terms":"stupa,vihara,monastery,temple,pagoda,zendo,dojo"},"amenity/place_of_worship/christian":{"name":"Church","terms":"christian,abbey,basilica,bethel,cathedral,chancel,chantry,chapel,fold,house of God,house of prayer,house of worship,minster,mission,oratory,parish,sacellum,sanctuary,shrine,tabernacle,temple"},"amenity/place_of_worship/jewish":{"name":"Synagogue","terms":"jewish"},"amenity/place_of_worship/muslim":{"name":"Mosque","terms":"muslim"},"amenity/planetarium":{"name":"Planetarium","terms":"museum,astronomy,observatory"},"amenity/police":{"name":"Police","terms":"badge,constable,constabulary,cop,detective,fed,law,enforcement,officer,patrol"},"amenity/post_box":{"name":"Mailbox","terms":"letter,post"},"amenity/post_office":{"name":"Post Office","terms":"letter,mail"},"amenity/prison":{"name":"Prison Grounds","terms":"cell,jail"},"amenity/pub":{"name":"Pub","terms":"alcohol,drink,dive,beer,bier,booze"},"amenity/public_bath":{"name":"Public Bath","terms":"onsen,foot bath,hot springs"},"amenity/public_bookcase":{"name":"Public Bookcase","terms":"library,bookcrossing"},"amenity/ranger_station":{"name":"Ranger Station","terms":"visitor center,visitor centre,permit center,permit centre,backcountry office,warden office,warden center"},"amenity/recycling_centre":{"name":"Recycling Center","terms":"bottle,can,dump,glass,garbage,rubbish,scrap,trash"},"amenity/recycling":{"name":"Recycling","terms":"bin,can,bottle,glass,garbage,rubbish,scrap,trash"},"amenity/restaurant":{"name":"Restaurant","terms":"bar,breakfast,cafe,café,canteen,coffee,dine,dining,dinner,drive-in,eat,grill,lunch,table"},"amenity/sanitary_dump_station":{"name":"RV Toilet Disposal","terms":"Motor Home,Camper,Sanitary,Dump Station,Elsan,CDP,CTDP,Chemical Toilet"},"amenity/school":{"name":"School Grounds","terms":"academy,elementary school,middle school,high school"},"amenity/shelter":{"name":"Shelter","terms":"lean-to,gazebo,picnic"},"amenity/social_facility":{"name":"Social Facility","terms":""},"amenity/social_facility/food_bank":{"name":"Food Bank","terms":""},"amenity/social_facility/group_home":{"name":"Elderly Group Home","terms":"old,senior,living"},"amenity/social_facility/homeless_shelter":{"name":"Homeless Shelter","terms":"houseless,unhoused,displaced"},"amenity/studio":{"name":"Studio","terms":"recording,radio,television"},"amenity/taxi":{"name":"Taxi Stand","terms":"cab"},"amenity/telephone":{"name":"Telephone","terms":"phone"},"amenity/theatre":{"name":"Theater","terms":"theatre,performance,play,musical"},"amenity/toilets":{"name":"Toilets","terms":"bathroom,restroom,outhouse,privy,head,lavatory,latrine,water closet,WC,W.C."},"amenity/townhall":{"name":"Town Hall","terms":"village,city,government,courthouse,municipal"},"amenity/university":{"name":"University Grounds","terms":"college"},"amenity/vending_machine/cigarettes":{"name":"Cigarette Vending Machine","terms":"cigarette"},"amenity/vending_machine/condoms":{"name":"Condom Vending Machine","terms":"condom"},"amenity/vending_machine/drinks":{"name":"Drink Vending Machine","terms":"drink,soda,beverage,juice,pop"},"amenity/vending_machine/excrement_bags":{"name":"Excrement Bag Vending Machine","terms":"excrement bags,poop,dog,animal"},"amenity/vending_machine/news_papers":{"name":"Newspaper Vending Machine","terms":"newspaper"},"amenity/vending_machine/parcel_pickup_dropoff":{"name":"Parcel Pickup/Dropoff Vending Machine","terms":"parcel,mail,pickup"},"amenity/vending_machine/parking_tickets":{"name":"Parking Ticket Vending Machine","terms":"parking,ticket"},"amenity/vending_machine/public_transport_tickets":{"name":"Transit Ticket Vending Machine","terms":"bus,train,ferry,rail,ticket,transportation"},"amenity/vending_machine/sweets":{"name":"Snack Vending Machine","terms":"candy,gum,chip,pretzel,cookie,cracker"},"amenity/vending_machine/vending_machine":{"name":"Vending Machine","terms":""},"amenity/veterinary":{"name":"Veterinary","terms":"pet clinic,veterinarian,animal hospital,pet doctor"},"amenity/waste_basket":{"name":"Waste Basket","terms":"bin,garbage,rubbish,litter,trash"},"amenity/waste_disposal":{"name":"Garbage Dumpster","terms":"garbage,rubbish,litter,trash"},"amenity/waste_transfer_station":{"name":"Waste Transfer Station","terms":"dump,garbage,recycling,rubbish,scrap,trash"},"amenity/water_point":{"name":"RV Drinking Water","terms":""},"area":{"name":"Area","terms":""},"area/highway":{"name":"Road Surface","terms":""},"barrier":{"name":"Barrier","terms":""},"barrier/entrance":{"name":"Entrance","terms":""},"barrier/block":{"name":"Block","terms":""},"barrier/bollard":{"name":"Bollard","terms":""},"barrier/cattle_grid":{"name":"Cattle Grid","terms":""},"barrier/city_wall":{"name":"City Wall","terms":""},"barrier/cycle_barrier":{"name":"Cycle Barrier","terms":""},"barrier/ditch":{"name":"Trench","terms":""},"barrier/fence":{"name":"Fence","terms":""},"barrier/gate":{"name":"Gate","terms":""},"barrier/hedge":{"name":"Hedge","terms":""},"barrier/kissing_gate":{"name":"Kissing Gate","terms":""},"barrier/lift_gate":{"name":"Lift Gate","terms":""},"barrier/retaining_wall":{"name":"Retaining Wall","terms":""},"barrier/stile":{"name":"Stile","terms":""},"barrier/toll_booth":{"name":"Toll Booth","terms":""},"barrier/wall":{"name":"Wall","terms":""},"boundary/administrative":{"name":"Administrative Boundary","terms":""},"building":{"name":"Building","terms":""},"building/bunker":{"name":"Bunker","terms":""},"building/entrance":{"name":"Entrance/Exit","terms":""},"building/train_station":{"name":"Train Station","terms":""},"building/apartments":{"name":"Apartments","terms":""},"building/barn":{"name":"Barn","terms":""},"building/cabin":{"name":"Cabin","terms":""},"building/cathedral":{"name":"Cathedral Building","terms":""},"building/chapel":{"name":"Chapel Building","terms":""},"building/church":{"name":"Church Building","terms":""},"building/college":{"name":"College Building","terms":"university"},"building/commercial":{"name":"Commercial Building","terms":""},"building/construction":{"name":"Building Under Construction","terms":""},"building/detached":{"name":"Detached House","terms":"home,single,family,residence,dwelling"},"building/dormitory":{"name":"Dormitory","terms":""},"building/garage":{"name":"Garage","terms":""},"building/garages":{"name":"Garages","terms":""},"building/greenhouse":{"name":"Greenhouse","terms":""},"building/hospital":{"name":"Hospital Building","terms":""},"building/hotel":{"name":"Hotel Building","terms":""},"building/house":{"name":"House","terms":"home,family,residence,dwelling"},"building/hut":{"name":"Hut","terms":""},"building/industrial":{"name":"Industrial Building","terms":""},"building/kindergarten":{"name":"Preschool/Kindergarten Building","terms":"kindergarden,pre-school"},"building/public":{"name":"Public Building","terms":""},"building/residential":{"name":"Residential Building","terms":""},"building/retail":{"name":"Retail Building","terms":""},"building/roof":{"name":"Roof","terms":""},"building/school":{"name":"School Building","terms":"academy,elementary school,middle school,high school"},"building/semidetached_house":{"name":"Semi-Detached House","terms":"home,double,duplex,twin,family,residence,dwelling"},"building/shed":{"name":"Shed","terms":""},"building/stable":{"name":"Stable","terms":""},"building/static_caravan":{"name":"Static Mobile Home","terms":""},"building/terrace":{"name":"Row Houses","terms":"home,terrace,brownstone,family,residence,dwelling"},"building/university":{"name":"University Building","terms":"college"},"building/warehouse":{"name":"Warehouse","terms":""},"camp_site/camp_pitch":{"name":"Camp Pitch","terms":"tent,rv"},"craft":{"name":"Craft","terms":""},"craft/jeweler":{"name":"Jeweler","terms":""},"craft/locksmith":{"name":"Locksmith","terms":""},"craft/optician":{"name":"Optician","terms":""},"craft/tailor":{"name":"Tailor","terms":"clothes,suit"},"craft/basket_maker":{"name":"Basket Maker","terms":""},"craft/beekeeper":{"name":"Beekeeper","terms":""},"craft/blacksmith":{"name":"Blacksmith","terms":""},"craft/boatbuilder":{"name":"Boat Builder","terms":""},"craft/bookbinder":{"name":"Bookbinder","terms":"book repair"},"craft/brewery":{"name":"Brewery","terms":"beer,bier"},"craft/carpenter":{"name":"Carpenter","terms":"woodworker"},"craft/carpet_layer":{"name":"Carpet Layer","terms":""},"craft/caterer":{"name":"Caterer","terms":""},"craft/clockmaker":{"name":"Clockmaker","terms":""},"craft/confectionery":{"name":"Confectionery","terms":"sweets,candy"},"craft/dressmaker":{"name":"Dressmaker","terms":"seamstress"},"craft/electrician":{"name":"Electrician","terms":"power,wire"},"craft/gardener":{"name":"Gardener","terms":"landscaper,grounds keeper"},"craft/glaziery":{"name":"Glaziery","terms":"glass,stained-glass,window"},"craft/handicraft":{"name":"Handicraft","terms":""},"craft/hvac":{"name":"HVAC","terms":"heat*,vent*,air conditioning"},"craft/insulator":{"name":"Insulator","terms":""},"craft/key_cutter":{"name":"Key Cutter","terms":""},"craft/metal_construction":{"name":"Metal Construction","terms":""},"craft/painter":{"name":"Painter","terms":""},"craft/photographer":{"name":"Photographer","terms":""},"craft/photographic_laboratory":{"name":"Photographic Laboratory","terms":"film"},"craft/plasterer":{"name":"Plasterer","terms":""},"craft/plumber":{"name":"Plumber","terms":"pipe"},"craft/pottery":{"name":"Pottery","terms":"ceramic"},"craft/rigger":{"name":"Rigger","terms":""},"craft/roofer":{"name":"Roofer","terms":""},"craft/saddler":{"name":"Saddler","terms":""},"craft/sailmaker":{"name":"Sailmaker","terms":""},"craft/sawmill":{"name":"Sawmill","terms":"lumber"},"craft/scaffolder":{"name":"Scaffolder","terms":""},"craft/sculpter":{"name":"Sculpter","terms":""},"craft/shoemaker":{"name":"Shoemaker","terms":"cobbler"},"craft/stonemason":{"name":"Stonemason","terms":"masonry"},"craft/sweep":{"name":"Chimney Sweep","terms":""},"craft/tiler":{"name":"Tiler","terms":""},"craft/tinsmith":{"name":"Tinsmith","terms":""},"craft/upholsterer":{"name":"Upholsterer","terms":""},"craft/watchmaker":{"name":"Watchmaker","terms":""},"craft/window_construction":{"name":"Window Construction","terms":"glass"},"craft/winery":{"name":"Winery","terms":""},"embankment":{"name":"Embankment","terms":""},"emergency/designated":{"name":"Emergency Access Designated","terms":""},"emergency/destination":{"name":"Emergency Access Destination","terms":""},"emergency/no":{"name":"Emergency Access No","terms":""},"emergency/official":{"name":"Emergency Access Official","terms":""},"emergency/private":{"name":"Emergency Access Private","terms":""},"emergency/yes":{"name":"Emergency Access Yes","terms":""},"emergency/ambulance_station":{"name":"Ambulance Station","terms":"EMS,EMT,rescue"},"emergency/defibrillator":{"name":"Defibrillator","terms":"AED"},"emergency/fire_hydrant":{"name":"Fire Hydrant","terms":""},"emergency/phone":{"name":"Emergency Phone","terms":""},"entrance":{"name":"Entrance/Exit","terms":""},"footway/crossing":{"name":"Street Crossing","terms":""},"footway/crosswalk":{"name":"Pedestrian Crosswalk","terms":"zebra crossing"},"footway/sidewalk":{"name":"Sidewalk","terms":""},"ford":{"name":"Ford","terms":""},"golf/bunker":{"name":"Sand Trap","terms":"hazard,bunker"},"golf/fairway":{"name":"Fairway","terms":""},"golf/green":{"name":"Putting Green","terms":""},"golf/hole":{"name":"Golf Hole","terms":""},"golf/lateral_water_hazard_area":{"name":"Lateral Water Hazard","terms":""},"golf/lateral_water_hazard_line":{"name":"Lateral Water Hazard","terms":""},"golf/rough":{"name":"Rough","terms":""},"golf/tee":{"name":"Tee Box","terms":"teeing ground"},"golf/water_hazard_area":{"name":"Water Hazard","terms":""},"golf/water_hazard_line":{"name":"Water Hazard","terms":""},"healthcare/blood_donation":{"name":"Blood Donor Center","terms":"blood bank,blood donation,blood transfusion,apheresis,plasmapheresis,plateletpheresis,stem cell donation"},"highway/bridleway":{"name":"Bridle Path","terms":"bridleway,equestrian,horse"},"highway/bus_stop":{"name":"Bus Stop","terms":""},"highway/corridor":{"name":"Indoor Corridor","terms":"gallery,hall,hallway,indoor,passage,passageway"},"highway/crossing":{"name":"Street Crossing","terms":""},"highway/crosswalk":{"name":"Pedestrian Crosswalk","terms":"zebra crossing"},"highway/cycleway":{"name":"Cycle Path","terms":"bike"},"highway/footway":{"name":"Foot Path","terms":"hike,hiking,trackway,trail,walk"},"highway/give_way":{"name":"Yield Sign","terms":"give way,yield,sign"},"highway/living_street":{"name":"Living Street","terms":""},"highway/mini_roundabout":{"name":"Mini-Roundabout","terms":""},"highway/motorway_junction":{"name":"Motorway Junction / Exit","terms":""},"highway/motorway_link":{"name":"Motorway Link","terms":"ramp,on ramp,off ramp"},"highway/motorway":{"name":"Motorway","terms":""},"highway/path":{"name":"Path","terms":"hike,hiking,trackway,trail,walk"},"highway/pedestrian":{"name":"Pedestrian Street","terms":""},"highway/primary_link":{"name":"Primary Link","terms":"ramp,on ramp,off ramp"},"highway/primary":{"name":"Primary Road","terms":""},"highway/raceway":{"name":"Motor Raceway","terms":"auto*,race*,nascar"},"highway/residential":{"name":"Residential Road","terms":""},"highway/rest_area":{"name":"Rest Area","terms":"rest stop"},"highway/road":{"name":"Unknown Road","terms":""},"highway/secondary_link":{"name":"Secondary Link","terms":"ramp,on ramp,off ramp"},"highway/secondary":{"name":"Secondary Road","terms":""},"highway/service":{"name":"Service Road","terms":""},"highway/service/alley":{"name":"Alley","terms":""},"highway/service/drive-through":{"name":"Drive-Through","terms":""},"highway/service/driveway":{"name":"Driveway","terms":""},"highway/service/emergency_access":{"name":"Emergency Access","terms":""},"highway/service/parking_aisle":{"name":"Parking Aisle","terms":""},"highway/services":{"name":"Service Area","terms":"services,travel plaza,service station"},"highway/steps":{"name":"Steps","terms":"stairs,staircase"},"highway/stop":{"name":"Stop Sign","terms":"stop,halt,sign"},"highway/street_lamp":{"name":"Street Lamp","terms":"streetlight,street light,lamp,light,gaslight"},"highway/tertiary_link":{"name":"Tertiary Link","terms":"ramp,on ramp,off ramp"},"highway/tertiary":{"name":"Tertiary Road","terms":""},"highway/track":{"name":"Unmaintained Track Road","terms":"woods road,forest road,logging road,fire road,farm road,agricultural road,ranch road,carriage road,primitive,unmaintained,rut,offroad,4wd,4x4,four wheel drive,atv,quad,jeep,double track,two track"},"highway/traffic_mirror":{"name":"Traffic Mirror","terms":"blind spot,convex,corner,curved,roadside,round,safety,sphere,visibility"},"highway/traffic_signals":{"name":"Traffic Signals","terms":"light,stoplight,traffic light"},"highway/trunk_link":{"name":"Trunk Link","terms":"ramp,on ramp,off ramp"},"highway/trunk":{"name":"Trunk Road","terms":""},"highway/turning_circle":{"name":"Turning Circle","terms":"cul-de-sac"},"highway/turning_loop":{"name":"Turning Loop (Island)","terms":"cul-de-sac"},"highway/unclassified":{"name":"Minor/Unclassified Road","terms":""},"historic":{"name":"Historic Site","terms":""},"historic/archaeological_site":{"name":"Archaeological Site","terms":""},"historic/boundary_stone":{"name":"Boundary Stone","terms":""},"historic/castle":{"name":"Castle","terms":""},"historic/memorial":{"name":"Memorial","terms":""},"historic/monument":{"name":"Monument","terms":""},"historic/ruins":{"name":"Ruins","terms":""},"historic/wayside_cross":{"name":"Wayside Cross","terms":""},"historic/wayside_shrine":{"name":"Wayside Shrine","terms":""},"junction":{"name":"Junction","terms":""},"landuse":{"name":"Land Use","terms":""},"landuse/farm":{"name":"Farmland","terms":""},"landuse/allotments":{"name":"Community Garden","terms":"allotment,garden"},"landuse/basin":{"name":"Basin","terms":""},"landuse/cemetery":{"name":"Cemetery","terms":""},"landuse/churchyard":{"name":"Churchyard","terms":""},"landuse/commercial":{"name":"Commercial Area","terms":""},"landuse/construction":{"name":"Construction","terms":""},"landuse/farmland":{"name":"Farmland","terms":""},"landuse/farmyard":{"name":"Farmyard","terms":""},"landuse/forest":{"name":"Forest","terms":"tree"},"landuse/garages":{"name":"Garages","terms":""},"landuse/grass":{"name":"Grass","terms":""},"landuse/industrial":{"name":"Industrial Area","terms":""},"landuse/landfill":{"name":"Landfill","terms":"dump"},"landuse/meadow":{"name":"Meadow","terms":""},"landuse/military":{"name":"Military Area","terms":""},"landuse/orchard":{"name":"Orchard","terms":""},"landuse/plant_nursery":{"name":"Plant Nursery","terms":"vivero"},"landuse/quarry":{"name":"Quarry","terms":""},"landuse/recreation_ground":{"name":"Recreation Ground","terms":"playing fields"},"landuse/residential":{"name":"Residential Area","terms":""},"landuse/retail":{"name":"Retail Area","terms":""},"landuse/vineyard":{"name":"Vineyard","terms":""},"leisure":{"name":"Leisure","terms":""},"leisure/adult_gaming_centre":{"name":"Adult Gaming Center","terms":"gambling,slot machine"},"leisure/bird_hide":{"name":"Bird Hide","terms":"machan,ornithology"},"leisure/bowling_alley":{"name":"Bowling Alley","terms":""},"leisure/common":{"name":"Common","terms":"open space"},"leisure/dance":{"name":"Dance Hall","terms":"ballroom,jive,swing,tango,waltz"},"leisure/dog_park":{"name":"Dog Park","terms":""},"leisure/firepit":{"name":"Firepit","terms":"fireplace,campfire"},"leisure/fitness_centre":{"name":"Gym / Fitness Center","terms":"health,gym,leisure,studio"},"leisure/fitness_centre/yoga":{"name":"Yoga Studio","terms":"studio"},"leisure/fitness_station":{"name":"Outdoor Fitness Station","terms":"fitness,gym"},"leisure/garden":{"name":"Garden","terms":""},"leisure/golf_course":{"name":"Golf Course","terms":"links"},"leisure/ice_rink":{"name":"Ice Rink","terms":"hockey,skating,curling"},"leisure/marina":{"name":"Marina","terms":"boat"},"leisure/miniature_golf":{"name":"Miniature Golf","terms":"crazy golf,mini golf,putt-putt"},"leisure/nature_reserve":{"name":"Nature Reserve","terms":"protected,wildlife"},"leisure/park":{"name":"Park","terms":"esplanade,estate,forest,garden,grass,green,grounds,lawn,lot,meadow,parkland,place,playground,plaza,pleasure garden,recreation area,square,tract,village green,woodland"},"leisure/picnic_table":{"name":"Picnic Table","terms":"bench"},"leisure/pitch":{"name":"Sport Pitch","terms":"field"},"leisure/pitch/american_football":{"name":"American Football Field","terms":""},"leisure/pitch/baseball":{"name":"Baseball Diamond","terms":""},"leisure/pitch/basketball":{"name":"Basketball Court","terms":""},"leisure/pitch/bowls":{"name":"Bowling Green","terms":""},"leisure/pitch/rugby_league":{"name":"Rugby League Field","terms":""},"leisure/pitch/rugby_union":{"name":"Rugby Union Field","terms":""},"leisure/pitch/skateboard":{"name":"Skate Park","terms":""},"leisure/pitch/soccer":{"name":"Soccer Field","terms":""},"leisure/pitch/tennis":{"name":"Tennis Court","terms":""},"leisure/pitch/volleyball":{"name":"Volleyball Court","terms":""},"leisure/playground":{"name":"Playground","terms":"jungle gym,play area"},"leisure/resort":{"name":"Resort","terms":""},"leisure/running_track":{"name":"Running Track","terms":""},"leisure/slipway":{"name":"Slipway","terms":"boat launch,boat ramp"},"leisure/sports_centre":{"name":"Sports Center / Complex","terms":""},"leisure/sports_centre/swimming":{"name":"Swimming Pool Facility","terms":"dive,water"},"leisure/stadium":{"name":"Stadium","terms":""},"leisure/swimming_pool":{"name":"Swimming Pool","terms":"dive,water"},"leisure/track":{"name":"Racetrack (non-Motorsport)","terms":""},"leisure/water_park":{"name":"Water Park","terms":"swim,pool,dive"},"line":{"name":"Line","terms":""},"man_made":{"name":"Man Made","terms":""},"man_made/embankment":{"name":"Embankment","terms":""},"man_made/adit":{"name":"Adit","terms":"entrance,underground,mine,cave"},"man_made/breakwater":{"name":"Breakwater","terms":""},"man_made/bridge":{"name":"Bridge","terms":""},"man_made/chimney":{"name":"Chimney","terms":""},"man_made/cutline":{"name":"Cut line","terms":""},"man_made/flagpole":{"name":"Flagpole","terms":""},"man_made/gasometer":{"name":"Gasometer","terms":"gas holder"},"man_made/groyne":{"name":"Groyne","terms":""},"man_made/lighthouse":{"name":"Lighthouse","terms":""},"man_made/mast":{"name":"Radio Mast","terms":"broadcast tower,cell phone tower,cell tower,guyed tower,mobile phone tower,radio tower,television tower,transmission mast,transmission tower,tv tower"},"man_made/observation":{"name":"Observation Tower","terms":"lookout tower,fire tower"},"man_made/petroleum_well":{"name":"Oil Well","terms":"drilling rig,oil derrick,oil drill,oil horse,oil rig,oil pump,petroleum well,pumpjack"},"man_made/pier":{"name":"Pier","terms":"dock"},"man_made/pipeline":{"name":"Pipeline","terms":""},"man_made/pumping_station":{"name":"Pumping Station","terms":""},"man_made/silo":{"name":"Silo","terms":"grain,corn,wheat"},"man_made/storage_tank":{"name":"Storage Tank","terms":"water,oil,gas,petrol"},"man_made/surveillance_camera":{"name":"Surveillance Camera","terms":"anpr,alpr,camera,car plate recognition,cctv,guard,license plate recognition,monitoring,number plate recognition,security,video,webcam"},"man_made/surveillance":{"name":"Surveillance","terms":"anpr,alpr,camera,car plate recognition,cctv,guard,license plate recognition,monitoring,number plate recognition,security,video,webcam"},"man_made/survey_point":{"name":"Survey Point","terms":""},"man_made/tower":{"name":"Tower","terms":""},"man_made/wastewater_plant":{"name":"Wastewater Plant","terms":"sewage*,water treatment plant,reclamation plant"},"man_made/water_tower":{"name":"Water Tower","terms":""},"man_made/water_well":{"name":"Water Well","terms":""},"man_made/water_works":{"name":"Water Works","terms":""},"man_made/works":{"name":"Works","terms":"car assembly plant,aluminium processing plant,brewery,furniture manufacture factory,oil refinery,plastic recycling"},"military/airfield":{"name":"Airfield","terms":""},"military/barracks":{"name":"Barracks","terms":""},"military/bunker":{"name":"Bunker","terms":""},"military/checkpoint":{"name":"Checkpoint","terms":""},"military/danger_area":{"name":"Danger Area","terms":""},"military/naval_base":{"name":"Naval Base","terms":""},"military/obstacle_course":{"name":"Obstacle Course","terms":""},"military/range":{"name":"Military Range","terms":""},"military/training_area":{"name":"Training area","terms":""},"natural":{"name":"Natural","terms":""},"natural/bay":{"name":"Bay","terms":""},"natural/beach":{"name":"Beach","terms":""},"natural/cave_entrance":{"name":"Cave Entrance","terms":"cavern,hollow,grotto,shelter,cavity"},"natural/cliff":{"name":"Cliff","terms":""},"natural/coastline":{"name":"Coastline","terms":"shore"},"natural/fell":{"name":"Fell","terms":""},"natural/glacier":{"name":"Glacier","terms":""},"natural/grassland":{"name":"Grassland","terms":""},"natural/heath":{"name":"Heath","terms":""},"natural/peak":{"name":"Peak","terms":"acme,aiguille,alp,climax,crest,crown,hill,mount,mountain,pinnacle,summit,tip,top"},"natural/saddle":{"name":"Saddle","terms":"pass,mountain pass,top"},"natural/scree":{"name":"Scree","terms":"loose rocks"},"natural/scrub":{"name":"Scrub","terms":"bush,shrubs"},"natural/spring":{"name":"Spring","terms":""},"natural/tree_row":{"name":"Tree row","terms":""},"natural/tree":{"name":"Tree","terms":""},"natural/volcano":{"name":"Volcano","terms":"mountain,crater"},"natural/water":{"name":"Water","terms":""},"natural/water/lake":{"name":"Lake","terms":"lakelet,loch,mere"},"natural/water/pond":{"name":"Pond","terms":"lakelet,millpond,tarn,pool,mere"},"natural/water/reservoir":{"name":"Reservoir","terms":""},"natural/wetland":{"name":"Wetland","terms":""},"natural/wood":{"name":"Wood","terms":"tree"},"office":{"name":"Office","terms":""},"office/travel_agent":{"name":"Travel Agency","terms":""},"office/accountant":{"name":"Accountant","terms":""},"office/administrative":{"name":"Administrative Office","terms":""},"office/architect":{"name":"Architect","terms":""},"office/company":{"name":"Company Office","terms":""},"office/educational_institution":{"name":"Educational Institution","terms":""},"office/employment_agency":{"name":"Employment Agency","terms":"job"},"office/estate_agent":{"name":"Real Estate Office","terms":""},"office/financial":{"name":"Financial Office","terms":""},"office/government":{"name":"Government Office","terms":""},"office/government/register_office":{"name":"Register Office","terms":"clerk,marriage,death,birth,certificate"},"office/insurance":{"name":"Insurance Office","terms":""},"office/it":{"name":"IT Office","terms":""},"office/lawyer":{"name":"Law Office","terms":""},"office/newspaper":{"name":"Newspaper","terms":""},"office/ngo":{"name":"NGO Office","terms":""},"office/physician":{"name":"Physician","terms":""},"office/political_party":{"name":"Political Party","terms":""},"office/research":{"name":"Research Office","terms":""},"office/telecommunication":{"name":"Telecom Office","terms":""},"office/therapist":{"name":"Therapist","terms":""},"piste":{"name":"Piste/Ski Trail","terms":"ski,sled,sleigh,snowboard,nordic,downhill,snowmobile"},"place/city":{"name":"City","terms":""},"place/farm":{"name":"Farm","terms":""},"place/hamlet":{"name":"Hamlet","terms":""},"place/island":{"name":"Island","terms":"archipelago,atoll,bar,cay,isle,islet,key,reef"},"place/isolated_dwelling":{"name":"Isolated Dwelling","terms":""},"place/locality":{"name":"Locality","terms":""},"place/neighbourhood":{"name":"Neighborhood","terms":"neighbourhood"},"place/suburb":{"name":"Borough","terms":"Boro,Quarter"},"place/town":{"name":"Town","terms":""},"place/village":{"name":"Village","terms":""},"point":{"name":"Point","terms":""},"power/sub_station":{"name":"Substation","terms":""},"power/generator":{"name":"Power Generator","terms":""},"power/line":{"name":"Power Line","terms":""},"power/minor_line":{"name":"Minor Power Line","terms":""},"power/pole":{"name":"Power Pole","terms":""},"power/substation":{"name":"Substation","terms":""},"power/tower":{"name":"High-Voltage Tower","terms":""},"power/transformer":{"name":"Transformer","terms":""},"public_transport/platform":{"name":"Platform","terms":""},"public_transport/stop_position":{"name":"Stop Position","terms":""},"railway/abandoned":{"name":"Abandoned Railway","terms":""},"railway/crossing":{"name":"Railway Crossing (Path)","terms":"crossing,pedestrian crossing,railroad crossing,level crossing,grade crossing,path through railroad,train crossing"},"railway/disused":{"name":"Disused Railway","terms":""},"railway/funicular":{"name":"Funicular","terms":"venicular,cliff railway,cable car,cable railway,funicular railway"},"railway/halt":{"name":"Railway Halt","terms":"break,interrupt,rest,wait,interruption"},"railway/level_crossing":{"name":"Railway Crossing (Road)","terms":"crossing,railroad crossing,level crossing,grade crossing,road through railroad,train crossing"},"railway/monorail":{"name":"Monorail","terms":""},"railway/narrow_gauge":{"name":"Narrow Gauge Rail","terms":"narrow gauge railway,narrow gauge railroad"},"railway/platform":{"name":"Railway Platform","terms":""},"railway/rail":{"name":"Rail","terms":""},"railway/station":{"name":"Railway Station","terms":"train station,station"},"railway/subway_entrance":{"name":"Subway Entrance","terms":""},"railway/subway":{"name":"Subway","terms":""},"railway/tram":{"name":"Tram","terms":"streetcar"},"relation":{"name":"Relation","terms":""},"route/ferry":{"name":"Ferry Route","terms":""},"shop":{"name":"Shop","terms":""},"shop/fishmonger":{"name":"Fishmonger","terms":""},"shop/vacant":{"name":"Vacant Shop","terms":""},"shop/alcohol":{"name":"Liquor Store","terms":"alcohol,beer,booze,wine"},"shop/anime":{"name":"Anime Shop","terms":"manga,japan,cosplay,figurine,dakimakura"},"shop/antiques":{"name":"Antiques Shop","terms":""},"shop/art":{"name":"Art Store","terms":"art*,exhibit*,gallery"},"shop/baby_goods":{"name":"Baby Goods Store","terms":""},"shop/bag":{"name":"Bag/Luggage Store","terms":"handbag,purse"},"shop/bakery":{"name":"Bakery","terms":""},"shop/bathroom_furnishing":{"name":"Bathroom Furnishing Store","terms":""},"shop/beauty":{"name":"Beauty Shop","terms":"spa,salon,tanning"},"shop/beauty/nails":{"name":"Nail Salon","terms":"manicure,pedicure"},"shop/beauty/tanning":{"name":"Tanning Salon","terms":""},"shop/bed":{"name":"Bedding/Mattress Store","terms":""},"shop/beverages":{"name":"Beverage Store","terms":""},"shop/bicycle":{"name":"Bicycle Shop","terms":"bike,repair"},"shop/bookmaker":{"name":"Bookmaker","terms":"betting"},"shop/books":{"name":"Book Store","terms":""},"shop/boutique":{"name":"Boutique","terms":""},"shop/butcher":{"name":"Butcher","terms":"meat"},"shop/candles":{"name":"Candle Shop","terms":""},"shop/car_parts":{"name":"Car Parts Store","terms":"auto"},"shop/car_repair":{"name":"Car Repair Shop","terms":"auto,garage,service"},"shop/car":{"name":"Car Dealership","terms":"auto"},"shop/carpet":{"name":"Carpet Store","terms":"rug"},"shop/charity":{"name":"Charity Store","terms":"thrift,op shop,nonprofit"},"shop/cheese":{"name":"Cheese Store","terms":""},"shop/chemist":{"name":"Drugstore","terms":"med*,drug*,gift"},"shop/chocolate":{"name":"Chocolate Store","terms":""},"shop/clothes":{"name":"Clothing Store","terms":""},"shop/coffee":{"name":"Coffee Store","terms":""},"shop/computer":{"name":"Computer Store","terms":""},"shop/confectionery":{"name":"Candy Store","terms":""},"shop/convenience":{"name":"Convenience Store","terms":""},"shop/copyshop":{"name":"Copy Store","terms":""},"shop/cosmetics":{"name":"Cosmetics Store","terms":""},"shop/craft":{"name":"Arts and Crafts Store","terms":"art*,paint*,frame"},"shop/curtain":{"name":"Curtain Store","terms":"drape*,window"},"shop/dairy":{"name":"Dairy Store","terms":"milk,egg,cheese"},"shop/deli":{"name":"Deli","terms":"lunch,meat,sandwich"},"shop/department_store":{"name":"Department Store","terms":""},"shop/doityourself":{"name":"DIY Store","terms":""},"shop/dry_cleaning":{"name":"Dry Cleaner","terms":""},"shop/e-cigarette":{"name":"E-Cigarette Shop","terms":"electronic,vapor"},"shop/electronics":{"name":"Electronics Store","terms":"appliance,audio,computer,tv"},"shop/erotic":{"name":"Erotic Store","terms":"sex,porn"},"shop/fabric":{"name":"Fabric Store","terms":"sew"},"shop/farm":{"name":"Produce Stand","terms":"farm shop,farm stand"},"shop/fashion":{"name":"Fashion Store","terms":""},"shop/florist":{"name":"Florist","terms":"flower"},"shop/frame":{"name":"Framing Shop","terms":"art*,paint*,photo*,frame"},"shop/funeral_directors":{"name":"Funeral Home","terms":"undertaker,memorial home"},"shop/furnace":{"name":"Furnace Store","terms":"oven,stove"},"shop/furniture":{"name":"Furniture Store","terms":"chair,sofa,table"},"shop/garden_centre":{"name":"Garden Center","terms":"landscape,mulch,shrub,tree"},"shop/gift":{"name":"Gift Shop","terms":"souvenir"},"shop/greengrocer":{"name":"Greengrocer","terms":"fruit,vegetable"},"shop/hairdresser":{"name":"Hairdresser","terms":"barber"},"shop/hardware":{"name":"Hardware Store","terms":""},"shop/hearing_aids":{"name":"Hearing Aids Store","terms":""},"shop/herbalist":{"name":"Herbalist","terms":""},"shop/hifi":{"name":"Hifi Store","terms":"stereo,video"},"shop/houseware":{"name":"Houseware Store","terms":"home,household"},"shop/interior_decoration":{"name":"Interior Decoration Store","terms":""},"shop/jewelry":{"name":"Jeweler","terms":"diamond,gem,ring"},"shop/kiosk":{"name":"News Kiosk","terms":""},"shop/kitchen":{"name":"Kitchen Design Store","terms":""},"shop/laundry":{"name":"Laundry","terms":""},"shop/leather":{"name":"Leather Store","terms":""},"shop/locksmith":{"name":"Locksmith","terms":"key,lockpick"},"shop/lottery":{"name":"Lottery Shop","terms":""},"shop/mall":{"name":"Mall","terms":"shopping"},"shop/massage":{"name":"Massage Shop","terms":""},"shop/medical_supply":{"name":"Medical Supply Store","terms":""},"shop/mobile_phone":{"name":"Mobile Phone Store","terms":""},"shop/money_lender":{"name":"Money Lender","terms":""},"shop/motorcycle":{"name":"Motorcycle Dealership","terms":"bike"},"shop/music":{"name":"Music Store","terms":"CD,vinyl"},"shop/musical_instrument":{"name":"Musical Instrument Store","terms":"guitar"},"shop/newsagent":{"name":"Newspaper/Magazine Shop","terms":""},"shop/nutrition_supplements":{"name":"Nutrition Supplements Store","terms":""},"shop/optician":{"name":"Optician","terms":"eye,glasses"},"shop/organic":{"name":"Organic Goods Store","terms":""},"shop/outdoor":{"name":"Outdoors Store","terms":"camping,climbing,hiking"},"shop/paint":{"name":"Paint Store","terms":""},"shop/pastry":{"name":"Pastry Shop","terms":"patisserie,cake shop,cakery"},"shop/pawnbroker":{"name":"Pawn Shop","terms":""},"shop/pet":{"name":"Pet Store","terms":"cat,dog,fish"},"shop/photo":{"name":"Photography Store","terms":"camera,film"},"shop/pyrotechnics":{"name":"Fireworks Store","terms":""},"shop/radiotechnics":{"name":"Radio/Electronic Component Store","terms":""},"shop/religion":{"name":"Religious Store","terms":""},"shop/scuba_diving":{"name":"Scuba Diving Shop","terms":""},"shop/seafood":{"name":"Seafood Shop","terms":"fishmonger"},"shop/second_hand":{"name":"Consignment/Thrift Store","terms":"secondhand,second hand,resale,thrift,used"},"shop/shoes":{"name":"Shoe Store","terms":""},"shop/sports":{"name":"Sporting Goods Store","terms":""},"shop/stationery":{"name":"Stationery Store","terms":"card,paper"},"shop/storage_rental":{"name":"Storage Rental","terms":""},"shop/supermarket":{"name":"Supermarket","terms":"grocery,store,shop"},"shop/tailor":{"name":"Tailor","terms":"clothes,suit"},"shop/tattoo":{"name":"Tattoo Parlor","terms":""},"shop/tea":{"name":"Tea Store","terms":""},"shop/ticket":{"name":"Ticket Seller","terms":""},"shop/tobacco":{"name":"Tobacco Shop","terms":""},"shop/toys":{"name":"Toy Store","terms":""},"shop/travel_agency":{"name":"Travel Agency","terms":""},"shop/tyres":{"name":"Tire Store","terms":""},"shop/vacuum_cleaner":{"name":"Vacuum Cleaner Store","terms":""},"shop/variety_store":{"name":"Variety Store","terms":""},"shop/video_games":{"name":"Video Game Store","terms":""},"shop/video":{"name":"Video Store","terms":"DVD"},"shop/water_sports":{"name":"Watersport/Swim Shop","terms":""},"shop/weapons":{"name":"Weapon Shop","terms":"ammo,gun,knife,knives"},"shop/window_blind":{"name":"Window Blind Store","terms":""},"shop/wine":{"name":"Wine Shop","terms":""},"tourism":{"name":"Tourism","terms":""},"tourism/alpine_hut":{"name":"Alpine Hut","terms":""},"tourism/apartment":{"name":"Guest Apartment / Condo","terms":""},"tourism/aquarium":{"name":"Aquarium","terms":"fish,sea,water"},"tourism/artwork":{"name":"Artwork","terms":"mural,sculpture,statue"},"tourism/attraction":{"name":"Tourist Attraction","terms":""},"tourism/camp_site":{"name":"Campground","terms":"tent,rv"},"tourism/caravan_site":{"name":"RV Park","terms":"Motor Home,Camper"},"tourism/chalet":{"name":"Chalet","terms":""},"tourism/gallery":{"name":"Art Gallery","terms":"art*,exhibit*,paint*,photo*,sculpt*"},"tourism/guest_house":{"name":"Guest House","terms":"B&B,Bed and Breakfast"},"tourism/hostel":{"name":"Hostel","terms":""},"tourism/hotel":{"name":"Hotel","terms":""},"tourism/information":{"name":"Information","terms":""},"tourism/information/board":{"name":"Information Board","terms":""},"tourism/information/guidepost":{"name":"Guidepost","terms":""},"tourism/information/map":{"name":"Map","terms":""},"tourism/information/office":{"name":"Tourist Information Office","terms":""},"tourism/motel":{"name":"Motel","terms":""},"tourism/museum":{"name":"Museum","terms":"art*,exhibit*,gallery,foundation,hall,institution,paint*,photo*,sculpt*"},"tourism/picnic_site":{"name":"Picnic Site","terms":"camp"},"tourism/theme_park":{"name":"Theme Park","terms":""},"tourism/viewpoint":{"name":"Viewpoint","terms":""},"tourism/zoo":{"name":"Zoo","terms":"animal"},"traffic_calming":{"name":"Traffic Calming","terms":"bump,hump,slow,speed"},"traffic_calming/bump":{"name":"Speed Bump","terms":"hump,speed,slow"},"traffic_calming/chicane":{"name":"Traffic Chicane","terms":"driveway link,speed,slow"},"traffic_calming/choker":{"name":"Traffic Choker","terms":"speed,slow"},"traffic_calming/cushion":{"name":"Speed Cushion","terms":"bump,hump,speed,slow"},"traffic_calming/dip":{"name":"Dip","terms":"speed,slow"},"traffic_calming/hump":{"name":"Speed Hump","terms":"bump,speed,slow"},"traffic_calming/island":{"name":"Traffic Island","terms":"circle,roundabout,slow"},"traffic_calming/rumble_strip":{"name":"Rumble Strip","terms":"audible lines,sleeper lines,growlers"},"traffic_calming/table":{"name":"Raised Pedestrian Crossing","terms":"flat top,hump,speed,slow"},"type/multipolygon":{"name":"Multipolygon","terms":""},"type/boundary":{"name":"Boundary","terms":""},"type/boundary/administrative":{"name":"Administrative Boundary","terms":""},"type/restriction":{"name":"Restriction","terms":""},"type/restriction/no_left_turn":{"name":"No Left Turn","terms":""},"type/restriction/no_right_turn":{"name":"No Right Turn","terms":""},"type/restriction/no_straight_on":{"name":"No Straight On","terms":""},"type/restriction/no_u_turn":{"name":"No U-turn","terms":""},"type/restriction/only_left_turn":{"name":"Left Turn Only","terms":""},"type/restriction/only_right_turn":{"name":"Right Turn Only","terms":""},"type/restriction/only_straight_on":{"name":"No Turns","terms":""},"type/route_master":{"name":"Route Master","terms":""},"type/route":{"name":"Route","terms":""},"type/route/bicycle":{"name":"Cycle Route","terms":""},"type/route/bus":{"name":"Bus Route","terms":""},"type/route/detour":{"name":"Detour Route","terms":""},"type/route/ferry":{"name":"Ferry Route","terms":""},"type/route/foot":{"name":"Foot Route","terms":""},"type/route/hiking":{"name":"Hiking Route","terms":""},"type/route/horse":{"name":"Riding Route","terms":""},"type/route/pipeline":{"name":"Pipeline Route","terms":""},"type/route/power":{"name":"Power Route","terms":""},"type/route/road":{"name":"Road Route","terms":""},"type/route/train":{"name":"Train Route","terms":""},"type/route/tram":{"name":"Tram Route","terms":""},"type/site":{"name":"Site","terms":""},"vertex":{"name":"Other","terms":""},"waterway/boatyard":{"name":"Boatyard","terms":""},"waterway/canal":{"name":"Canal","terms":""},"waterway/dam":{"name":"Dam","terms":""},"waterway/ditch":{"name":"Ditch","terms":""},"waterway/dock":{"name":"Wet Dock / Dry Dock","terms":"boat,ship,vessel,marine"},"waterway/drain":{"name":"Drain","terms":""},"waterway/fuel":{"name":"Marine Fuel Station","terms":"petrol,gas,diesel,boat"},"waterway/river":{"name":"River","terms":"beck,branch,brook,course,creek,estuary,rill,rivulet,run,runnel,stream,tributary,watercourse"},"waterway/riverbank":{"name":"Riverbank","terms":""},"waterway/sanitary_dump_station":{"name":"Marine Toilet Disposal","terms":"Boat,Watercraft,Sanitary,Dump Station,Pumpout,Pump out,Elsan,CDP,CTDP,Chemical Toilet"},"waterway/stream":{"name":"Stream","terms":"beck,branch,brook,burn,course,creek,current,drift,flood,flow,freshet,race,rill,rindle,rivulet,run,runnel,rush,spate,spritz,surge,tide,torrent,tributary,watercourse"},"waterway/water_point":{"name":"Marine Drinking Water","terms":""},"waterway/waterfall":{"name":"Waterfall","terms":"fall"},"waterway/weir":{"name":"Weir","terms":""}}}};
18949 var dataImagery = [{"id":"sjcgis.org-Aerials_2013_WM","name":"2013 aerial imagery for San Juan County WA","type":"tms","template":"http://sjcgis.org/arcgis/rest/services/Basemaps/Aerials_2013_WM/MapServer/tile/{zoom}/{y}/{x}","description":"Public domain aerial imagery taken in May/June 2013 from San Juan County, WA. Resolution is 9 inch.","scaleExtent":[0,19],"polygon":[[[-122.98339348286,48.78214357977],[-122.93498497456,48.76653172572],[-122.91181068867,48.73857664785],[-122.80229073018,48.73982194177],[-122.81945686787,48.75498940888],[-122.93429832906,48.79571515892],[-122.98373680562,48.79435816618],[-122.98339348286,48.78214357977]],[[-123.02167396992,48.44667085335],[-122.9466579482,48.44780949945],[-122.90151100606,48.41306930778],[-122.80263405293,48.40771378918],[-122.79199104756,48.44279926564],[-122.8088138625,48.47865708877],[-122.73911934346,48.49572334021],[-122.78546791524,48.62160819278],[-122.73087959737,48.6361306644],[-122.75559883565,48.71207854113],[-122.95747261494,48.71592956034],[-122.97086220235,48.695765074],[-122.99970131367,48.69780454658],[-123.00347786397,48.73427448605],[-123.04330330342,48.74310484148],[-123.0762622878,48.70528190578],[-123.08484535664,48.66334903433],[-123.12844734639,48.66380254936],[-123.22698097676,48.70301615666],[-123.24655037373,48.68352650341],[-123.17445259541,48.64701977542],[-123.21513634175,48.60106537642],[-123.21393471211,48.57335906966],[-123.18080406636,48.56574853208],[-123.16621284932,48.52006125122],[-123.10235481709,48.47683634964],[-123.02167396992,48.44667085335]]],"best":true},{"id":"OS7","name":"7th Series (OS7)","type":"tms","template":"http://ooc.openstreetmap.org/os7/{zoom}/{x}/{y}.jpg","polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]]},{"id":"AGRI-black_and_white-2.5m","name":"AGRI black-and-white 2.5m","type":"tms","template":"http://agri.openstreetmap.org/{zoom}/{x}/{y}.png","polygon":[[[112.28778,-28.784589],[112.71488,-31.13894],[114.11263,-34.178287],[113.60788,-37.39012],[117.17992,-37.451794],[119.31538,-37.42096],[121.72262,-36.708394],[123.81925,-35.76893],[125.9547,-34.3066],[127.97368,-33.727398],[130.07031,-33.24166],[130.10913,-33.888704],[131.00214,-34.049705],[131.0798,-34.72257],[132.28342,-35.39],[134.18591,-35.61126],[133.8753,-37.1119],[134.8459,-37.6365],[139.7769,-37.82075],[139.93223,-39.4283],[141.6017,-39.8767],[142.3783,-39.368294],[142.3783,-40.64702],[142.49478,-42.074874],[144.009,-44.060127],[147.23161,-44.03222],[149.05645,-42.534313],[149.52237,-40.99959],[149.9494,-40.852921],[150.8036,-38.09627],[151.81313,-38.12682],[156.20052,-22.667706],[156.20052,-20.10109],[156.62761,-17.417627],[155.26869,-17.19521],[154.14272,-19.51662],[153.5215,-18.34139],[153.05558,-16.5636],[152.78379,-15.256768],[152.27905,-13.4135],[151.3472,-12.391767],[149.48354,-12.05024],[146.9598,-9.992408],[135.9719,-9.992408],[130.3032,-10.33636],[128.09016,-12.164136],[125.91588,-12.315912],[124.3239,-11.860326],[122.03323,-11.974295],[118.26706,-16.9353],[115.93747,-19.11357],[114.0738,-21.11863],[113.49141,-22.596033],[112.28778,-28.784589]]],"terms_text":"AGRI"},{"id":"basemap.at","name":"basemap.at","type":"tms","template":"https://maps{switch:1,2,3,4}.wien.gv.at/basemap/geolandbasemap/normal/google3857/{zoom}/{y}/{x}.png","description":"Basemap of Austria, based on goverment data.","scaleExtent":[0,19],"polygon":[[[16.5073284,46.9929304],[16.283417,46.9929304],[16.135839,46.8713046],[15.9831722,46.8190947],[16.0493278,46.655175],[15.8610387,46.7180116],[15.7592608,46.6900933],[15.5607938,46.6796202],[15.5760605,46.6342132],[15.4793715,46.6027553],[15.4335715,46.6516819],[15.2249267,46.6342132],[15.0468154,46.6481886],[14.9908376,46.5887681],[14.9603042,46.6237293],[14.8534374,46.6027553],[14.8330818,46.5012666],[14.7516595,46.4977636],[14.6804149,46.4381781],[14.6142593,46.4381781],[14.578637,46.3785275],[14.4412369,46.4311638],[14.1613476,46.4276563],[14.1257253,46.4767409],[14.0188585,46.4767409],[13.9119917,46.5257813],[13.8254805,46.5047694],[13.4438134,46.560783],[13.3064132,46.5502848],[13.1283019,46.5887681],[12.8433237,46.6132433],[12.7262791,46.6412014],[12.5125455,46.6656529],[12.3598787,46.7040543],[12.3649676,46.7703197],[12.2886341,46.7772902],[12.2733674,46.8852187],[12.2072118,46.8747835],[12.1308784,46.9026062],[12.1156117,46.9998721],[12.2530119,47.0657733],[12.2123007,47.0934969],[11.9833004,47.0449712],[11.7339445,46.9616816],[11.6321666,47.010283],[11.5405665,46.9755722],[11.4998553,47.0068129],[11.418433,46.9651546],[11.2555884,46.9755722],[11.1130993,46.913036],[11.0418548,46.7633482],[10.8891879,46.7598621],[10.7416099,46.7842599],[10.7059877,46.8643462],[10.5787653,46.8399847],[10.4566318,46.8504267],[10.4769874,46.9269392],[10.3853873,46.9894592],[10.2327204,46.8643462],[10.1207647,46.8330223],[9.8663199,46.9408389],[9.9019422,47.0033426],[9.6831197,47.0588402],[9.6118752,47.0380354],[9.6322307,47.128131],[9.5813418,47.1662025],[9.5406306,47.2664422],[9.6067863,47.3492559],[9.6729419,47.369939],[9.6424085,47.4457079],[9.5660751,47.4801122],[9.7136531,47.5282405],[9.7848976,47.5969187],[9.8357866,47.5454185],[9.9477423,47.538548],[10.0902313,47.4491493],[10.1105869,47.3664924],[10.2428982,47.3871688],[10.1869203,47.2698953],[10.3243205,47.2975125],[10.4820763,47.4491493],[10.4311873,47.4869904],[10.4413651,47.5900549],[10.4871652,47.5522881],[10.5482319,47.5351124],[10.5991209,47.5660246],[10.7568766,47.5316766],[10.8891879,47.5454185],[10.9400769,47.4869904],[10.9960547,47.3906141],[11.2352328,47.4422662],[11.2810328,47.3975039],[11.4235219,47.5144941],[11.5761888,47.5076195],[11.6067221,47.5900549],[11.8357224,47.5866227],[12.003656,47.6243647],[12.2072118,47.6037815],[12.1614117,47.6963421],[12.2581008,47.7442718],[12.2530119,47.6792136],[12.4311232,47.7100408],[12.4921899,47.631224],[12.5685234,47.6277944],[12.6295901,47.6894913],[12.7720792,47.6689338],[12.8331459,47.5419833],[12.975635,47.4732332],[13.0417906,47.4938677],[13.0367017,47.5557226],[13.0977685,47.6415112],[13.0316128,47.7100408],[12.9043905,47.7203125],[13.0061684,47.84683],[12.9451016,47.9355501],[12.8636793,47.9594103],[12.8636793,48.0036929],[12.7517236,48.0989418],[12.8738571,48.2109733],[12.9603683,48.2109733],[13.0417906,48.2652035],[13.1842797,48.2990682],[13.2606131,48.2922971],[13.3980133,48.3565867],[13.4438134,48.417418],[13.4387245,48.5523383],[13.509969,48.5860123],[13.6117469,48.5725454],[13.7287915,48.5118999],[13.7847694,48.5725454],[13.8203916,48.6263915],[13.7949471,48.7171267],[13.850925,48.7741724],[14.0595697,48.6633774],[14.0137696,48.6331182],[14.0748364,48.5927444],[14.2173255,48.5961101],[14.3649034,48.5489696],[14.4666813,48.6499311],[14.5582815,48.5961101],[14.5989926,48.6263915],[14.7211261,48.5759124],[14.7211261,48.6868997],[14.822904,48.7271983],[14.8178151,48.777526],[14.9647227,48.7851754],[14.9893637,49.0126611],[15.1485933,48.9950306],[15.1943934,48.9315502],[15.3063491,48.9850128],[15.3928603,48.9850128],[15.4844604,48.9282069],[15.749083,48.8545973],[15.8406831,48.8880697],[16.0086166,48.7808794],[16.2070835,48.7339115],[16.3953727,48.7372678],[16.4920617,48.8110498],[16.6905286,48.7741724],[16.7057953,48.7339115],[16.8991733,48.713769],[16.9755067,48.515271],[16.8482844,48.4511817],[16.8533733,48.3464411],[16.9551512,48.2516513],[16.9907734,48.1498955],[17.0925513,48.1397088],[17.0823736,48.0241182],[17.1739737,48.0207146],[17.0823736,47.8741447],[16.9856845,47.8673174],[17.0823736,47.8092489],[17.0925513,47.7031919],[16.7414176,47.6792136],[16.7057953,47.7511153],[16.5378617,47.7545368],[16.5480395,47.7066164],[16.4208172,47.6689338],[16.573484,47.6175045],[16.670173,47.631224],[16.7108842,47.538548],[16.6599952,47.4491493],[16.5429506,47.3940591],[16.4615283,47.3940591],[16.4920617,47.276801],[16.425906,47.1973317],[16.4717061,47.1489007],[16.5480395,47.1489007],[16.476795,47.0796369],[16.527684,47.0588402],[16.5073284,46.9929304]]],"terms_text":"basemap.at"},{"id":"basemap.at-orthofoto","name":"basemap.at Orthofoto","type":"tms","template":"https://maps{switch:1,2,3,4}.wien.gv.at/basemap/bmaporthofoto30cm/normal/google3857/{zoom}/{y}/{x}.jpeg","description":"Orthofoto layer provided by basemap.at. \"Successor\" of geoimage.at imagery.","scaleExtent":[0,19],"polygon":[[[16.5073284,46.9929304],[16.283417,46.9929304],[16.135839,46.8713046],[15.9831722,46.8190947],[16.0493278,46.655175],[15.8610387,46.7180116],[15.7592608,46.6900933],[15.5607938,46.6796202],[15.5760605,46.6342132],[15.4793715,46.6027553],[15.4335715,46.6516819],[15.2249267,46.6342132],[15.0468154,46.6481886],[14.9908376,46.5887681],[14.9603042,46.6237293],[14.8534374,46.6027553],[14.8330818,46.5012666],[14.7516595,46.4977636],[14.6804149,46.4381781],[14.6142593,46.4381781],[14.578637,46.3785275],[14.4412369,46.4311638],[14.1613476,46.4276563],[14.1257253,46.4767409],[14.0188585,46.4767409],[13.9119917,46.5257813],[13.8254805,46.5047694],[13.4438134,46.560783],[13.3064132,46.5502848],[13.1283019,46.5887681],[12.8433237,46.6132433],[12.7262791,46.6412014],[12.5125455,46.6656529],[12.3598787,46.7040543],[12.3649676,46.7703197],[12.2886341,46.7772902],[12.2733674,46.8852187],[12.2072118,46.8747835],[12.1308784,46.9026062],[12.1156117,46.9998721],[12.2530119,47.0657733],[12.2123007,47.0934969],[11.9833004,47.0449712],[11.7339445,46.9616816],[11.6321666,47.010283],[11.5405665,46.9755722],[11.4998553,47.0068129],[11.418433,46.9651546],[11.2555884,46.9755722],[11.1130993,46.913036],[11.0418548,46.7633482],[10.8891879,46.7598621],[10.7416099,46.7842599],[10.7059877,46.8643462],[10.5787653,46.8399847],[10.4566318,46.8504267],[10.4769874,46.9269392],[10.3853873,46.9894592],[10.2327204,46.8643462],[10.1207647,46.8330223],[9.8663199,46.9408389],[9.9019422,47.0033426],[9.6831197,47.0588402],[9.6118752,47.0380354],[9.6322307,47.128131],[9.5813418,47.1662025],[9.5406306,47.2664422],[9.6067863,47.3492559],[9.6729419,47.369939],[9.6424085,47.4457079],[9.5660751,47.4801122],[9.7136531,47.5282405],[9.7848976,47.5969187],[9.8357866,47.5454185],[9.9477423,47.538548],[10.0902313,47.4491493],[10.1105869,47.3664924],[10.2428982,47.3871688],[10.1869203,47.2698953],[10.3243205,47.2975125],[10.4820763,47.4491493],[10.4311873,47.4869904],[10.4413651,47.5900549],[10.4871652,47.5522881],[10.5482319,47.5351124],[10.5991209,47.5660246],[10.7568766,47.5316766],[10.8891879,47.5454185],[10.9400769,47.4869904],[10.9960547,47.3906141],[11.2352328,47.4422662],[11.2810328,47.3975039],[11.4235219,47.5144941],[11.5761888,47.5076195],[11.6067221,47.5900549],[11.8357224,47.5866227],[12.003656,47.6243647],[12.2072118,47.6037815],[12.1614117,47.6963421],[12.2581008,47.7442718],[12.2530119,47.6792136],[12.4311232,47.7100408],[12.4921899,47.631224],[12.5685234,47.6277944],[12.6295901,47.6894913],[12.7720792,47.6689338],[12.8331459,47.5419833],[12.975635,47.4732332],[13.0417906,47.4938677],[13.0367017,47.5557226],[13.0977685,47.6415112],[13.0316128,47.7100408],[12.9043905,47.7203125],[13.0061684,47.84683],[12.9451016,47.9355501],[12.8636793,47.9594103],[12.8636793,48.0036929],[12.7517236,48.0989418],[12.8738571,48.2109733],[12.9603683,48.2109733],[13.0417906,48.2652035],[13.1842797,48.2990682],[13.2606131,48.2922971],[13.3980133,48.3565867],[13.4438134,48.417418],[13.4387245,48.5523383],[13.509969,48.5860123],[13.6117469,48.5725454],[13.7287915,48.5118999],[13.7847694,48.5725454],[13.8203916,48.6263915],[13.7949471,48.7171267],[13.850925,48.7741724],[14.0595697,48.6633774],[14.0137696,48.6331182],[14.0748364,48.5927444],[14.2173255,48.5961101],[14.3649034,48.5489696],[14.4666813,48.6499311],[14.5582815,48.5961101],[14.5989926,48.6263915],[14.7211261,48.5759124],[14.7211261,48.6868997],[14.822904,48.7271983],[14.8178151,48.777526],[14.9647227,48.7851754],[14.9893637,49.0126611],[15.1485933,48.9950306],[15.1943934,48.9315502],[15.3063491,48.9850128],[15.3928603,48.9850128],[15.4844604,48.9282069],[15.749083,48.8545973],[15.8406831,48.8880697],[16.0086166,48.7808794],[16.2070835,48.7339115],[16.3953727,48.7372678],[16.4920617,48.8110498],[16.6905286,48.7741724],[16.7057953,48.7339115],[16.8991733,48.713769],[16.9755067,48.515271],[16.8482844,48.4511817],[16.8533733,48.3464411],[16.9551512,48.2516513],[16.9907734,48.1498955],[17.0925513,48.1397088],[17.0823736,48.0241182],[17.1739737,48.0207146],[17.0823736,47.8741447],[16.9856845,47.8673174],[17.0823736,47.8092489],[17.0925513,47.7031919],[16.7414176,47.6792136],[16.7057953,47.7511153],[16.5378617,47.7545368],[16.5480395,47.7066164],[16.4208172,47.6689338],[16.573484,47.6175045],[16.670173,47.631224],[16.7108842,47.538548],[16.6599952,47.4491493],[16.5429506,47.3940591],[16.4615283,47.3940591],[16.4920617,47.276801],[16.425906,47.1973317],[16.4717061,47.1489007],[16.5480395,47.1489007],[16.476795,47.0796369],[16.527684,47.0588402],[16.5073284,46.9929304]]],"terms_text":"basemap.at","best":true},{"id":"bavaria-DOP80","name":"Bavaria DOP 80cm","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/BAYERNDOP80/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[0,18],"polygon":[[[10.1235886,50.568462],[10.1428576,50.5507804],[10.2028056,50.5574195],[10.2520485,50.5179575],[10.3269835,50.4934473],[10.4104825,50.4184762],[10.6031724,50.3310874],[10.6224414,50.2271041],[10.7252093,50.2106649],[10.7294913,50.2476451],[10.8515282,50.2435376],[10.7187863,50.3201525],[10.7123633,50.3652428],[10.8558102,50.3966441],[10.9371682,50.3966441],[10.9906932,50.3666085],[11.1277171,50.3666085],[11.1791011,50.3133169],[11.1619731,50.294172],[11.24119,50.2928042],[11.249754,50.3734364],[11.24119,50.479825],[11.358945,50.5234025],[11.4381619,50.5097889],[11.4424439,50.4893611],[11.425316,50.4771001],[11.425316,50.4416618],[11.4895459,50.4225686],[11.4916869,50.3980089],[11.5195199,50.3980089],[11.5259429,50.3761673],[11.5987369,50.4034677],[11.6372748,50.3884544],[11.7935678,50.4212045],[11.8363877,50.3925494],[11.9220277,50.4280246],[11.9862577,50.3870894],[11.9841167,50.3570478],[12.0483466,50.3310874],[12.0933076,50.3297207],[12.1297046,50.2982751],[12.1404096,50.2722826],[12.1061536,50.255859],[12.1125766,50.2353216],[12.1489736,50.236691],[12.1982166,50.2010728],[12.2239086,50.1640565],[12.2046396,50.1434795],[12.2067806,50.1077916],[12.2431775,50.0995522],[12.2774335,50.0720772],[12.4936744,49.985428],[12.4979564,49.9413559],[12.5557634,49.9220616],[12.5493404,49.8682726],[12.4808284,49.7881677],[12.4101755,49.7577484],[12.4615594,49.7065456],[12.5471994,49.6802313],[12.5878784,49.552613],[12.6542493,49.534553],[12.6628133,49.4330153],[12.7527353,49.4107323],[12.7976963,49.3466124],[12.9047462,49.3563752],[12.9968092,49.3368477],[13.0546161,49.2754251],[13.1316921,49.2195199],[13.1916401,49.1439475],[13.236601,49.1215335],[13.296549,49.1229347],[13.371484,49.0808823],[13.414304,49.0289687],[13.414304,48.9798112],[13.5791609,48.9699739],[13.6348268,48.9432629],[13.6776468,48.8869823],[13.7375948,48.8926132],[13.7846968,48.8334571],[13.8403627,48.774231],[13.8168118,48.7064584],[13.8446447,48.7008065],[13.8425037,48.6003807],[13.7654278,48.5422972],[13.7525818,48.5040106],[13.6712238,48.5054291],[13.6433908,48.5437146],[13.4571239,48.5508013],[13.4571239,48.4159838],[13.40574,48.3605338],[13.283703,48.2751083],[13.0931541,48.2694081],[12.9582712,48.1909669],[12.8769132,48.1852574],[12.7720043,48.0938188],[12.8640672,48.0136764],[12.8983232,47.9549216],[12.9454252,47.9563555],[12.9968092,47.8846147],[13.0139372,47.834337],[12.9347202,47.7321953],[13.0588981,47.7249947],[13.1188461,47.6385093],[13.0653211,47.5692178],[13.0567571,47.473792],[13.0032322,47.4520801],[12.7677223,47.5504355],[12.7698633,47.6327385],[12.7398893,47.6731207],[12.6670953,47.6702373],[12.5750324,47.621195],[12.4808284,47.6197519],[12.4144575,47.6702373],[12.2431775,47.6774455],[12.2132036,47.6918589],[12.1917936,47.6817699],[12.2132036,47.6659119],[12.2110626,47.603875],[12.1746656,47.5952129],[12.1382686,47.603875],[11.8920537,47.603875],[11.8513747,47.5793285],[11.6394158,47.5822169],[11.5944549,47.5489905],[11.5901729,47.5128508],[11.5173789,47.498388],[11.4403029,47.5041736],[11.395342,47.4752392],[11.427457,47.4448409],[11.346099,47.4433929],[11.279728,47.3955873],[11.2133571,47.3883402],[11.247613,47.4318076],[11.1020251,47.3926886],[10.9650012,47.3897897],[10.9778472,47.4361524],[10.9178992,47.4752392],[10.8707972,47.4752392],[10.8558102,47.4940484],[10.9007712,47.5142969],[10.8729382,47.5359831],[10.8108493,47.5128508],[10.6438513,47.5489905],[10.5946084,47.5547705],[10.5796214,47.5287553],[10.4618664,47.5403192],[10.4661484,47.4839212],[10.4875584,47.4781333],[10.4875584,47.4129762],[10.4597254,47.4028333],[10.4597254,47.375293],[10.4104825,47.3738431],[10.4083415,47.3433862],[10.3205605,47.2867768],[10.2820225,47.2780622],[10.2841635,47.2620819],[10.1471396,47.2620819],[10.1921006,47.3027497],[10.1942416,47.3738431],[10.1664086,47.3738431],[10.1664086,47.3462876],[10.1000376,47.3433862],[10.0614996,47.3636928],[10.0679226,47.4187712],[10.0936146,47.426014],[10.0957556,47.4419449],[9.9780007,47.485368],[9.9565907,47.5273097],[9.8945017,47.5287553],[9.8559637,47.5085124],[9.8174258,47.544655],[9.8217078,47.5764399],[9.7746058,47.5822169],[9.7382088,47.525864],[9.6739788,47.5345376],[9.5840569,47.564884],[9.6397228,47.6053186],[9.7167988,47.603875],[9.8559637,47.6760039],[9.9780007,47.6558179],[10.0293846,47.6817699],[10.1000376,47.6673537],[10.1321526,47.6760039],[10.1428576,47.7019459],[10.0614996,47.7725005],[10.1128836,47.8098988],[10.0829096,47.8530173],[10.1086016,47.9090177],[10.0764866,47.9649577],[10.1300116,48.020837],[10.1342936,48.1066872],[10.1000376,48.1281274],[10.0550766,48.2622821],[9.9694367,48.3676462],[10.0315256,48.4259299],[10.0293846,48.461436],[10.1235886,48.4770509],[10.1535626,48.4514968],[10.2349205,48.5125212],[10.3162785,48.516776],[10.2991505,48.6187835],[10.2456255,48.6682961],[10.2734585,48.7064584],[10.3698035,48.6838472],[10.4318924,48.6993935],[10.4511614,48.7276471],[10.4019185,48.7460035],[10.4404564,48.8489571],[10.4340334,48.9587289],[10.3376885,49.0205451],[10.2499075,49.0359872],[10.2499075,49.0738701],[10.2006646,49.1033147],[10.2520485,49.1327418],[10.1235886,49.1971401],[10.1193066,49.2628519],[10.1514216,49.2893915],[10.1043196,49.3452175],[10.1407166,49.3940134],[10.1086016,49.445545],[10.1107426,49.5053651],[10.0722046,49.5331635],[10.0165387,49.4761598],[9.9266167,49.478942],[9.9244757,49.5567797],[9.8987837,49.5817727],[9.8559637,49.5387213],[9.8067208,49.5567797],[9.8666687,49.6067529],[9.8538227,49.6441991],[9.8174258,49.6608327],[9.8345537,49.6899277],[9.7960158,49.7203895],[9.7574778,49.7079302],[9.7403498,49.6857723],[9.7060938,49.7162368],[9.6782608,49.7162368],[9.6825428,49.6885426],[9.6204539,49.6913127],[9.6461458,49.78955],[9.5583649,49.7743431],[9.5712109,49.7356133],[9.5069809,49.7522156],[9.4919939,49.7798735],[9.4684429,49.7605146],[9.425623,49.7784909],[9.404213,49.7646636],[9.33356,49.770195],[9.329278,49.7342295],[9.408495,49.725926],[9.427764,49.6982374],[9.414918,49.6441991],[9.380662,49.6386533],[9.359252,49.6497443],[9.339983,49.6372668],[9.31215,49.648358],[9.277894,49.626173],[9.284317,49.6081403],[9.241497,49.5748315],[9.0980501,49.5720547],[9.0659351,49.6081403],[9.1001911,49.6511305],[9.0916271,49.6926978],[9.1301651,49.7120837],[9.1387291,49.7425316],[9.1087551,49.7563653],[9.1365881,49.7909322],[9.1001911,49.78955],[9.0723581,49.8282367],[9.0359611,49.8351418],[9.0166922,50.0267091],[8.9631672,50.0308352],[8.9567442,50.0597083],[9.0017052,50.0707031],[9.0209742,50.1105378],[9.1216011,50.1228936],[9.1558571,50.1132838],[9.1965361,50.1187753],[9.1858311,50.1352462],[9.235074,50.1475956],[9.37638,50.1270115],[9.408495,50.0816953],[9.5219679,50.095432],[9.5048399,50.1421073],[9.5326729,50.1640565],[9.4898529,50.1695422],[9.4941349,50.2435376],[9.6140309,50.221625],[9.6654148,50.2353216],[9.6354408,50.2490142],[9.6675558,50.2722826],[9.7424908,50.3092151],[9.7296448,50.3584137],[9.7703238,50.4293885],[9.8688097,50.4007384],[9.9180527,50.4089259],[10.0358076,50.479825],[10.0379486,50.5111504],[10.1235886,50.568462]]]},{"id":"GRB","name":"Belgium AGIV GRB Flanders","type":"tms","template":"http://tile.informatievlaanderen.be/ws/raadpleegdiensten/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=grb_bsk&STYLE=&FORMAT=image/png&tileMatrixSet=GoogleMapsVL&tileMatrix={zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,21],"polygon":[[[2.522393220658428,51.101723961331],[3.1260610915867457,51.34117672029327],[3.174929443042849,51.382459567439525],[3.3761520666856217,51.38784154353026],[3.410647373595811,51.33040116175589],[3.4020235468682634,51.28547573497245],[3.4911364230529203,51.256700377228974],[3.4825125963253734,51.30345118353617],[3.5773746903283947,51.323216048914524],[3.813092620881357,51.27288873325703],[3.8217164476089045,51.236906864834886],[3.9309515861578386,51.236906864834886],[4.054559769252684,51.27468708752057],[4.20116482362099,51.35194974615148],[4.169544125619984,51.38066543475199],[4.342020660170932,51.395016527087456],[4.3650175314443915,51.46491366130351],[4.5374940659953396,51.50071687469512],[4.571989372905529,51.479238319799464],[4.560490937268798,51.44879304380801],[4.638105377816725,51.45058450468522],[4.750215125274841,51.5239738914927],[4.8364533925503155,51.507874144493115],[5.080795149830825,51.49892738159079],[5.135412719105292,51.447001512638565],[5.106666630013469,51.391429175957505],[5.264770120018504,51.31782647548482],[5.264770120018504,51.28727359653538],[5.4085005654776275,51.292666758936925],[5.486115006025553,51.325012432665545],[5.5809771000285755,51.28367780302667],[5.583851708937758,51.23510703218069],[5.767826679125435,51.20449910348059],[5.8770618176743685,51.161253258857485],[5.704585283123422,50.80292546633848],[5.905807906766195,50.7865720955422],[5.9374286047672005,50.732019528192964],[5.902933297857012,50.70107817444857],[5.8138204216723555,50.69379488717487],[5.615472406938765,50.761122144578216],[5.500488050571466,50.71200098472672],[5.204403332925673,50.70289881954383],[5.164158808197117,50.67558172042608],[5.037676016193088,50.70107817444857],[4.988807664736986,50.750210783384084],[4.916942442007425,50.72656077355532],[4.790459650003396,50.766576871275696],[4.681224511454462,50.77021300246129],[4.6697260758177315,50.73565834458533],[4.287403090896464,50.67922491935501],[3.91082932379356,50.677403355240585],[3.718230526878334,50.752029520237265],[3.6549891308763196,50.71200098472672],[3.5342555566906557,50.710180693059606],[3.514133294326379,50.741116039142966],[3.45664111614273,50.74384464791457],[3.373277457776438,50.69561581502901],[3.310036061774423,50.70745012302645],[3.2899137994101473,50.7365680045137],[3.1648683118607086,50.742935129324266],[3.1318103094051106,50.77203096207303],[3.080067349039826,50.76021296163662],[2.8745328120332805,50.73929687829333],[2.8960923788521487,50.71109084772858],[2.8745328120332805,50.69561581502901],[2.796918371485353,50.70289881954383],[2.699181668573149,50.80020030189157],[2.6201299235706315,50.79747497850781],[2.5698242676599374,50.85830267681076],[2.5669496587507554,50.923581424665855],[2.6028822701155367,50.94984841176044],[2.549702005295661,50.996006093918574],[2.522393220658428,51.101723961331]]],"terms_text":"GRB Flanders (c) AGIV"},{"id":"AGIV","name":"Belgium AGIV Orthophoto Flanders","type":"tms","template":"http://tile.informatievlaanderen.be/ws/raadpleegdiensten/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=omwrgbmrvl&STYLE=&FORMAT=image/png&tileMatrixSet=GoogleMapsVL&tileMatrix={zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,21],"polygon":[[[2.522393220658428,51.101723961331],[3.1260610915867457,51.34117672029327],[3.174929443042849,51.382459567439525],[3.3761520666856217,51.38784154353026],[3.410647373595811,51.33040116175589],[3.4020235468682634,51.28547573497245],[3.4911364230529203,51.256700377228974],[3.4825125963253734,51.30345118353617],[3.5773746903283947,51.323216048914524],[3.813092620881357,51.27288873325703],[3.8217164476089045,51.236906864834886],[3.9309515861578386,51.236906864834886],[4.054559769252684,51.27468708752057],[4.20116482362099,51.35194974615148],[4.169544125619984,51.38066543475199],[4.342020660170932,51.395016527087456],[4.3650175314443915,51.46491366130351],[4.5374940659953396,51.50071687469512],[4.571989372905529,51.479238319799464],[4.560490937268798,51.44879304380801],[4.638105377816725,51.45058450468522],[4.750215125274841,51.5239738914927],[4.8364533925503155,51.507874144493115],[5.080795149830825,51.49892738159079],[5.135412719105292,51.447001512638565],[5.106666630013469,51.391429175957505],[5.264770120018504,51.31782647548482],[5.264770120018504,51.28727359653538],[5.4085005654776275,51.292666758936925],[5.486115006025553,51.325012432665545],[5.5809771000285755,51.28367780302667],[5.583851708937758,51.23510703218069],[5.767826679125435,51.20449910348059],[5.8770618176743685,51.161253258857485],[5.704585283123422,50.80292546633848],[5.905807906766195,50.7865720955422],[5.9374286047672005,50.732019528192964],[5.902933297857012,50.70107817444857],[5.8138204216723555,50.69379488717487],[5.615472406938765,50.761122144578216],[5.500488050571466,50.71200098472672],[5.204403332925673,50.70289881954383],[5.164158808197117,50.67558172042608],[5.037676016193088,50.70107817444857],[4.988807664736986,50.750210783384084],[4.916942442007425,50.72656077355532],[4.790459650003396,50.766576871275696],[4.681224511454462,50.77021300246129],[4.6697260758177315,50.73565834458533],[4.287403090896464,50.67922491935501],[3.91082932379356,50.677403355240585],[3.718230526878334,50.752029520237265],[3.6549891308763196,50.71200098472672],[3.5342555566906557,50.710180693059606],[3.514133294326379,50.741116039142966],[3.45664111614273,50.74384464791457],[3.373277457776438,50.69561581502901],[3.310036061774423,50.70745012302645],[3.2899137994101473,50.7365680045137],[3.1648683118607086,50.742935129324266],[3.1318103094051106,50.77203096207303],[3.080067349039826,50.76021296163662],[2.8745328120332805,50.73929687829333],[2.8960923788521487,50.71109084772858],[2.8745328120332805,50.69561581502901],[2.796918371485353,50.70289881954383],[2.699181668573149,50.80020030189157],[2.6201299235706315,50.79747497850781],[2.5698242676599374,50.85830267681076],[2.5669496587507554,50.923581424665855],[2.6028822701155367,50.94984841176044],[2.549702005295661,50.996006093918574],[2.522393220658428,51.101723961331]]],"terms_text":"Orthophoto Flanders most recent (c) AGIV","best":true},{"id":"Benin_cotonou_pleiade_2016","name":"Benin: Cotonou Pleiade 2016","type":"tms","template":"http://geoxxx.agrocampus-ouest.fr/owsifl/gwc/service/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=Benin:cotonou_pleiade_2016&STYLE=&FORMAT=image/jpeg&tileMatrixSet=EPSG:3857&tileMatrix=EPSG:3857:{zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,21],"polygon":[[[2.31953818544,6.55745092536],[2.33645249928,6.56023631702],[2.36377172444,6.56211241002],[2.36737717181,6.56067658005],[2.37777373205,6.54939665325],[2.3777926612,6.53484752744],[2.36994151563,6.4933195729],[2.37038356708,6.45527010853],[2.36958186167,6.45269435578],[2.36188103586,6.44177160245],[2.35391742884,6.40545220189],[2.3674929737,6.40149524022],[2.39525870424,6.40071623744],[2.40128040262,6.40374371884],[2.40587684694,6.40340733291],[2.42045897749,6.39382909301],[2.42485054154,6.3979366042],[2.42949152505,6.39887495342],[2.43625257397,6.39628121034],[2.43958410532,6.40041525877],[2.44439433776,6.40189359345],[2.45375647532,6.39899446003],[2.47144744127,6.3963166199],[2.48162019208,6.3910582748],[2.49453210303,6.38739776192],[2.50893162289,6.38888498676],[2.50719014059,6.39228876781],[2.50120407357,6.39162040687],[2.4963025358,6.39521449649],[2.49509997769,6.40123077776],[2.49543290813,6.40400928653],[2.49830345887,6.41022131795],[2.50191336015,6.41281720321],[2.5108701911,6.41321333458],[2.52218648559,6.40849403999],[2.53352059576,6.4051656109],[2.53809922441,6.40960941297],[2.5411100736,6.41090182623],[2.54650822333,6.41099034757],[2.54654385468,6.40651114868],[2.57638511144,6.40723702943],[2.57642074279,6.41176933466],[2.58575615684,6.41196408125],[2.58867792765,6.41095493903],[2.60877400982,6.39413560832],[2.62569890171,6.39487921149],[2.64554556441,6.39728706193],[2.65039142819,6.39339200408],[2.6536650586,6.36823275735],[2.6431181786,6.3665949733],[2.61251084779,6.3628944474],[2.56867983171,6.3607044406],[2.54682890549,6.36055393954],[2.54687344468,6.35546343647],[2.50206702036,6.35461353888],[2.47064016846,6.35595920942],[2.46777184468,6.35202842507],[2.46422652522,6.35020467258],[2.45253944198,6.35006302163],[2.4511320036,6.34813302357],[2.44737289603,6.34629155079],[2.43757427441,6.34653944174],[2.43297783009,6.33841209773],[2.43016295333,6.33706638135],[2.42244876576,6.33706638135],[2.39236031651,6.34114999999],[2.39315311407,6.34114999999],[2.3652849434,6.34445228474],[2.35386064137,6.34529777247],[2.34377474198,6.34457844399],[2.34093759563,6.34533982549],[2.31086028117,6.36567095094],[2.28434610184,6.37465215648],[2.28146887022,6.37761782314],[2.27599054995,6.39517244756],[2.27611525968,6.39819996182],[2.31528747657,6.4926104105],[2.31579967725,6.5530659484]],[[1.69563043958,6.25076170066],[1.70009994721,6.24711901182],[1.70417862346,6.24697179839],[1.75874803806,6.25835802546],[1.77079143482,6.25995187823],[1.81712109941,6.27161341959],[1.84456614779,6.27656750346],[1.85767848509,6.27944518918],[1.88843363033,6.28325588467],[1.90481876292,6.28594870029],[1.90617692982,6.29435189983],[1.90083111364,6.29721233234],[1.89880903445,6.29953873942],[1.89404334121,6.30085024405],[1.89047742238,6.29969866569],[1.88747882146,6.29636150888],[1.88344050885,6.29622344016],[1.86969682855,6.29226563906],[1.8564007671,6.29198230539],[1.85206654725,6.28674503171],[1.84991419093,6.28906373821],[1.84691224958,6.29202989661],[1.8435272712,6.29332703219],[1.84040507404,6.29315437611],[1.83626738336,6.29129499924],[1.83409832485,6.28733273348],[1.83416513363,6.2851988527],[1.83229560117,6.28456355663],[1.82785949792,6.28644177291],[1.82182443779,6.2908379014],[1.81562903657,6.28997904337],[1.81211044063,6.29143113241],[1.80757635117,6.29570768815],[1.80471693522,6.29692955475],[1.80073513171,6.29709778253],[1.79775991387,6.29612383144],[1.79625448928,6.29491967121],[1.79490049792,6.28965143736],[1.79641483036,6.28608317469],[1.80097564333,6.28338261222],[1.79566657198,6.28013306439],[1.79156005874,6.28174455931],[1.78498607441,6.28122215216],[1.78092410036,6.27752986974],[1.77588226414,6.27550220232],[1.76744654171,6.27696318619],[1.75653444036,6.27496207997],[1.74833032171,6.27238985028],[1.74761769468,6.27726423691],[1.74572477914,6.27938486862],[1.73948038482,6.27984972411],[1.73680357955,6.27761398678],[1.73572127725,6.27891558552],[1.72901812928,6.27911038233],[1.72435487617,6.27422273126],[1.72449294765,6.2678607472],[1.72555966124,6.26683029328],[1.69933944056,6.26159387355],[1.69572953928,6.25725948175]]],"best":true},{"id":"Bing","name":"Bing aerial imagery","type":"bing","template":"http://www.bing.com/maps/","description":"Satellite and aerial imagery.","scaleExtent":[0,22],"default":true},{"id":"British_Columbia_Mosaic","name":"British Columbia Mosaic","type":"tms","template":"http://{switch:a,b,c,d}.imagery.paulnorman.ca/tiles/bc_mosaic/{zoom}/{x}/{y}.png","scaleExtent":[9,20],"polygon":[[[-123.3176032,49.3272567],[-123.4405258,49.3268222],[-123.440717,49.3384429],[-123.4398375,49.3430357],[-123.4401258,49.3435398],[-123.4401106,49.3439946],[-123.4406265,49.3444493],[-123.4404747,49.3455762],[-123.4397768,49.3460606],[-123.4389726,49.3461298],[-123.4372904,49.3567236],[-123.4374774,49.3710843],[-123.4335292,49.3709446],[-123.4330357,49.373725],[-123.4332717,49.3751221],[-123.4322847,49.3761001],[-123.4317482,49.3791736],[-123.4314264,49.3795927],[-123.4307826,49.3823866],[-123.4313405,49.3827358],[-123.4312118,49.3838533],[-123.4300415,49.3845883],[-123.4189858,49.3847087],[-123.4192235,49.4135198],[-123.3972532,49.4135691],[-123.3972758,49.4243473],[-123.4006929,49.4243314],[-123.4007741,49.5703491],[-123.4000812,49.570345],[-123.4010761,49.5933838],[-123.3760399,49.5932848],[-123.3769811,49.6756063],[-123.3507288,49.6756396],[-123.3507969,49.7086751],[-123.332887,49.708722],[-123.3327888,49.7256288],[-123.3007111,49.7255625],[-123.3009164,49.7375384],[-123.2885986,49.737638],[-123.2887823,49.8249207],[-123.2997955,49.8249207],[-123.3011721,49.8497814],[-123.3218218,49.850669],[-123.3273284,49.8577696],[-123.3276726,49.9758852],[-123.3008279,49.9752212],[-123.3007204,50.0997002],[-123.2501716,50.100735],[-123.25091,50.2754901],[-123.0224338,50.2755598],[-123.0224879,50.3254853],[-123.0009318,50.3254689],[-123.0007778,50.3423899],[-122.9775023,50.3423408],[-122.9774766,50.3504306],[-122.9508137,50.3504961],[-122.950795,50.3711984],[-122.9325221,50.3711521],[-122.9321048,50.399793],[-122.8874234,50.3999748],[-122.8873385,50.4256108],[-122.6620152,50.4256959],[-122.6623083,50.3994506],[-122.5990316,50.3992413],[-122.5988274,50.3755206],[-122.5724832,50.3753706],[-122.5735621,50.2493891],[-122.5990415,50.2494643],[-122.5991504,50.2265663],[-122.6185016,50.2266359],[-122.6185741,50.2244081],[-122.6490609,50.2245126],[-122.6492181,50.1993528],[-122.7308575,50.1993758],[-122.7311583,50.1244287],[-122.7490352,50.1245109],[-122.7490541,50.0903032],[-122.7687806,50.0903435],[-122.7689801,49.9494546],[-122.999047,49.9494706],[-122.9991199,49.8754553],[-122.9775894,49.8754553],[-122.9778145,49.6995098],[-122.9992362,49.6994781],[-122.9992524,49.6516526],[-123.0221525,49.6516526],[-123.0221162,49.5995096],[-123.0491898,49.5994625],[-123.0491898,49.5940523],[-123.0664647,49.5940405],[-123.0663594,49.5451868],[-123.0699906,49.5451202],[-123.0699008,49.5413153],[-123.0706835,49.5392837],[-123.0708888,49.5379931],[-123.0711454,49.5368773],[-123.0711069,49.5358115],[-123.0713764,49.532822],[-123.0716458,49.5321141],[-123.07171,49.5313896],[-123.0720308,49.5304153],[-123.0739554,49.5303486],[-123.0748023,49.5294992],[-123.0748151,49.5288079],[-123.0743403,49.5280584],[-123.073532,49.5274588],[-123.0733652,49.5270423],[-123.0732882,49.5255932],[-123.0737116,49.5249602],[-123.0736218,49.5244938],[-123.0992583,49.5244854],[-123.0991649,49.4754502],[-123.071052,49.4755252],[-123.071088,49.4663034],[-123.0739204,49.4663054],[-123.07422,49.4505028],[-123.0746319,49.4500858],[-123.074651,49.449329],[-123.0745999,49.449018],[-123.0744619,49.4486927],[-123.0743336,49.4479899],[-123.0742427,49.4477688],[-123.0743061,49.4447473],[-123.0747103,49.4447556],[-123.0746384,49.4377306],[-122.9996506,49.4377363],[-122.9996506,49.4369214],[-122.8606163,49.4415314],[-122.8102616,49.4423972],[-122.8098984,49.3766739],[-122.4036093,49.3766617],[-122.4036341,49.3771944],[-122.264739,49.3773028],[-122.263542,49.2360088],[-122.2155742,49.236139],[-122.0580956,49.235878],[-121.9538274,49.2966525],[-121.9400911,49.3045389],[-121.9235761,49.3142257],[-121.8990871,49.3225436],[-121.8883447,49.3259752],[-121.8552982,49.3363575],[-121.832697,49.3441519],[-121.7671336,49.3654361],[-121.6736683,49.3654589],[-121.6404153,49.3743775],[-121.5961976,49.3860493],[-121.5861178,49.3879193],[-121.5213684,49.3994649],[-121.5117375,49.4038378],[-121.4679302,49.4229024],[-121.4416803,49.4345607],[-121.422429,49.4345788],[-121.3462885,49.3932312],[-121.3480144,49.3412388],[-121.5135035,49.320577],[-121.6031683,49.2771727],[-121.6584065,49.1856125],[-121.679953,49.1654109],[-121.7815793,49.0702559],[-121.8076228,49.0622471],[-121.9393997,49.0636219],[-121.9725524,49.0424179],[-121.9921394,49.0332869],[-122.0035289,49.0273413],[-122.0178564,49.0241067],[-122.1108634,48.9992786],[-122.1493067,48.9995305],[-122.1492705,48.9991498],[-122.1991447,48.9996019],[-122.199181,48.9991974],[-122.234365,48.9994829],[-122.234365,49.000173],[-122.3994722,49.0012385],[-122.4521338,49.0016326],[-122.4521338,49.000883],[-122.4584089,49.0009306],[-122.4584814,48.9993124],[-122.4992458,48.9995022],[-122.4992458,48.9992906],[-122.5492618,48.9995107],[-122.5492564,48.9993206],[-122.6580785,48.9994212],[-122.6581061,48.9954007],[-122.7067604,48.9955344],[-122.7519761,48.9956392],[-122.7922063,48.9957204],[-122.7921907,48.9994331],[-123.0350417,48.9995724],[-123.0350437,49.0000958],[-123.0397091,49.0000536],[-123.0397444,49.0001812],[-123.0485506,49.0001348],[-123.0485329,49.0004712],[-123.0557122,49.000448],[-123.0556324,49.0002284],[-123.0641365,49.0001293],[-123.064158,48.9999421],[-123.074899,48.9996928],[-123.0750717,49.0006218],[-123.0899573,49.0003726],[-123.109229,48.9999421],[-123.1271193,49.0003046],[-123.1359953,48.9998741],[-123.1362716,49.0005765],[-123.153851,48.9998061],[-123.1540533,49.0006806],[-123.1710015,49.0001274],[-123.2000916,48.9996849],[-123.2003446,49.0497785],[-123.2108845,49.0497232],[-123.2112218,49.051989],[-123.2070479,49.0520857],[-123.2078911,49.0607884],[-123.2191688,49.0600978],[-123.218958,49.0612719],[-123.2251766,49.0612719],[-123.2253874,49.0622388],[-123.2297088,49.0620316],[-123.2298142,49.068592],[-123.2331869,49.0687301],[-123.2335031,49.0705945],[-123.249313,49.0702493],[-123.2497346,49.0802606],[-123.2751358,49.0803986],[-123.2751358,49.0870947],[-123.299483,49.0873018],[-123.29944,49.080253],[-123.3254508,49.0803944],[-123.3254353,49.1154662],[-123.2750966,49.1503341],[-123.275181,49.1873267],[-123.2788067,49.1871063],[-123.278891,49.1910741],[-123.3004767,49.1910741],[-123.3004186,49.2622933],[-123.3126185,49.2622416],[-123.3125958,49.2714948],[-123.3154251,49.2714727],[-123.3156628,49.2818906],[-123.3174735,49.2818832],[-123.3174961,49.2918488],[-123.3190353,49.2918488],[-123.3190692,49.298602],[-123.3202349,49.2985651],[-123.3202786,49.3019749],[-123.3222679,49.3019605],[-123.3223943,49.3118263],[-123.3254002,49.3118086],[-123.3253898,49.3201721],[-123.3192695,49.3201957],[-123.3192242,49.3246748],[-123.3179437,49.3246596],[-123.3179861,49.3254065],[-123.3176032,49.3272567]]],"terms_url":"http://imagery.paulnorman.ca/tiles/about.html","terms_text":"Copyright Province of British Columbia, City of Surrey"},{"id":"osm-cambodia_laos_thailand_vietnam-bilingual","name":"Cambodia, Laos, Thailand, Vietnam, Myanmar bilingual","type":"tms","template":"http://{switch:a,b,c,d}.tile.osm-tools.org/osm_then/{zoom}/{x}/{y}.png","scaleExtent":[0,19],"polygon":[[[92.1023798,20.8135629],[93.5690546,24.0975527],[94.1733026,23.9269484],[95.1950312,26.707274],[96.7550898,27.5286657],[97.5845575,28.5805966],[98.738122,27.514051],[98.7436151,25.8799151],[97.6779413,24.7577376],[97.9635858,24.042382],[98.8205194,24.1627239],[99.5236444,22.9593356],[100.3695917,21.5051376],[101.7923212,22.4830518],[105.3628778,23.3331079],[106.8185663,22.8480137],[108.1973505,21.3619661],[107.4389505,18.8539792],[117.1453714,7.4656173],[119.6172953,5.2875389],[118.1231546,4.0502277],[117.2552347,4.3624942],[115.8654642,4.3460623],[115.5084085,3.0249771],[114.552598,1.5100953],[113.5418558,1.2574836],[112.9650736,1.5704982],[112.2454691,1.5100953],[111.67418,1.0158321],[110.4546976,0.9004918],[109.4988871,1.9218969],[103.2256937,1.1256762],[100.4626322,3.2388904],[97.6721048,8.0588831],[93.892808,15.9398659],[92.1023798,20.8135629]]],"terms_url":"http://www.osm-tools.org/","terms_text":"© osm-tools.org & OpenStreetMap contributors, CC-BY-SA"},{"id":"South_Africa-CapeTown-Aerial-2013","name":"City of Cape Town 2013 Aerial","type":"tms","template":"http://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2013/{zoom}/{x}/{y}.jpg","description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 12cm ground sample distance","scaleExtent":[1,21],"polygon":[[[18.4486565,-33.893623],[18.4485868,-33.902644],[18.4702,-33.9027665],[18.4813902,-33.8472383],[18.4492466,-33.801069],[18.4281537,-33.7356408],[18.43914,-33.7177232],[18.4071895,-33.6589917],[18.3322379,-33.5775191],[18.3324525,-33.5504487],[18.353996,-33.5505918],[18.3542535,-33.5236025],[18.3652398,-33.5236561],[18.3650252,-33.5148009],[18.3760115,-33.5147652],[18.3760545,-33.5058017],[18.4296557,-33.5059449],[18.4296986,-33.4878541],[18.4404919,-33.4878899],[18.4405991,-33.4698849],[18.4943721,-33.4700997],[18.4943292,-33.4791564],[18.5158297,-33.4791743],[18.5157439,-33.4881941],[18.5264727,-33.4883015],[18.5263225,-33.5243538],[18.5479304,-33.5244253],[18.5479519,-33.5153913],[18.5693666,-33.5154987],[18.5693666,-33.524479],[18.5801169,-33.5245327],[18.580074,-33.5425978],[18.5907814,-33.5425978],[18.5907385,-33.5606413],[18.5799453,-33.5605341],[18.5798809,-33.569617],[18.5906956,-33.569617],[18.5906526,-33.5786811],[18.6230108,-33.5787347],[18.622925,-33.5877264],[18.6659691,-33.5878872],[18.6659262,-33.614928],[18.6767194,-33.6149726],[18.6765772,-33.6510279],[18.687298,-33.6510167],[18.6873409,-33.6600365],[18.6980697,-33.6600901],[18.6980697,-33.6690733],[18.7520358,-33.6692519],[18.7520787,-33.6421924],[18.7736437,-33.642246],[18.773708,-33.6331886],[18.8274595,-33.6332958],[18.8275239,-33.6603044],[18.8166663,-33.6602866],[18.8166019,-33.6783233],[18.8058087,-33.6783055],[18.8058087,-33.7053892],[18.8273951,-33.7054428],[18.8273308,-33.7234701],[18.838124,-33.7234344],[18.8380381,-33.7413865],[18.8165161,-33.7413687],[18.8163659,-33.7955057],[18.8055941,-33.7955057],[18.8055083,-33.8135675],[18.794758,-33.8135497],[18.7947151,-33.8315364],[18.7731072,-33.8315186],[18.7731287,-33.8405194],[18.7623569,-33.8405194],[18.7622711,-33.903588],[18.7514564,-33.9035167],[18.7510809,-33.9847823],[18.7619063,-33.9848001],[18.7617776,-34.0298785],[18.772603,-34.0298963],[18.7725815,-34.0389073],[18.7940338,-34.0389406],[18.7938756,-34.0406987],[18.7984461,-34.0411855],[18.8032445,-34.0411788],[18.8034055,-34.0389206],[18.8159367,-34.038974],[18.8163444,-34.0299318],[18.8379845,-34.0316479],[18.8380006,-34.030003],[18.8484183,-34.0300074],[18.8484666,-34.0218491],[18.859925,-34.0234675],[18.8598606,-34.0210132],[18.868272,-34.0220803],[18.8681862,-34.0211733],[18.8854596,-34.0234319],[18.8851806,-34.0213156],[18.9025184,-34.021031],[18.9025828,-34.0119958],[18.9134189,-34.0119958],[18.9134833,-33.9939582],[18.9458844,-33.9940294],[18.9458629,-34.003102],[18.9674279,-34.0029953],[18.9674708,-34.0120848],[18.9782211,-34.0120848],[18.9783284,-34.0211377],[18.9891431,-34.0211377],[18.9891645,-34.039134],[19.0000167,-34.0391251],[19.0000221,-34.0571798],[19.0108368,-34.0572509],[19.0107939,-34.0841436],[19.0000007,-34.0841258],[19.0000221,-34.0931977],[18.9891538,-34.0931711],[18.9891753,-34.1021976],[18.9783177,-34.1021798],[18.9783177,-34.111232],[18.967503,-34.1112143],[18.9674923,-34.1292536],[18.9566025,-34.1292358],[18.9565596,-34.1382408],[18.9674172,-34.1383118],[18.9674172,-34.1473157],[18.9891753,-34.147298],[18.9891753,-34.165303],[18.9782748,-34.1652852],[18.9783177,-34.1742863],[18.9674172,-34.1742685],[18.9674601,-34.1833042],[18.9565596,-34.1833219],[18.9565596,-34.1923565],[18.9457449,-34.192321],[18.945702,-34.2013192],[18.9348659,-34.2013725],[18.9348873,-34.2193305],[18.9023575,-34.2193482],[18.9017567,-34.2362557],[18.8878414,-34.2373467],[18.8894185,-34.2554123],[18.8805887,-34.2553414],[18.8792744,-34.2644348],[18.8696882,-34.2644126],[18.8697097,-34.2734386],[18.8371369,-34.2734208],[18.8371155,-34.2643771],[18.848016,-34.2644037],[18.8480267,-34.237391],[18.8154861,-34.210281],[18.8156471,-34.1741265],[18.8548824,-34.1562743],[18.7617561,-34.0840547],[18.6533734,-34.077479],[18.4797433,-34.1101217],[18.4463713,-34.1342269],[18.4444508,-34.1640868],[18.4359965,-34.1640513],[18.435975,-34.1820172],[18.4468111,-34.182106],[18.4467253,-34.1911052],[18.4659299,-34.1912117],[18.4866151,-34.2453911],[18.4788904,-34.2543659],[18.4860036,-34.2543748],[18.4677109,-34.2994116],[18.4892222,-34.3445792],[18.500112,-34.3445837],[18.4999189,-34.3626174],[18.467432,-34.3625111],[18.4673676,-34.3534947],[18.3916005,-34.3170651],[18.3917722,-34.2900161],[18.3701643,-34.2808678],[18.370682,-34.2178866],[18.3492324,-34.1816178],[18.3274743,-34.1814936],[18.3276674,-34.1634565],[18.3118746,-34.1543832],[18.3114025,-34.1435331],[18.3236656,-34.1346886],[18.3499297,-34.1042053],[18.3393189,-34.0882843],[18.3612487,-34.0597219],[18.3550474,-34.0553843],[18.3427522,-34.064326],[18.3199963,-34.0644326],[18.296071,-34.045126],[18.3068213,-34.0252637],[18.3287725,-34.0191992],[18.3289227,-34.001252],[18.3397374,-34.0012698],[18.3398017,-33.9866282],[18.3628687,-33.9735145],[18.3638129,-33.9292474],[18.3726212,-33.9292741],[18.3728358,-33.917763],[18.3977267,-33.8933469],[18.4486565,-33.893623]]],"terms_url":"https://www.capetown.gov.za","terms_text":"City of Cape Town Aerial - OPENSTREETMAP USE ONLY"},{"id":"South_Africa-CapeTown-Aerial","name":"City of Cape Town 2015 Aerial","type":"tms","template":"http://{switch:a,b,c}.coct.aerial.openstreetmap.org.za/layer/za_coct_aerial_2015/{zoom}/{x}/{y}.jpg","description":"OpenStreetMap use only. City of Cape Town Aerial ortho-photography of the municipal area. 8cm ground sample distance","scaleExtent":[1,21],"polygon":[[[18.4486565,-33.893623],[18.4485868,-33.902644],[18.4702,-33.9027665],[18.4813902,-33.8472383],[18.4492466,-33.801069],[18.4281537,-33.7356408],[18.43914,-33.7177232],[18.4071895,-33.6589917],[18.3322379,-33.5775191],[18.3324525,-33.5504487],[18.353996,-33.5505918],[18.3542535,-33.5236025],[18.3652398,-33.5236561],[18.3650252,-33.5148009],[18.3760115,-33.5147652],[18.3760545,-33.5058017],[18.4296557,-33.5059449],[18.4296986,-33.4878541],[18.4404919,-33.4878899],[18.4405991,-33.4698849],[18.4943721,-33.4700997],[18.4943292,-33.4791564],[18.5158297,-33.4791743],[18.5157439,-33.4881941],[18.5264727,-33.4883015],[18.5263225,-33.5243538],[18.5479304,-33.5244253],[18.5479519,-33.5153913],[18.5693666,-33.5154987],[18.5693666,-33.524479],[18.5801169,-33.5245327],[18.580074,-33.5425978],[18.5907814,-33.5425978],[18.5907385,-33.5606413],[18.5799453,-33.5605341],[18.5798809,-33.569617],[18.5906956,-33.569617],[18.5906526,-33.5786811],[18.6230108,-33.5787347],[18.622925,-33.5877264],[18.6659691,-33.5878872],[18.6659262,-33.614928],[18.6767194,-33.6149726],[18.6765772,-33.6510279],[18.687298,-33.6510167],[18.6873409,-33.6600365],[18.6980697,-33.6600901],[18.6980697,-33.6690733],[18.7520358,-33.6692519],[18.7520787,-33.6421924],[18.7736437,-33.642246],[18.773708,-33.6331886],[18.8274595,-33.6332958],[18.8275239,-33.6603044],[18.8166663,-33.6602866],[18.8166019,-33.6783233],[18.8058087,-33.6783055],[18.8058087,-33.7053892],[18.8273951,-33.7054428],[18.8273308,-33.7234701],[18.838124,-33.7234344],[18.8380381,-33.7413865],[18.8165161,-33.7413687],[18.8163659,-33.7955057],[18.8055941,-33.7955057],[18.8055083,-33.8135675],[18.794758,-33.8135497],[18.7947151,-33.8315364],[18.7731072,-33.8315186],[18.7731287,-33.8405194],[18.7623569,-33.8405194],[18.7622711,-33.903588],[18.7514564,-33.9035167],[18.7510809,-33.9847823],[18.7619063,-33.9848001],[18.7617776,-34.0298785],[18.772603,-34.0298963],[18.7725815,-34.0389073],[18.7940338,-34.0389406],[18.7938756,-34.0406987],[18.7984461,-34.0411855],[18.8032445,-34.0411788],[18.8034055,-34.0389206],[18.8159367,-34.038974],[18.8163444,-34.0299318],[18.8379845,-34.0316479],[18.8380006,-34.030003],[18.8484183,-34.0300074],[18.8484666,-34.0218491],[18.859925,-34.0234675],[18.8598606,-34.0210132],[18.868272,-34.0220803],[18.8681862,-34.0211733],[18.8854596,-34.0234319],[18.8851806,-34.0213156],[18.9025184,-34.021031],[18.9025828,-34.0119958],[18.9134189,-34.0119958],[18.9134833,-33.9939582],[18.9458844,-33.9940294],[18.9458629,-34.003102],[18.9674279,-34.0029953],[18.9674708,-34.0120848],[18.9782211,-34.0120848],[18.9783284,-34.0211377],[18.9891431,-34.0211377],[18.9891645,-34.039134],[19.0000167,-34.0391251],[19.0000221,-34.0571798],[19.0108368,-34.0572509],[19.0107939,-34.0841436],[19.0000007,-34.0841258],[19.0000221,-34.0931977],[18.9891538,-34.0931711],[18.9891753,-34.1021976],[18.9783177,-34.1021798],[18.9783177,-34.111232],[18.967503,-34.1112143],[18.9674923,-34.1292536],[18.9566025,-34.1292358],[18.9565596,-34.1382408],[18.9674172,-34.1383118],[18.9674172,-34.1473157],[18.9891753,-34.147298],[18.9891753,-34.165303],[18.9782748,-34.1652852],[18.9783177,-34.1742863],[18.9674172,-34.1742685],[18.9674601,-34.1833042],[18.9565596,-34.1833219],[18.9565596,-34.1923565],[18.9457449,-34.192321],[18.945702,-34.2013192],[18.9348659,-34.2013725],[18.9348873,-34.2193305],[18.9023575,-34.2193482],[18.9017567,-34.2362557],[18.8878414,-34.2373467],[18.8894185,-34.2554123],[18.8805887,-34.2553414],[18.8792744,-34.2644348],[18.8696882,-34.2644126],[18.8697097,-34.2734386],[18.8371369,-34.2734208],[18.8371155,-34.2643771],[18.848016,-34.2644037],[18.8480267,-34.237391],[18.8154861,-34.210281],[18.8156471,-34.1741265],[18.8548824,-34.1562743],[18.7617561,-34.0840547],[18.6533734,-34.077479],[18.4797433,-34.1101217],[18.4463713,-34.1342269],[18.4444508,-34.1640868],[18.4359965,-34.1640513],[18.435975,-34.1820172],[18.4468111,-34.182106],[18.4467253,-34.1911052],[18.4659299,-34.1912117],[18.4866151,-34.2453911],[18.4788904,-34.2543659],[18.4860036,-34.2543748],[18.4677109,-34.2994116],[18.4892222,-34.3445792],[18.500112,-34.3445837],[18.4999189,-34.3626174],[18.467432,-34.3625111],[18.4673676,-34.3534947],[18.3916005,-34.3170651],[18.3917722,-34.2900161],[18.3701643,-34.2808678],[18.370682,-34.2178866],[18.3492324,-34.1816178],[18.3274743,-34.1814936],[18.3276674,-34.1634565],[18.3118746,-34.1543832],[18.3114025,-34.1435331],[18.3236656,-34.1346886],[18.3499297,-34.1042053],[18.3393189,-34.0882843],[18.3612487,-34.0597219],[18.3550474,-34.0553843],[18.3427522,-34.064326],[18.3199963,-34.0644326],[18.296071,-34.045126],[18.3068213,-34.0252637],[18.3287725,-34.0191992],[18.3289227,-34.001252],[18.3397374,-34.0012698],[18.3398017,-33.9866282],[18.3628687,-33.9735145],[18.3638129,-33.9292474],[18.3726212,-33.9292741],[18.3728358,-33.917763],[18.3977267,-33.8933469],[18.4486565,-33.893623]]],"terms_url":"https://www.capetown.gov.za","terms_text":"City of Cape Town Aerial - OPENSTREETMAP USE ONLY","best":true},{"id":"CRAIG-Auvergne-2013","name":"CRAIG - Auvergne 2013 - 25 cm","type":"tms","template":"http://tiles.craig.fr/osm/tms/1.0.0/ortho_2013/webmercator/{zoom-1}/{x}/{-y}.jpeg","polygon":[[[2.9401192,44.6338837],[2.9971896,44.633931],[2.9971676,44.6473385],[3.0159744,44.6473541],[3.0159305,44.6741168],[3.0349486,44.6741326],[3.0349036,44.7015216],[3.0536338,44.7015371],[3.0535675,44.7418954],[3.0723301,44.741911],[3.0722196,44.8091687],[3.0921583,44.8091852],[3.092137,44.8221252],[3.1301398,44.8221567],[3.1300495,44.8770722],[3.1485587,44.8770875],[3.1485807,44.8636964],[3.1682313,44.8637126],[3.1682538,44.8500261],[3.2064,44.8500576],[3.2063789,44.8628393],[3.2439492,44.8628704],[3.2439263,44.8767893],[3.2631452,44.8768052],[3.2630782,44.9175197],[3.3200437,44.9175667],[3.3200227,44.9303336],[3.3390815,44.9303493],[3.3390586,44.9441978],[3.3769989,44.9442292],[3.3770218,44.9302879],[3.396031,44.9303036],[3.39612,44.8762713],[3.4148252,44.8762867],[3.4148923,44.8355255],[3.4333371,44.8355408],[3.4333819,44.8082784],[3.4525549,44.8082943],[3.4525774,44.7946344],[3.5089262,44.7946811],[3.508904,44.8081469],[3.604265,44.8082258],[3.6042213,44.8348239],[3.6236136,44.83484],[3.6235695,44.8616583],[3.6424823,44.8616739],[3.642549,44.821102],[3.6610055,44.8211172],[3.6610275,44.8077696],[3.6992999,44.8078013],[3.6992782,44.820994],[3.7361139,44.8210245],[3.7361819,44.7797075],[3.7751058,44.7797397],[3.775151,44.7522344],[3.8118352,44.7522648],[3.8118567,44.7392021],[3.8311822,44.7392181],[3.8312061,44.7246766],[3.887824,44.7247235],[3.8878019,44.7381833],[3.925626,44.7382146],[3.9256039,44.7516682],[3.9454097,44.7516846],[3.9453656,44.7784691],[3.9643737,44.7784848],[3.9643516,44.7919273],[4.0033183,44.7919596],[4.0032964,44.8052575],[4.0216937,44.8052727],[4.0216718,44.8185687],[4.0596515,44.8186001],[4.0596082,44.8449216],[4.0798132,44.8449383],[4.0797928,44.8573502],[4.173882,44.857428],[4.1738604,44.8705468],[4.1932576,44.8705628],[4.193235,44.8842744],[4.2140385,44.8842916],[4.2139961,44.9100242],[4.2324138,44.9100394],[4.2323689,44.9373093],[4.2715486,44.9373416],[4.2715273,44.9502971],[4.3288672,44.9503445],[4.3287793,45.0036659],[4.3489259,45.0036825],[4.3489038,45.0170656],[4.4060793,45.0171127],[4.4059904,45.0710024],[4.3884707,45.0709879],[4.3884482,45.0845976],[4.407943,45.0846137],[4.4079231,45.09663],[4.4843608,45.0966929],[4.4842941,45.1370472],[4.4663631,45.1370324],[4.4663413,45.1502035],[4.4864469,45.15022],[4.4864022,45.1772415],[4.5065524,45.177258],[4.5064402,45.2450058],[4.4881342,45.2449908],[4.4881106,45.2592077],[4.4698588,45.2591927],[4.469836,45.2729835],[4.4508849,45.2729679],[4.4508626,45.2864203],[4.3936753,45.2863733],[4.3936303,45.3135182],[4.3750893,45.3135029],[4.3750662,45.3274054],[4.3950734,45.3274218],[4.3950283,45.3545849],[4.3767871,45.35457],[4.3767639,45.3685486],[4.3576564,45.3685329],[4.3576335,45.3823359],[4.2814576,45.3822734],[4.2814334,45.3968834],[4.2444556,45.3968531],[4.2444325,45.4107893],[4.1481178,45.4107104],[4.1481388,45.3980659],[4.1291913,45.3980504],[4.1292145,45.3840899],[4.0902138,45.3840579],[4.0902351,45.3712093],[4.0135507,45.3711464],[4.0135259,45.3860975],[3.9170932,45.3860185],[3.9170704,45.3997355],[3.9375703,45.3997523],[3.9375481,45.4131142],[3.975277,45.4131451],[3.9752552,45.4262061],[3.9953725,45.4262226],[3.9956999,45.5209568],[3.9777821,45.5209421],[3.977693,45.5743873],[3.9581755,45.5743714],[3.9581522,45.5883658],[3.9396019,45.5883506],[3.9395781,45.6026212],[3.9202279,45.6026054],[3.9202048,45.6164603],[3.8818916,45.616429],[3.8818468,45.643276],[3.8441329,45.6432453],[3.8441098,45.6570896],[3.8261689,45.657075],[3.8261241,45.6838865],[3.8072175,45.6838711],[3.8071277,45.7375802],[3.7882101,45.7375648],[3.7881863,45.7517966],[3.7688482,45.7517809],[3.7688028,45.7789651],[3.750719,45.7789504],[3.7505822,45.8606554],[3.7696692,45.8606709],[3.7695793,45.914333],[3.751661,45.9143185],[3.7516379,45.9280879],[3.7328974,45.9280727],[3.7328527,45.9547155],[3.8101795,45.9547782],[3.8101569,45.9682278],[3.8495994,45.9682598],[3.8495098,46.0216192],[3.8318849,46.0216049],[3.8317936,46.0759058],[3.8505037,46.0759209],[3.8504583,46.1029545],[3.8324727,46.10294],[3.8323353,46.1845598],[3.8142194,46.1845452],[3.8141522,46.2244234],[3.8336864,46.2244392],[3.8336634,46.2381001],[3.8528929,46.2381156],[3.8528703,46.2514729],[3.8931424,46.2515054],[3.8931205,46.2644677],[3.9130562,46.2644838],[3.9130335,46.2779317],[3.9518926,46.2779631],[3.9518709,46.2908227],[3.971523,46.2908386],[3.9715012,46.3036947],[4.0105021,46.3037261],[4.0104784,46.3177638],[4.0298278,46.3177794],[4.029783,46.3442827],[4.0116018,46.344268],[4.0114647,46.4253437],[4.031532,46.4253598],[4.0314635,46.4657978],[4.0132435,46.4657832],[4.0132204,46.479378],[3.9943703,46.4793629],[3.9943461,46.4936113],[3.9745971,46.4935955],[3.9745735,46.5075278],[3.8775423,46.5074499],[3.8774959,46.5347758],[3.8583577,46.5347605],[3.8583347,46.5483156],[3.8186897,46.5482838],[3.8187114,46.5355316],[3.7992386,46.535516],[3.7992156,46.5490706],[3.7610377,46.5490399],[3.7609226,46.6168059],[3.7423295,46.616791],[3.7422834,46.6439624],[3.7228558,46.6439468],[3.7228098,46.6710357],[3.7038706,46.6710206],[3.7038474,46.6846709],[3.6841096,46.6846551],[3.6840631,46.711998],[3.6648359,46.7119826],[3.6647898,46.7390375],[3.6457623,46.7390222],[3.6457158,46.7663375],[3.6257542,46.7663216],[3.6257314,46.7797093],[3.5672301,46.7796626],[3.5672528,46.7663082],[3.5471462,46.7662922],[3.5471922,46.7392824],[3.5271621,46.7392664],[3.5272308,46.6988967],[3.4877399,46.6988651],[3.4877618,46.685943],[3.4679636,46.6859272],[3.4679407,46.6994059],[3.4679179,46.7127907],[3.4486497,46.7127753],[3.4486258,46.7267878],[3.350433,46.7267092],[3.3504786,46.6999004],[3.3303913,46.6998843],[3.3303448,46.7271984],[3.2327174,46.7271203],[3.2327406,46.7135148],[3.2129042,46.7134989],[3.212927,46.7001302],[3.1735446,46.7000987],[3.173498,46.7275094],[3.1541227,46.7274939],[3.1541002,46.7407271],[3.1147772,46.7406957],[3.114754,46.7542756],[3.0753432,46.7542441],[3.0752971,46.7813548],[3.05597,46.7813394],[3.055924,46.8083069],[2.99704,46.8082598],[2.9970166,46.8219593],[2.9379443,46.8219121],[2.9379675,46.8082604],[2.8986634,46.808229],[2.8986872,46.7942392],[2.878991,46.7942234],[2.8790134,46.7810427],[2.8594188,46.781027],[2.8594415,46.7677056],[2.8400446,46.7676901],[2.8400671,46.754466],[2.7414032,46.7543871],[2.741382,46.7668245],[2.7023351,46.7667932],[2.7023571,46.7538869],[2.6826621,46.7538711],[2.6826849,46.7404752],[2.6634875,46.7404599],[2.6635123,46.7258966],[2.6434164,46.7258805],[2.6434382,46.7130938],[2.6241432,46.7130784],[2.6241658,46.6998093],[2.6039699,46.6997931],[2.6039936,46.6858433],[2.5651245,46.6858122],[2.5651469,46.6726126],[2.5459278,46.6725972],[2.5459966,46.6321534],[2.5659222,46.6321694],[2.565946,46.6181104],[2.5456397,46.6180941],[2.5456862,46.5907192],[2.5664225,46.5907358],[2.5664449,46.5775417],[2.5854963,46.577557],[2.5855181,46.5647199],[2.5661318,46.5647044],[2.5661557,46.5506246],[2.468279,46.5505461],[2.4683039,46.5358205],[2.3321246,46.5357112],[2.3321701,46.5088566],[2.3126474,46.5088409],[2.3126703,46.4953444],[2.2928767,46.4953285],[2.2928996,46.4818182],[2.2748687,46.4818037],[2.2749151,46.4544154],[2.2553921,46.4543997],[2.255529,46.3734888],[2.275948,46.3735052],[2.276037,46.3208741],[2.3145615,46.3209052],[2.3145849,46.3070421],[2.3537075,46.3070737],[2.3537313,46.2929669],[2.3938428,46.2929992],[2.3938862,46.2672854],[2.4515727,46.267332],[2.451596,46.2534921],[2.4709353,46.2535077],[2.4709807,46.2265552],[2.4915062,46.2265718],[2.4915521,46.199329],[2.5108806,46.1993446],[2.5109254,46.1727799],[2.5311728,46.1727963],[2.5313772,46.051352],[2.5516349,46.0513684],[2.5516577,46.0377665],[2.5705635,46.0377818],[2.5706774,45.9699434],[2.5514356,45.9699278],[2.551458,45.9566151],[2.5322621,45.9565995],[2.5322849,45.9430066],[2.5130653,45.942991],[2.513134,45.9020279],[2.4749412,45.9019969],[2.4749633,45.8888235],[2.4361947,45.888792],[2.4362172,45.8753288],[2.417209,45.8753133],[2.4172548,45.8479368],[2.3784736,45.8479053],[2.378497,45.8339746],[2.3595157,45.8339592],[2.3595606,45.8070849],[2.3787254,45.8071005],[2.3787481,45.7935783],[2.3986981,45.7935945],[2.3987203,45.7803477],[2.4182486,45.7803636],[2.4183161,45.7400007],[2.4572171,45.7400324],[2.4572394,45.7266956],[2.4758919,45.7267107],[2.4759144,45.7132391],[2.49533,45.7132549],[2.4954204,45.6591268],[2.4576942,45.659096],[2.4577622,45.618343],[2.4391188,45.6183278],[2.4391866,45.5776619],[2.4585044,45.5776777],[2.4585496,45.5505348],[2.4780887,45.5505508],[2.4781108,45.5372464],[2.4975506,45.5372623],[2.4975949,45.5106757],[2.4785536,45.5106601],[2.4786444,45.4561337],[2.4597798,45.4561183],[2.4598701,45.401757],[2.4224876,45.4017264],[2.4224651,45.4152816],[2.4023154,45.4152651],[2.4022929,45.4288193],[2.3256006,45.4287565],[2.3256684,45.3879609],[2.3456182,45.3879773],[2.3456629,45.3611091],[2.326256,45.3610932],[2.326279,45.3472146],[2.3073819,45.3471991],[2.3074045,45.3335972],[2.2881095,45.3335813],[2.2881307,45.3208191],[2.2696332,45.3208039],[2.2696574,45.306212],[2.2506602,45.3061964],[2.2506828,45.2925147],[2.2316866,45.2924992],[2.2317086,45.2792355],[2.2130009,45.2792202],[2.213046,45.2520355],[2.1937387,45.2520197],[2.1937617,45.2381134],[2.1756091,45.2380985],[2.1757423,45.1576822],[2.1573543,45.157667],[2.1574448,45.1029478],[2.1202408,45.1029172],[2.1202629,45.0895468],[2.1006669,45.0895306],[2.1006902,45.0754441],[2.0824591,45.0754291],[2.082548,45.0215961],[2.1025534,45.0216126],[2.1025982,44.994453],[2.0457406,44.9944061],[2.0458508,44.9275321],[2.0657794,44.9275486],[2.0658912,44.8596881],[2.0856964,44.8597044],[2.0857193,44.8458126],[2.1055593,44.8458291],[2.1056029,44.8193264],[2.124743,44.8193422],[2.1247657,44.805512],[2.1435067,44.8055275],[2.143551,44.778597],[2.1256091,44.7785822],[2.1256984,44.7242739],[2.1066459,44.7242581],[2.1067116,44.6842263],[2.1263414,44.6842426],[2.1263635,44.670735],[2.14598,44.6707513],[2.146069,44.6164441],[2.1839622,44.6164756],[2.183983,44.6037819],[2.2404173,44.6038288],[2.2403728,44.6309515],[2.25948,44.6309674],[2.2594571,44.644934],[2.316678,44.6449815],[2.3167011,44.6308801],[2.3361516,44.6308963],[2.3361734,44.6175824],[2.3724238,44.6176125],[2.3724009,44.6315823],[2.4110495,44.6316144],[2.4110701,44.6190741],[2.4492173,44.6191058],[2.4491956,44.6323197],[2.5048575,44.6323659],[2.5048126,44.6597555],[2.5246119,44.6597719],[2.524567,44.6871739],[2.5422544,44.6871886],[2.5422313,44.70122],[2.5807101,44.701252],[2.5805999,44.7683374],[2.61769,44.7683681],[2.6176235,44.808838],[2.6367564,44.8088539],[2.6366899,44.8492948],[2.6733105,44.8493251],[2.6732888,44.8625164],[2.6933766,44.862533],[2.6933323,44.8894303],[2.7305201,44.8894611],[2.7304757,44.9164461],[2.7499202,44.9164622],[2.7500519,44.8364688],[2.8073346,44.8365162],[2.8073139,44.8491017],[2.8263796,44.8491175],[2.8264007,44.8362845],[2.8457039,44.8363004],[2.8457707,44.7957107],[2.8642166,44.795726],[2.8642611,44.7686452],[2.8839885,44.7686615],[2.8840323,44.7419697],[2.9020315,44.7419846],[2.9021426,44.6743192],[2.9219777,44.6743357],[2.9220221,44.6472986],[2.9400972,44.6473136],[2.9401192,44.6338837]]],"terms_url":"http://wiki.openstreetmap.org/wiki/WikiProject_France/CRAIG","terms_text":"Orthophotographie CRAIG/Sintegra/IGN 2013"},{"id":"Czech_CUZK-KM-tms","name":"Czech CUZK:KM tiles proxy","type":"tms","template":"http://osm-{switch:a,b,c}.zby.cz/tiles_cuzk.php/{zoom}/{x}/{y}.png","scaleExtent":[13,18],"polygon":[[[15.0063684,49.0177392],[15.1559854,49.0013828],[15.190896,48.9424551],[15.3105895,48.9882938],[15.4053469,48.9752013],[15.5400022,48.9162426],[15.7145553,48.8670572],[15.8342488,48.880178],[15.968904,48.8178233],[16.0885976,48.7455261],[16.3978059,48.7455261],[16.4875761,48.8145394],[16.6721036,48.7784014],[16.6820781,48.7356594],[16.9015163,48.7126294],[16.9464014,48.6237005],[17.1159672,48.8375227],[17.2107246,48.880178],[17.4052266,48.8178233],[17.4800351,48.8539329],[17.5299074,48.8178233],[17.7044605,48.8670572],[17.8141796,48.9359033],[17.8840008,48.9359033],[17.9438476,49.0210099],[18.0635412,49.0340903],[18.1184007,49.0994409],[18.1981964,49.3047337],[18.3877112,49.3339917],[18.577226,49.5091747],[18.7567663,49.4994587],[18.8465365,49.5253637],[18.8764598,49.5706645],[18.7966641,49.693412],[18.64206,49.7095399],[18.5872004,49.8351543],[18.6121366,49.8833809],[18.5622643,49.9347695],[18.512392,49.9058702],[18.362775,49.9540261],[18.3278644,49.9219275],[18.2630304,49.9732751],[18.1184007,50.0053395],[18.0635412,50.075806],[17.9139242,49.9796897],[17.779269,50.0309757],[17.714435,50.1237921],[17.6047159,50.1653411],[17.7593201,50.21962],[17.7343839,50.3439092],[17.6396265,50.2802117],[17.3802905,50.2802117],[17.3503671,50.3439092],[17.2805459,50.3375433],[17.1857885,50.4075214],[16.9015163,50.4615247],[16.8666057,50.4138779],[16.9663503,50.3184404],[17.0361715,50.2323826],[16.8366823,50.21962],[16.7120015,50.1046034],[16.5823335,50.1589513],[16.5623846,50.2387626],[16.4327166,50.3375433],[16.3529209,50.3916263],[16.2781124,50.3916263],[16.2082911,50.4456477],[16.3978059,50.5344899],[16.4476782,50.5978464],[16.3529209,50.670601],[16.2382145,50.6769221],[16.2182656,50.6326561],[16.1284954,50.6832425],[16.0486997,50.6073425],[15.988853,50.7021983],[15.8741467,50.6832425],[15.8292616,50.7653291],[15.729517,50.743243],[15.450232,50.8157725],[15.3903852,50.7747914],[15.3804108,50.8598659],[15.2956278,50.8850434],[15.2956278,50.9887568],[15.1709471,51.0201394],[14.9914067,51.0013124],[15.0063684,50.8881896],[14.8417898,50.8756034],[14.7969047,50.8252246],[14.6323261,50.8567177],[14.6622495,50.9353576],[14.5724793,50.9227841],[14.6123772,50.9856174],[14.4976708,51.0483657],[14.4178751,51.0232765],[14.3081561,51.0671736],[14.2532965,51.0044508],[14.4029134,50.9322145],[14.3729901,50.897627],[14.2433221,50.9070625],[14.2084114,50.844123],[14.0338583,50.8126214],[13.9789988,50.8252246],[13.9041903,50.7968626],[13.8742669,50.740087],[13.5351352,50.7243038],[13.530148,50.6579561],[13.4703012,50.6136722],[13.3905055,50.664279],[13.3256715,50.5883483],[13.250863,50.6105074],[13.1960035,50.5059517],[13.0513738,50.5218084],[12.9665909,50.4106997],[12.8269484,50.4710483],[12.7022676,50.4138779],[12.5077656,50.401164],[12.343187,50.2547088],[12.323238,50.1845054],[12.2484296,50.2738373],[12.1736211,50.3311765],[12.0988126,50.33436],[12.1187616,50.25152],[12.2234934,50.1653411],[12.2035445,50.1237921],[12.5027784,49.9732751],[12.4778422,49.9379795],[12.5476634,49.9155052],[12.4678677,49.8029766],[12.408021,49.7611134],[12.4828294,49.6869593],[12.5327017,49.6869593],[12.5177401,49.6288466],[12.6075102,49.5415474],[12.6723442,49.4378793],[12.8119867,49.3469896],[12.9466419,49.3437405],[13.2309141,49.1288206],[13.3256715,49.1059712],[13.4353906,49.0438984],[13.4154417,48.9948387],[13.5002246,48.949006],[13.5650586,48.9882938],[13.6847522,48.8834577],[13.7445989,48.9031312],[13.8243946,48.7751149],[13.8992031,48.7751149],[14.0587945,48.676418],[14.0438328,48.6302932],[14.1435774,48.5907241],[14.3729901,48.5610269],[14.4827091,48.6500662],[14.5774665,48.607215],[14.6273389,48.6335892],[14.7071346,48.5808269],[14.7470324,48.7027561],[14.8118664,48.7389485],[14.8168536,48.794831],[14.9864195,48.7652539],[15.0063684,49.0177392]]],"overlay":true},{"id":"Czech_RUIAN-budovy","name":"Czech RUIAN budovy","type":"tms","template":"http://tile.poloha.net/budovy/{zoom}/{x}/{y}.png","scaleExtent":[12,20],"polygon":[[[15.0063684,49.0177392],[15.1559854,49.0013828],[15.190896,48.9424551],[15.3105895,48.9882938],[15.4053469,48.9752013],[15.5400022,48.9162426],[15.7145553,48.8670572],[15.8342488,48.880178],[15.968904,48.8178233],[16.0885976,48.7455261],[16.3978059,48.7455261],[16.4875761,48.8145394],[16.6721036,48.7784014],[16.6820781,48.7356594],[16.9015163,48.7126294],[16.9464014,48.6237005],[17.1159672,48.8375227],[17.2107246,48.880178],[17.4052266,48.8178233],[17.4800351,48.8539329],[17.5299074,48.8178233],[17.7044605,48.8670572],[17.8141796,48.9359033],[17.8840008,48.9359033],[17.9438476,49.0210099],[18.0635412,49.0340903],[18.1184007,49.0994409],[18.1981964,49.3047337],[18.3877112,49.3339917],[18.577226,49.5091747],[18.7567663,49.4994587],[18.8465365,49.5253637],[18.8764598,49.5706645],[18.7966641,49.693412],[18.64206,49.7095399],[18.5872004,49.8351543],[18.6121366,49.8833809],[18.5622643,49.9347695],[18.512392,49.9058702],[18.362775,49.9540261],[18.3278644,49.9219275],[18.2630304,49.9732751],[18.1184007,50.0053395],[18.0635412,50.075806],[17.9139242,49.9796897],[17.779269,50.0309757],[17.714435,50.1237921],[17.6047159,50.1653411],[17.7593201,50.21962],[17.7343839,50.3439092],[17.6396265,50.2802117],[17.3802905,50.2802117],[17.3503671,50.3439092],[17.2805459,50.3375433],[17.1857885,50.4075214],[16.9015163,50.4615247],[16.8666057,50.4138779],[16.9663503,50.3184404],[17.0361715,50.2323826],[16.8366823,50.21962],[16.7120015,50.1046034],[16.5823335,50.1589513],[16.5623846,50.2387626],[16.4327166,50.3375433],[16.3529209,50.3916263],[16.2781124,50.3916263],[16.2082911,50.4456477],[16.3978059,50.5344899],[16.4476782,50.5978464],[16.3529209,50.670601],[16.2382145,50.6769221],[16.2182656,50.6326561],[16.1284954,50.6832425],[16.0486997,50.6073425],[15.988853,50.7021983],[15.8741467,50.6832425],[15.8292616,50.7653291],[15.729517,50.743243],[15.450232,50.8157725],[15.3903852,50.7747914],[15.3804108,50.8598659],[15.2956278,50.8850434],[15.2956278,50.9887568],[15.1709471,51.0201394],[14.9914067,51.0013124],[15.0063684,50.8881896],[14.8417898,50.8756034],[14.7969047,50.8252246],[14.6323261,50.8567177],[14.6622495,50.9353576],[14.5724793,50.9227841],[14.6123772,50.9856174],[14.4976708,51.0483657],[14.4178751,51.0232765],[14.3081561,51.0671736],[14.2532965,51.0044508],[14.4029134,50.9322145],[14.3729901,50.897627],[14.2433221,50.9070625],[14.2084114,50.844123],[14.0338583,50.8126214],[13.9789988,50.8252246],[13.9041903,50.7968626],[13.8742669,50.740087],[13.5351352,50.7243038],[13.530148,50.6579561],[13.4703012,50.6136722],[13.3905055,50.664279],[13.3256715,50.5883483],[13.250863,50.6105074],[13.1960035,50.5059517],[13.0513738,50.5218084],[12.9665909,50.4106997],[12.8269484,50.4710483],[12.7022676,50.4138779],[12.5077656,50.401164],[12.343187,50.2547088],[12.323238,50.1845054],[12.2484296,50.2738373],[12.1736211,50.3311765],[12.0988126,50.33436],[12.1187616,50.25152],[12.2234934,50.1653411],[12.2035445,50.1237921],[12.5027784,49.9732751],[12.4778422,49.9379795],[12.5476634,49.9155052],[12.4678677,49.8029766],[12.408021,49.7611134],[12.4828294,49.6869593],[12.5327017,49.6869593],[12.5177401,49.6288466],[12.6075102,49.5415474],[12.6723442,49.4378793],[12.8119867,49.3469896],[12.9466419,49.3437405],[13.2309141,49.1288206],[13.3256715,49.1059712],[13.4353906,49.0438984],[13.4154417,48.9948387],[13.5002246,48.949006],[13.5650586,48.9882938],[13.6847522,48.8834577],[13.7445989,48.9031312],[13.8243946,48.7751149],[13.8992031,48.7751149],[14.0587945,48.676418],[14.0438328,48.6302932],[14.1435774,48.5907241],[14.3729901,48.5610269],[14.4827091,48.6500662],[14.5774665,48.607215],[14.6273389,48.6335892],[14.7071346,48.5808269],[14.7470324,48.7027561],[14.8118664,48.7389485],[14.8168536,48.794831],[14.9864195,48.7652539]]],"terms_url":"http://poloha.net/"},{"id":"Czech_RUIAN-parcely","name":"Czech RUIAN parcely","type":"tms","template":"http://tile.poloha.net/parcely/{zoom}/{x}/{y}.png","scaleExtent":[12,20],"polygon":[[[15.0063684,49.0177392],[15.1559854,49.0013828],[15.190896,48.9424551],[15.3105895,48.9882938],[15.4053469,48.9752013],[15.5400022,48.9162426],[15.7145553,48.8670572],[15.8342488,48.880178],[15.968904,48.8178233],[16.0885976,48.7455261],[16.3978059,48.7455261],[16.4875761,48.8145394],[16.6721036,48.7784014],[16.6820781,48.7356594],[16.9015163,48.7126294],[16.9464014,48.6237005],[17.1159672,48.8375227],[17.2107246,48.880178],[17.4052266,48.8178233],[17.4800351,48.8539329],[17.5299074,48.8178233],[17.7044605,48.8670572],[17.8141796,48.9359033],[17.8840008,48.9359033],[17.9438476,49.0210099],[18.0635412,49.0340903],[18.1184007,49.0994409],[18.1981964,49.3047337],[18.3877112,49.3339917],[18.577226,49.5091747],[18.7567663,49.4994587],[18.8465365,49.5253637],[18.8764598,49.5706645],[18.7966641,49.693412],[18.64206,49.7095399],[18.5872004,49.8351543],[18.6121366,49.8833809],[18.5622643,49.9347695],[18.512392,49.9058702],[18.362775,49.9540261],[18.3278644,49.9219275],[18.2630304,49.9732751],[18.1184007,50.0053395],[18.0635412,50.075806],[17.9139242,49.9796897],[17.779269,50.0309757],[17.714435,50.1237921],[17.6047159,50.1653411],[17.7593201,50.21962],[17.7343839,50.3439092],[17.6396265,50.2802117],[17.3802905,50.2802117],[17.3503671,50.3439092],[17.2805459,50.3375433],[17.1857885,50.4075214],[16.9015163,50.4615247],[16.8666057,50.4138779],[16.9663503,50.3184404],[17.0361715,50.2323826],[16.8366823,50.21962],[16.7120015,50.1046034],[16.5823335,50.1589513],[16.5623846,50.2387626],[16.4327166,50.3375433],[16.3529209,50.3916263],[16.2781124,50.3916263],[16.2082911,50.4456477],[16.3978059,50.5344899],[16.4476782,50.5978464],[16.3529209,50.670601],[16.2382145,50.6769221],[16.2182656,50.6326561],[16.1284954,50.6832425],[16.0486997,50.6073425],[15.988853,50.7021983],[15.8741467,50.6832425],[15.8292616,50.7653291],[15.729517,50.743243],[15.450232,50.8157725],[15.3903852,50.7747914],[15.3804108,50.8598659],[15.2956278,50.8850434],[15.2956278,50.9887568],[15.1709471,51.0201394],[14.9914067,51.0013124],[15.0063684,50.8881896],[14.8417898,50.8756034],[14.7969047,50.8252246],[14.6323261,50.8567177],[14.6622495,50.9353576],[14.5724793,50.9227841],[14.6123772,50.9856174],[14.4976708,51.0483657],[14.4178751,51.0232765],[14.3081561,51.0671736],[14.2532965,51.0044508],[14.4029134,50.9322145],[14.3729901,50.897627],[14.2433221,50.9070625],[14.2084114,50.844123],[14.0338583,50.8126214],[13.9789988,50.8252246],[13.9041903,50.7968626],[13.8742669,50.740087],[13.5351352,50.7243038],[13.530148,50.6579561],[13.4703012,50.6136722],[13.3905055,50.664279],[13.3256715,50.5883483],[13.250863,50.6105074],[13.1960035,50.5059517],[13.0513738,50.5218084],[12.9665909,50.4106997],[12.8269484,50.4710483],[12.7022676,50.4138779],[12.5077656,50.401164],[12.343187,50.2547088],[12.323238,50.1845054],[12.2484296,50.2738373],[12.1736211,50.3311765],[12.0988126,50.33436],[12.1187616,50.25152],[12.2234934,50.1653411],[12.2035445,50.1237921],[12.5027784,49.9732751],[12.4778422,49.9379795],[12.5476634,49.9155052],[12.4678677,49.8029766],[12.408021,49.7611134],[12.4828294,49.6869593],[12.5327017,49.6869593],[12.5177401,49.6288466],[12.6075102,49.5415474],[12.6723442,49.4378793],[12.8119867,49.3469896],[12.9466419,49.3437405],[13.2309141,49.1288206],[13.3256715,49.1059712],[13.4353906,49.0438984],[13.4154417,48.9948387],[13.5002246,48.949006],[13.5650586,48.9882938],[13.6847522,48.8834577],[13.7445989,48.9031312],[13.8243946,48.7751149],[13.8992031,48.7751149],[14.0587945,48.676418],[14.0438328,48.6302932],[14.1435774,48.5907241],[14.3729901,48.5610269],[14.4827091,48.6500662],[14.5774665,48.607215],[14.6273389,48.6335892],[14.7071346,48.5808269],[14.7470324,48.7027561],[14.8118664,48.7389485],[14.8168536,48.794831],[14.9864195,48.7652539]]],"terms_url":"http://poloha.net/"},{"id":"Duna_2013","name":"Danube flood ortophoto 2013","type":"tms","template":"http://e.tile.openstreetmap.hu/dunai-arviz-2013/{zoom}/{x}/{y}.jpg","scaleExtent":[10,20],"polygon":[[[19.0773152,47.6959718],[19.0779881,47.6959835],[19.0946205,47.6944562],[19.0805603,47.595874],[19.0743376,47.5890907],[19.0795196,47.5888284],[19.07717,47.5724109],[19.0577884,47.5720924],[19.0773152,47.6959718]]],"terms_url":"http://fototerkep.hu/","terms_text":"Fotótérkép.hu"},{"id":"Delaware2012Orthophotography","name":"Delaware 2012 Orthophotography","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/0/https://firstmap.delaware.gov/arcgis/services/DE_Imagery/DE_Imagery_2012/ImageServer/WMSServer","description":"This data set consists of 0.3-meter pixel resolution (approximately 1-foot), 4-band true color and near infrared (R, G, B, IR) orthoimages covering New Castle, Kent and Sussex Counties in Delaware.","polygon":[[[-75.01770587603,38.45188674427],[-75.74173524589,38.4499581145],[-75.80699639658,39.73907123636],[-75.75558784863,39.80106251053],[-75.64692187603,39.8563815616],[-75.47114773904,39.84645578141],[-75.37725787603,39.81477822231],[-75.48746302671,39.6718115509],[-75.50901151986,39.43446011595],[-75.39326532808,39.27784018498],[-75.30707135548,39.01666513594],[-75.1931721774,38.82218696272],[-75.05341480753,38.80875503297],[-75.01770587603,38.45188674427]]],"terms_url":"https://firstmap.delaware.gov/arcgis/rest/services/DE_Imagery/DE_Imagery_2012/ImageServer","terms_text":"Digital Aerial Solutions, LLC"},{"id":"maaamet.ee-orto","name":"Estonia Ortho (Maaamet)","type":"tms","template":"http://kaart.maakaart.ee/orto/{zoom}/{x}/{y}.jpeg","scaleExtent":[14,20],"polygon":[[[21.6940073,57.5025466],[21.6940073,59.8274564],[28.2110546,59.8274564],[28.2110546,57.5025466],[21.6940073,57.5025466]]],"terms_text":"Maa-Ameti ortofoto "},{"id":"FOMI_2000","name":"FÖMI ortofotó 2000","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2000/{zoom}/{x}/{y}.jpg","description":"Hungary","scaleExtent":[0,17],"polygon":[[[16.1139147,46.8691038],[16.1789749,46.90662],[16.2000429,46.9415079],[16.2217547,46.9355441],[16.2462784,46.9463851],[16.2553226,46.9642125],[16.2764694,46.9626082],[16.290583,47.0139849],[16.3016199,46.9992329],[16.3414618,46.9965225],[16.3505162,47.0106313],[16.3734016,46.9985929],[16.412765,47.00475],[16.4332705,46.9927417],[16.4478119,47.003893],[16.479997,46.9941169],[16.5121988,47.0011695],[16.4635584,47.0322699],[16.4478586,47.0227481],[16.439123,47.029663],[16.445673,47.038872],[16.520323,47.056103],[16.473213,47.0736169],[16.4637199,47.09392],[16.500798,47.110058],[16.500035,47.123295],[16.5295349,47.1287419],[16.5171609,47.1496938],[16.454951,47.1425878],[16.4648728,47.1683349],[16.4555643,47.1875584],[16.4305559,47.1847022],[16.4195013,47.1949147],[16.4189215,47.2107114],[16.4371293,47.2097043],[16.4426335,47.2337117],[16.4313127,47.2527554],[16.4671512,47.2531652],[16.4892319,47.2798885],[16.4646338,47.3338455],[16.4337002,47.3528101],[16.458513,47.3670496],[16.4454619,47.4070195],[16.4831657,47.4093628],[16.4963821,47.3892659],[16.5170941,47.4100218],[16.5749054,47.4054243],[16.5807291,47.4191699],[16.661847,47.455595],[16.6706419,47.47422],[16.6523395,47.500342],[16.6895619,47.510161],[16.7147797,47.540199],[16.663545,47.567733],[16.673199,47.6049544],[16.6595343,47.6061018],[16.652758,47.622852],[16.6314207,47.6283176],[16.5739108,47.619667],[16.5147382,47.6461964],[16.4967504,47.6393149],[16.425464,47.6621679],[16.4437449,47.674205],[16.4480507,47.6964725],[16.4746984,47.6811576],[16.4872245,47.6979767],[16.5521729,47.7225519],[16.5363779,47.736785],[16.5479799,47.751544],[16.6095193,47.7603722],[16.6344148,47.7590843],[16.65729,47.7414879],[16.7209405,47.7353565],[16.7534062,47.6828165],[16.8301587,47.681058],[16.8394284,47.7045139],[16.8668943,47.7211462],[16.876679,47.6876452],[17.0937421,47.7077706],[17.0706562,47.7285366],[17.0516019,47.7938499],[17.0749479,47.8084997],[17.047139,47.8285635],[17.0519452,47.8377691],[17.0105513,47.8581765],[17.0163878,47.8673325],[17.0857537,47.8746239],[17.113171,47.9271605],[17.0917133,47.9342916],[17.1183782,47.9601083],[17.094657,47.9708775],[17.2010289,48.019992],[17.241769,48.0224651],[17.257955,47.998655],[17.334651,47.993125],[17.4029929,47.947849],[17.4539199,47.8852579],[17.5267369,47.865509],[17.5675779,47.8151289],[17.608402,47.8218859],[17.7085789,47.756678],[17.7798739,47.739487],[17.8660959,47.74575],[17.9001292,47.7392633],[17.946867,47.744668],[17.9708709,47.7578392],[18.0044103,47.7463402],[18.0380583,47.7576812],[18.2958774,47.7314616],[18.4540681,47.7651226],[18.4931553,47.7527552],[18.5590761,47.7659963],[18.6460866,47.7590921],[18.7260691,47.7890411],[18.7411784,47.8138245],[18.7920013,47.8230869],[18.8485417,47.8167221],[18.855876,47.826077],[18.828014,47.834291],[18.8135749,47.85555],[18.76353,47.8716049],[18.756858,47.896838],[18.776746,47.955092],[18.7552499,47.9763469],[18.8157429,47.993442],[18.819998,48.039676],[18.833268,48.048239],[18.8749364,48.0470707],[18.886674,48.058682],[18.9089819,48.051139],[18.9439039,48.058865],[18.9816099,48.0536009],[19.0148639,48.078179],[19.0585249,48.0573529],[19.0843619,48.072781],[19.107402,48.065596],[19.1352889,48.074146],[19.2413679,48.0536529],[19.2557819,48.0715559],[19.3031119,48.088711],[19.3865969,48.091914],[19.400018,48.082304],[19.454053,48.101436],[19.467354,48.083933],[19.4944199,48.109906],[19.492377,48.1396639],[19.5128219,48.154663],[19.504518,48.173443],[19.528967,48.190358],[19.526044,48.20313],[19.577502,48.2160149],[19.6308263,48.2500725],[19.6445239,48.2391719],[19.669857,48.239212],[19.691219,48.203894],[19.721125,48.201473],[19.74618,48.2165119],[19.7871629,48.19253],[19.7987329,48.19482],[19.8052829,48.183733],[19.782415,48.165039],[19.794812,48.153529],[19.821331,48.169081],[19.8452819,48.162742],[19.8551729,48.178431],[19.8601309,48.169409],[19.898745,48.1663119],[19.9145359,48.146863],[19.898298,48.1249019],[19.937383,48.131118],[19.9743939,48.1660049],[19.988706,48.1621679],[20.029038,48.1776849],[20.049449,48.1671999],[20.0729859,48.179606],[20.0700369,48.1917019],[20.1340909,48.225182],[20.1331879,48.253982],[20.206162,48.250979],[20.2038299,48.261906],[20.228466,48.262779],[20.2349469,48.279933],[20.286858,48.26164],[20.3257109,48.272794],[20.3374649,48.301667],[20.3656579,48.316606],[20.384077,48.3511809],[20.4098349,48.365857],[20.402532,48.382565],[20.4205349,48.403858],[20.416228,48.418536],[20.507929,48.489363],[20.5065069,48.534415],[20.537471,48.527878],[20.5464939,48.544292],[20.586595,48.535759],[20.6538739,48.561413],[20.836359,48.58284],[20.8378,48.57421],[20.8504359,48.5816329],[20.8453301,48.5665046],[20.8681549,48.551818],[20.922323,48.559453],[20.9346349,48.538341],[20.955882,48.533963],[20.9561979,48.521666],[20.9815849,48.5177669],[21.0151139,48.532313],[21.0663209,48.525894],[21.1174479,48.4910549],[21.1608749,48.521499],[21.179634,48.518232],[21.221061,48.537497],[21.305488,48.5222489],[21.313377,48.550841],[21.326875,48.554129],[21.319384,48.561201],[21.4154499,48.558951],[21.4226649,48.578821],[21.4406099,48.585104],[21.514091,48.551065],[21.5420199,48.508395],[21.6139329,48.509416],[21.6201879,48.469826],[21.663549,48.417961],[21.6645609,48.392164],[21.7017409,48.380695],[21.711871,48.357617],[21.8174139,48.332787],[21.8352029,48.3346409],[21.837213,48.363253],[21.8842979,48.356047],[21.8848429,48.367539],[21.897883,48.36256],[21.8997959,48.3702229],[21.9281859,48.3615969],[21.9268059,48.370899],[21.949198,48.378728],[21.994463,48.377323],[22.0213259,48.392749],[22.0546049,48.377528],[22.0764859,48.387241],[22.086743,48.371564],[22.1359089,48.380519],[22.131056,48.3912329],[22.152768,48.3962409],[22.1561913,48.4093076],[22.2125722,48.4256468],[22.2371405,48.4100396],[22.2654858,48.4098675],[22.2398761,48.3870055],[22.2675722,48.3611612],[22.3178106,48.3545437],[22.3132861,48.3250712],[22.3372944,48.3079113],[22.3384267,48.2792074],[22.3847547,48.2339632],[22.4006407,48.249198],[22.4328384,48.2525166],[22.456386,48.2423109],[22.4899029,48.2534237],[22.4972201,48.2395546],[22.5161491,48.237965],[22.5311088,48.2094282],[22.5711442,48.1961428],[22.5616362,48.1816066],[22.5982449,48.144756],[22.5902763,48.1073414],[22.6754492,48.091997],[22.7347192,48.119848],[22.7576242,48.1200599],[22.7703914,48.1090162],[22.772319,48.1218742],[22.8027688,48.1221112],[22.8025285,48.1070813],[22.8254256,48.1175119],[22.8364365,48.080249],[22.8611284,48.0750312],[22.8677955,48.0524256],[22.8820424,48.0548053],[22.8659692,48.0113165],[22.835562,47.9905988],[22.8407599,47.9813636],[22.8725729,47.9752683],[22.8697274,47.9659593],[22.8915652,47.9672446],[22.897435,47.9540629],[22.8473299,47.9077579],[22.7928135,47.8908586],[22.7586924,47.8941446],[22.77775,47.8422508],[22.7136344,47.8360928],[22.6801938,47.7877527],[22.6111171,47.7717455],[22.5490018,47.7722246],[22.4812121,47.8108886],[22.4513078,47.803389],[22.4313319,47.7398119],[22.3566167,47.7486206],[22.3177714,47.7660887],[22.3176236,47.7433657],[22.2851369,47.7292757],[22.264325,47.7310675],[22.2589955,47.6979057],[22.2306796,47.693196],[22.1796501,47.5916115],[22.1289245,47.5978984],[22.0942787,47.5583628],[22.0782587,47.5621299],[22.0534529,47.5474795],[22.0712176,47.5380742],[22.0617872,47.5288029],[22.0451278,47.5398919],[22.0367222,47.5326653],[22.0071886,47.48362],[22.0327909,47.4508372],[22.0238835,47.3908631],[22.0119849,47.3758016],[21.9627373,47.381053],[21.9382461,47.3725317],[21.8777922,47.2857763],[21.8872845,47.2730473],[21.8534909,47.2397622],[21.8580662,47.1873597],[21.8124804,47.1667511],[21.7924092,47.1059751],[21.7268258,47.0983882],[21.6976037,47.057915],[21.6504151,47.0408303],[21.6888701,47.0019977],[21.6678744,46.9712337],[21.6814917,46.9652089],[21.6381964,46.9330487],[21.5984455,46.9274708],[21.6142857,46.8867275],[21.6016694,46.8668202],[21.520328,46.8373749],[21.5186086,46.8000703],[21.4831761,46.7650246],[21.5263389,46.7393249],[21.529369,46.7209721],[21.4923253,46.6859652],[21.4728438,46.6959075],[21.4299047,46.693937],[21.4309553,46.6781367],[21.4546661,46.660863],[21.4162375,46.6426231],[21.4097959,46.6218052],[21.3657038,46.6379501],[21.3300499,46.6318155],[21.3139733,46.617666],[21.3012351,46.5908672],[21.3207905,46.5828562],[21.2743045,46.5407362],[21.2600254,46.5021583],[21.2744188,46.4767333],[21.2964506,46.4762973],[21.3174343,46.4507288],[21.2895176,46.4154784],[21.2963256,46.4069601],[21.2250116,46.4136899],[21.2064214,46.4033825],[21.1992563,46.3479034],[21.1762269,46.3357664],[21.180497,46.3044494],[21.1155437,46.3018529],[21.1030549,46.2624637],[21.0708792,46.2539014],[21.0660827,46.2429394],[21.0366237,46.2480392],[21.0246723,46.2665329],[20.960817,46.2623039],[20.9465849,46.2793024],[20.9250701,46.2766191],[20.9218133,46.2618129],[20.8732713,46.2877555],[20.7756538,46.2759602],[20.7490474,46.2508489],[20.7618619,46.204563],[20.727401,46.2077485],[20.7341052,46.1939355],[20.7140487,46.1660531],[20.6843592,46.1447802],[20.6549178,46.1497739],[20.6394471,46.1267602],[20.5450486,46.1790935],[20.5014839,46.190334],[20.4949436,46.1709908],[20.4592293,46.1428837],[20.3975133,46.1574709],[20.3685325,46.1528554],[20.3557074,46.1696256],[20.2968136,46.1521542],[20.2549024,46.1158522],[20.2484757,46.1300956],[20.2330132,46.1241668],[20.1817362,46.1601137],[20.1364966,46.1449476],[20.1009667,46.1772756],[20.0636156,46.1437275],[20.0346142,46.1458888],[20.0158072,46.1768354],[19.9354075,46.1764243],[19.8533469,46.1500005],[19.8179747,46.1281652],[19.7585403,46.1479754],[19.6982054,46.1879317],[19.6827672,46.1800388],[19.661508,46.1904394],[19.6317396,46.1692993],[19.5676482,46.179106],[19.5604013,46.1665762],[19.5026585,46.1424492],[19.5271208,46.1210269],[19.4645033,46.0953827],[19.4665828,46.0820437],[19.4160037,46.0460453],[19.3803957,46.0358749],[19.3640923,46.0522965],[19.2819012,46.0148048],[19.2965348,45.9881173],[19.2856472,45.9968981],[19.1479857,45.9963445],[19.1338422,46.0370993],[19.104873,46.0401673],[19.0660427,46.0001999],[19.0796791,45.9636376],[19.0059803,45.9590674],[19.0092745,45.9236559],[18.9061334,45.9353801],[18.8794572,45.9166827],[18.8647137,45.9208493],[18.8685629,45.9113361],[18.8276792,45.9051714],[18.8220041,45.9145893],[18.8075092,45.9036055],[18.809247,45.8796189],[18.7956242,45.8784488],[18.7048857,45.9181883],[18.6700246,45.9108439],[18.6596602,45.9168934],[18.6651348,45.899279],[18.6412808,45.8890396],[18.6550179,45.8742393],[18.6277704,45.8733782],[18.6148449,45.8531438],[18.6236656,45.8398531],[18.5732391,45.8137578],[18.5749849,45.8004344],[18.559716,45.8037961],[18.5223504,45.7826858],[18.4906706,45.7947167],[18.4821905,45.7655032],[18.4562828,45.7695229],[18.4450763,45.7605195],[18.446853,45.737128],[18.40763,45.7397119],[18.3918949,45.7616983],[18.3642257,45.7729364],[18.3394214,45.7471605],[18.2968157,45.7612196],[18.2440473,45.7612305],[18.2307311,45.7790328],[18.1908702,45.7878759],[18.1681939,45.7762712],[18.1246514,45.7896277],[18.1068067,45.7708256],[18.0818922,45.7645205],[17.9958808,45.7957311],[17.9302095,45.7863301],[17.9066757,45.7925692],[17.8653145,45.7670064],[17.8262748,45.8099957],[17.8089784,45.8040989],[17.7809054,45.8174884],[17.7603399,45.811923],[17.7408624,45.8295975],[17.6632915,45.8381849],[17.6276211,45.8979446],[17.5700676,45.9358204],[17.4378254,45.9503823],[17.4258964,45.9272681],[17.4108059,45.9399665],[17.392149,45.9302149],[17.3828713,45.9475733],[17.3476208,45.9423413],[17.3438769,45.9605329],[17.3537711,45.9525011],[17.3905375,45.9581914],[17.387423,45.9661823],[17.3583539,45.9642737],[17.3754852,45.9686921],[17.3751895,45.9881054],[17.3635685,45.9915442],[17.3567202,45.9735836],[17.3339583,45.9960781],[17.3319847,45.9728948],[17.3129974,45.9665347],[17.323647,45.9887776],[17.2987653,45.9838652],[17.3041996,46.0021128],[17.2579726,46.0110256],[17.29632,46.0285169],[17.2541514,46.030005],[17.270955,46.0567055],[17.2324767,46.0592034],[17.2525145,46.0664725],[17.2313144,46.0790345],[17.2019916,46.0765488],[17.2331299,46.0989644],[17.2104017,46.1001693],[17.2129734,46.113855],[17.175927,46.1084583],[17.1743424,46.1287608],[17.1865197,46.1332308],[17.1810983,46.1505485],[17.1562307,46.1585819],[17.1592857,46.1696818],[17.1261012,46.1684495],[17.1227409,46.1789791],[17.0752482,46.1889531],[17.0661614,46.2022984],[16.9735401,46.2251982],[16.973954,46.2431113],[16.9504085,46.2415285],[16.8862356,46.2814598],[16.8713682,46.3252767],[16.8802109,46.3356966],[16.8615374,46.3452401],[16.8656232,46.3556489],[16.8521959,46.3517189],[16.8498589,46.3626245],[16.8352859,46.3638195],[16.8376499,46.3748032],[16.8261732,46.3670994],[16.7933444,46.387385],[16.7592072,46.3776563],[16.7298672,46.40149],[16.7182119,46.3898704],[16.6772872,46.4494536],[16.6631785,46.4486958],[16.6663732,46.4582995],[16.6187915,46.4619875],[16.604468,46.4760773],[16.5235997,46.5053761],[16.5325768,46.5314027],[16.5176728,46.5363516],[16.5084107,46.5652692],[16.4829969,46.5660383],[16.4834008,46.5786011],[16.4455713,46.610952],[16.4248583,46.6131645],[16.385941,46.6442485],[16.3915424,46.6637257],[16.4198454,46.6584771],[16.4286335,46.6939737],[16.3689211,46.7040082],[16.3798266,46.7153869],[16.3710856,46.7222945],[16.3570587,46.7142387],[16.3185954,46.7541449],[16.3305417,46.7752119],[16.3121626,46.7780033],[16.3127666,46.797314],[16.3406373,46.8051851],[16.3508404,46.8300552],[16.3403309,46.8468762],[16.3015007,46.8595142],[16.2913867,46.8728341],[16.2332296,46.8766702],[16.1560866,46.8537074],[16.126571,46.8569079],[16.1139147,46.8691038]]],"terms_url":"http://www.fomi.hu/","terms_text":"Földmérési és Távérzékelési Intézet"},{"id":"FOMI_2005","name":"FÖMI ortofotó 2005","type":"tms","template":"http://e.tile.openstreetmap.hu/ortofoto2005/{zoom}/{x}/{y}.jpg","description":"Hungary","scaleExtent":[0,17],"polygon":[[[16.1139147,46.8691038],[16.1789749,46.90662],[16.2000429,46.9415079],[16.2217547,46.9355441],[16.2462784,46.9463851],[16.2553226,46.9642125],[16.2764694,46.9626082],[16.290583,47.0139849],[16.3016199,46.9992329],[16.3414618,46.9965225],[16.3505162,47.0106313],[16.3734016,46.9985929],[16.412765,47.00475],[16.4332705,46.9927417],[16.4478119,47.003893],[16.479997,46.9941169],[16.5121988,47.0011695],[16.4635584,47.0322699],[16.4478586,47.0227481],[16.439123,47.029663],[16.445673,47.038872],[16.520323,47.056103],[16.473213,47.0736169],[16.4637199,47.09392],[16.500798,47.110058],[16.500035,47.123295],[16.5295349,47.1287419],[16.5171609,47.1496938],[16.454951,47.1425878],[16.4648728,47.1683349],[16.4555643,47.1875584],[16.4305559,47.1847022],[16.4195013,47.1949147],[16.4189215,47.2107114],[16.4371293,47.2097043],[16.4426335,47.2337117],[16.4313127,47.2527554],[16.4671512,47.2531652],[16.4892319,47.2798885],[16.4646338,47.3338455],[16.4337002,47.3528101],[16.458513,47.3670496],[16.4454619,47.4070195],[16.4831657,47.4093628],[16.4963821,47.3892659],[16.5170941,47.4100218],[16.5749054,47.4054243],[16.5807291,47.4191699],[16.661847,47.455595],[16.6706419,47.47422],[16.6523395,47.500342],[16.6895619,47.510161],[16.7147797,47.540199],[16.663545,47.567733],[16.673199,47.6049544],[16.6595343,47.6061018],[16.652758,47.622852],[16.6314207,47.6283176],[16.5739108,47.619667],[16.5147382,47.6461964],[16.4967504,47.6393149],[16.425464,47.6621679],[16.4437449,47.674205],[16.4480507,47.6964725],[16.4746984,47.6811576],[16.4872245,47.6979767],[16.5521729,47.7225519],[16.5363779,47.736785],[16.5479799,47.751544],[16.6095193,47.7603722],[16.6344148,47.7590843],[16.65729,47.7414879],[16.7209405,47.7353565],[16.7534062,47.6828165],[16.8301587,47.681058],[16.8394284,47.7045139],[16.8668943,47.7211462],[16.876679,47.6876452],[17.0937421,47.7077706],[17.0706562,47.7285366],[17.0516019,47.7938499],[17.0749479,47.8084997],[17.047139,47.8285635],[17.0519452,47.8377691],[17.0105513,47.8581765],[17.0163878,47.8673325],[17.0857537,47.8746239],[17.113171,47.9271605],[17.0917133,47.9342916],[17.1183782,47.9601083],[17.094657,47.9708775],[17.2010289,48.019992],[17.241769,48.0224651],[17.257955,47.998655],[17.334651,47.993125],[17.4029929,47.947849],[17.4539199,47.8852579],[17.5267369,47.865509],[17.5675779,47.8151289],[17.608402,47.8218859],[17.7085789,47.756678],[17.7798739,47.739487],[17.8660959,47.74575],[17.9001292,47.7392633],[17.946867,47.744668],[17.9708709,47.7578392],[18.0044103,47.7463402],[18.0380583,47.7576812],[18.2958774,47.7314616],[18.4540681,47.7651226],[18.4931553,47.7527552],[18.5590761,47.7659963],[18.6460866,47.7590921],[18.7260691,47.7890411],[18.7411784,47.8138245],[18.7920013,47.8230869],[18.8485417,47.8167221],[18.855876,47.826077],[18.828014,47.834291],[18.8135749,47.85555],[18.76353,47.8716049],[18.756858,47.896838],[18.776746,47.955092],[18.7552499,47.9763469],[18.8157429,47.993442],[18.819998,48.039676],[18.833268,48.048239],[18.8749364,48.0470707],[18.886674,48.058682],[18.9089819,48.051139],[18.9439039,48.058865],[18.9816099,48.0536009],[19.0148639,48.078179],[19.0585249,48.0573529],[19.0843619,48.072781],[19.107402,48.065596],[19.1352889,48.074146],[19.2413679,48.0536529],[19.2557819,48.0715559],[19.3031119,48.088711],[19.3865969,48.091914],[19.400018,48.082304],[19.454053,48.101436],[19.467354,48.083933],[19.4944199,48.109906],[19.492377,48.1396639],[19.5128219,48.154663],[19.504518,48.173443],[19.528967,48.190358],[19.526044,48.20313],[19.577502,48.2160149],[19.6308263,48.2500725],[19.6445239,48.2391719],[19.669857,48.239212],[19.691219,48.203894],[19.721125,48.201473],[19.74618,48.2165119],[19.7871629,48.19253],[19.7987329,48.19482],[19.8052829,48.183733],[19.782415,48.165039],[19.794812,48.153529],[19.821331,48.169081],[19.8452819,48.162742],[19.8551729,48.178431],[19.8601309,48.169409],[19.898745,48.1663119],[19.9145359,48.146863],[19.898298,48.1249019],[19.937383,48.131118],[19.9743939,48.1660049],[19.988706,48.1621679],[20.029038,48.1776849],[20.049449,48.1671999],[20.0729859,48.179606],[20.0700369,48.1917019],[20.1340909,48.225182],[20.1331879,48.253982],[20.206162,48.250979],[20.2038299,48.261906],[20.228466,48.262779],[20.2349469,48.279933],[20.286858,48.26164],[20.3257109,48.272794],[20.3374649,48.301667],[20.3656579,48.316606],[20.384077,48.3511809],[20.4098349,48.365857],[20.402532,48.382565],[20.4205349,48.403858],[20.416228,48.418536],[20.507929,48.489363],[20.5065069,48.534415],[20.537471,48.527878],[20.5464939,48.544292],[20.586595,48.535759],[20.6538739,48.561413],[20.836359,48.58284],[20.8378,48.57421],[20.8504359,48.5816329],[20.8453301,48.5665046],[20.8681549,48.551818],[20.922323,48.559453],[20.9346349,48.538341],[20.955882,48.533963],[20.9561979,48.521666],[20.9815849,48.5177669],[21.0151139,48.532313],[21.0663209,48.525894],[21.1174479,48.4910549],[21.1608749,48.521499],[21.179634,48.518232],[21.221061,48.537497],[21.305488,48.5222489],[21.313377,48.550841],[21.326875,48.554129],[21.319384,48.561201],[21.4154499,48.558951],[21.4226649,48.578821],[21.4406099,48.585104],[21.514091,48.551065],[21.5420199,48.508395],[21.6139329,48.509416],[21.6201879,48.469826],[21.663549,48.417961],[21.6645609,48.392164],[21.7017409,48.380695],[21.711871,48.357617],[21.8174139,48.332787],[21.8352029,48.3346409],[21.837213,48.363253],[21.8842979,48.356047],[21.8848429,48.367539],[21.897883,48.36256],[21.8997959,48.3702229],[21.9281859,48.3615969],[21.9268059,48.370899],[21.949198,48.378728],[21.994463,48.377323],[22.0213259,48.392749],[22.0546049,48.377528],[22.0764859,48.387241],[22.086743,48.371564],[22.1359089,48.380519],[22.131056,48.3912329],[22.152768,48.3962409],[22.1561913,48.4093076],[22.2125722,48.4256468],[22.2371405,48.4100396],[22.2654858,48.4098675],[22.2398761,48.3870055],[22.2675722,48.3611612],[22.3178106,48.3545437],[22.3132861,48.3250712],[22.3372944,48.3079113],[22.3384267,48.2792074],[22.3847547,48.2339632],[22.4006407,48.249198],[22.4328384,48.2525166],[22.456386,48.2423109],[22.4899029,48.2534237],[22.4972201,48.2395546],[22.5161491,48.237965],[22.5311088,48.2094282],[22.5711442,48.1961428],[22.5616362,48.1816066],[22.5982449,48.144756],[22.5902763,48.1073414],[22.6754492,48.091997],[22.7347192,48.119848],[22.7576242,48.1200599],[22.7703914,48.1090162],[22.772319,48.1218742],[22.8027688,48.1221112],[22.8025285,48.1070813],[22.8254256,48.1175119],[22.8364365,48.080249],[22.8611284,48.0750312],[22.8677955,48.0524256],[22.8820424,48.0548053],[22.8659692,48.0113165],[22.835562,47.9905988],[22.8407599,47.9813636],[22.8725729,47.9752683],[22.8697274,47.9659593],[22.8915652,47.9672446],[22.897435,47.9540629],[22.8473299,47.9077579],[22.7928135,47.8908586],[22.7586924,47.8941446],[22.77775,47.8422508],[22.7136344,47.8360928],[22.6801938,47.7877527],[22.6111171,47.7717455],[22.5490018,47.7722246],[22.4812121,47.8108886],[22.4513078,47.803389],[22.4313319,47.7398119],[22.3566167,47.7486206],[22.3177714,47.7660887],[22.3176236,47.7433657],[22.2851369,47.7292757],[22.264325,47.7310675],[22.2589955,47.6979057],[22.2306796,47.693196],[22.1796501,47.5916115],[22.1289245,47.5978984],[22.0942787,47.5583628],[22.0782587,47.5621299],[22.0534529,47.5474795],[22.0712176,47.5380742],[22.0617872,47.5288029],[22.0451278,47.5398919],[22.0367222,47.5326653],[22.0071886,47.48362],[22.0327909,47.4508372],[22.0238835,47.3908631],[22.0119849,47.3758016],[21.9627373,47.381053],[21.9382461,47.3725317],[21.8777922,47.2857763],[21.8872845,47.2730473],[21.8534909,47.2397622],[21.8580662,47.1873597],[21.8124804,47.1667511],[21.7924092,47.1059751],[21.7268258,47.0983882],[21.6976037,47.057915],[21.6504151,47.0408303],[21.6888701,47.0019977],[21.6678744,46.9712337],[21.6814917,46.9652089],[21.6381964,46.9330487],[21.5984455,46.9274708],[21.6142857,46.8867275],[21.6016694,46.8668202],[21.520328,46.8373749],[21.5186086,46.8000703],[21.4831761,46.7650246],[21.5263389,46.7393249],[21.529369,46.7209721],[21.4923253,46.6859652],[21.4728438,46.6959075],[21.4299047,46.693937],[21.4309553,46.6781367],[21.4546661,46.660863],[21.4162375,46.6426231],[21.4097959,46.6218052],[21.3657038,46.6379501],[21.3300499,46.6318155],[21.3139733,46.617666],[21.3012351,46.5908672],[21.3207905,46.5828562],[21.2743045,46.5407362],[21.2600254,46.5021583],[21.2744188,46.4767333],[21.2964506,46.4762973],[21.3174343,46.4507288],[21.2895176,46.4154784],[21.2963256,46.4069601],[21.2250116,46.4136899],[21.2064214,46.4033825],[21.1992563,46.3479034],[21.1762269,46.3357664],[21.180497,46.3044494],[21.1155437,46.3018529],[21.1030549,46.2624637],[21.0708792,46.2539014],[21.0660827,46.2429394],[21.0366237,46.2480392],[21.0246723,46.2665329],[20.960817,46.2623039],[20.9465849,46.2793024],[20.9250701,46.2766191],[20.9218133,46.2618129],[20.8732713,46.2877555],[20.7756538,46.2759602],[20.7490474,46.2508489],[20.7618619,46.204563],[20.727401,46.2077485],[20.7341052,46.1939355],[20.7140487,46.1660531],[20.6843592,46.1447802],[20.6549178,46.1497739],[20.6394471,46.1267602],[20.5450486,46.1790935],[20.5014839,46.190334],[20.4949436,46.1709908],[20.4592293,46.1428837],[20.3975133,46.1574709],[20.3685325,46.1528554],[20.3557074,46.1696256],[20.2968136,46.1521542],[20.2549024,46.1158522],[20.2484757,46.1300956],[20.2330132,46.1241668],[20.1817362,46.1601137],[20.1364966,46.1449476],[20.1009667,46.1772756],[20.0636156,46.1437275],[20.0346142,46.1458888],[20.0158072,46.1768354],[19.9354075,46.1764243],[19.8533469,46.1500005],[19.8179747,46.1281652],[19.7585403,46.1479754],[19.6982054,46.1879317],[19.6827672,46.1800388],[19.661508,46.1904394],[19.6317396,46.1692993],[19.5676482,46.179106],[19.5604013,46.1665762],[19.5026585,46.1424492],[19.5271208,46.1210269],[19.4645033,46.0953827],[19.4665828,46.0820437],[19.4160037,46.0460453],[19.3803957,46.0358749],[19.3640923,46.0522965],[19.2819012,46.0148048],[19.2965348,45.9881173],[19.2856472,45.9968981],[19.1479857,45.9963445],[19.1338422,46.0370993],[19.104873,46.0401673],[19.0660427,46.0001999],[19.0796791,45.9636376],[19.0059803,45.9590674],[19.0092745,45.9236559],[18.9061334,45.9353801],[18.8794572,45.9166827],[18.8647137,45.9208493],[18.8685629,45.9113361],[18.8276792,45.9051714],[18.8220041,45.9145893],[18.8075092,45.9036055],[18.809247,45.8796189],[18.7956242,45.8784488],[18.7048857,45.9181883],[18.6700246,45.9108439],[18.6596602,45.9168934],[18.6651348,45.899279],[18.6412808,45.8890396],[18.6550179,45.8742393],[18.6277704,45.8733782],[18.6148449,45.8531438],[18.6236656,45.8398531],[18.5732391,45.8137578],[18.5749849,45.8004344],[18.559716,45.8037961],[18.5223504,45.7826858],[18.4906706,45.7947167],[18.4821905,45.7655032],[18.4562828,45.7695229],[18.4450763,45.7605195],[18.446853,45.737128],[18.40763,45.7397119],[18.3918949,45.7616983],[18.3642257,45.7729364],[18.3394214,45.7471605],[18.2968157,45.7612196],[18.2440473,45.7612305],[18.2307311,45.7790328],[18.1908702,45.7878759],[18.1681939,45.7762712],[18.1246514,45.7896277],[18.1068067,45.7708256],[18.0818922,45.7645205],[17.9958808,45.7957311],[17.9302095,45.7863301],[17.9066757,45.7925692],[17.8653145,45.7670064],[17.8262748,45.8099957],[17.8089784,45.8040989],[17.7809054,45.8174884],[17.7603399,45.811923],[17.7408624,45.8295975],[17.6632915,45.8381849],[17.6276211,45.8979446],[17.5700676,45.9358204],[17.4378254,45.9503823],[17.4258964,45.9272681],[17.4108059,45.9399665],[17.392149,45.9302149],[17.3828713,45.9475733],[17.3476208,45.9423413],[17.3438769,45.9605329],[17.3537711,45.9525011],[17.3905375,45.9581914],[17.387423,45.9661823],[17.3583539,45.9642737],[17.3754852,45.9686921],[17.3751895,45.9881054],[17.3635685,45.9915442],[17.3567202,45.9735836],[17.3339583,45.9960781],[17.3319847,45.9728948],[17.3129974,45.9665347],[17.323647,45.9887776],[17.2987653,45.9838652],[17.3041996,46.0021128],[17.2579726,46.0110256],[17.29632,46.0285169],[17.2541514,46.030005],[17.270955,46.0567055],[17.2324767,46.0592034],[17.2525145,46.0664725],[17.2313144,46.0790345],[17.2019916,46.0765488],[17.2331299,46.0989644],[17.2104017,46.1001693],[17.2129734,46.113855],[17.175927,46.1084583],[17.1743424,46.1287608],[17.1865197,46.1332308],[17.1810983,46.1505485],[17.1562307,46.1585819],[17.1592857,46.1696818],[17.1261012,46.1684495],[17.1227409,46.1789791],[17.0752482,46.1889531],[17.0661614,46.2022984],[16.9735401,46.2251982],[16.973954,46.2431113],[16.9504085,46.2415285],[16.8862356,46.2814598],[16.8713682,46.3252767],[16.8802109,46.3356966],[16.8615374,46.3452401],[16.8656232,46.3556489],[16.8521959,46.3517189],[16.8498589,46.3626245],[16.8352859,46.3638195],[16.8376499,46.3748032],[16.8261732,46.3670994],[16.7933444,46.387385],[16.7592072,46.3776563],[16.7298672,46.40149],[16.7182119,46.3898704],[16.6772872,46.4494536],[16.6631785,46.4486958],[16.6663732,46.4582995],[16.6187915,46.4619875],[16.604468,46.4760773],[16.5235997,46.5053761],[16.5325768,46.5314027],[16.5176728,46.5363516],[16.5084107,46.5652692],[16.4829969,46.5660383],[16.4834008,46.5786011],[16.4455713,46.610952],[16.4248583,46.6131645],[16.385941,46.6442485],[16.3915424,46.6637257],[16.4198454,46.6584771],[16.4286335,46.6939737],[16.3689211,46.7040082],[16.3798266,46.7153869],[16.3710856,46.7222945],[16.3570587,46.7142387],[16.3185954,46.7541449],[16.3305417,46.7752119],[16.3121626,46.7780033],[16.3127666,46.797314],[16.3406373,46.8051851],[16.3508404,46.8300552],[16.3403309,46.8468762],[16.3015007,46.8595142],[16.2913867,46.8728341],[16.2332296,46.8766702],[16.1560866,46.8537074],[16.126571,46.8569079],[16.1139147,46.8691038]]],"terms_url":"http://www.fomi.hu/","terms_text":"Földmérési és Távérzékelési Intézet"},{"id":"FR-BAN","name":"FR-BAN","type":"tms","template":"http://{switch:a,b,c}.layers.openstreetmap.fr/bano/{zoom}/{x}/{y}.png","description":"French address registry or Base Adresses Nationale","scaleExtent":[12,20],"polygon":[[[8.3247852,49.0891892],[6.1566882,49.6167369],[4.8666714,50.2126152],[2.4937064,51.1761675],[1.3121526,50.9324682],[1.2659981,50.1877492],[0.1121369,49.8258592],[-0.3494075,49.4312336],[-1.0232625,49.4852345],[-1.3278818,49.7901162],[-2.1032765,49.7901162],[-1.6232703,48.7420657],[-3.1002126,48.9728514],[-5.1125465,48.6811558],[-5.3525496,48.4367783],[-4.5984193,47.7194959],[-2.555398,47.0232784],[-2.4738077,46.6638823],[-1.6676954,46.1055717],[-1.334807,45.5141125],[-1.4914604,44.1627003],[-1.9940567,43.3708146],[-0.956228,42.7364747],[2.2029487,42.2841894],[3.2342502,42.5444129],[3.2407774,43.1140543],[4.0436261,43.3280964],[6.4325902,42.808345],[7.6270723,43.5934102],[7.8163619,44.1720643],[7.0396221,44.41967],[7.268075,45.4958141],[7.1244761,46.2140775],[6.5631347,46.771283],[7.6571492,47.59128],[7.6527839,47.5941813],[7.6224698,47.5776739],[7.6047297,47.578221],[7.5877054,47.5901532],[7.521558,47.65161],[7.503992,47.70235],[7.520958,47.77685],[7.557124,47.84839],[7.549463,47.879205],[7.574615,47.93028],[7.613179,47.96804],[7.611904,47.9871],[7.5612401,48.0383618],[7.574915,48.1258],[7.595338,48.15977],[7.633047,48.19717],[7.662748,48.22473],[7.684659,48.30305],[7.763463,48.49158],[7.8004602,48.5125977],[7.799582,48.5878],[7.834088,48.64439],[7.9121073,48.6889897],[7.9672295,48.7571585],[8.020692,48.78879],[8.043024,48.7956],[8.0864658,48.8130551],[8.1364418,48.8978239],[8.1970586,48.96021],[8.2816129,48.9948995],[8.2996723,49.025966],[8.3124269,49.0599642],[8.3247852,49.0891892]],[[9.3609615,43.1345098],[8.4393174,42.48439],[8.4836272,41.8175373],[8.8469677,41.3768281],[9.2058772,41.3136241],[9.48946,41.5461776],[9.6356823,42.1994563],[9.6046655,42.901254],[9.3609615,43.1345098]]],"terms_url":"https://wiki.openstreetmap.org/wiki/WikiProject_France/WikiProject_Base_Adresses_Nationale_Ouverte_(BANO)","terms_text":"Tiles © cquest@Openstreetmap France, data © OpenStreetMap contributors, ODBL"},{"id":"FR-Cadastre","name":"FR-Cadastre","type":"tms","template":"http://tms.cadastre.openstreetmap.fr/*/tout/{zoom}/{x}/{y}.png","description":"French land registry","scaleExtent":[12,20],"polygon":[[[8.3247852,49.0891892],[6.1566882,49.6167369],[4.8666714,50.2126152],[2.4937064,51.1761675],[1.3121526,50.9324682],[1.2659981,50.1877492],[0.1121369,49.8258592],[-0.3494075,49.4312336],[-1.0232625,49.4852345],[-1.3278818,49.7901162],[-2.1032765,49.7901162],[-1.6232703,48.7420657],[-3.1002126,48.9728514],[-5.1125465,48.6811558],[-5.3525496,48.4367783],[-4.5984193,47.7194959],[-2.555398,47.0232784],[-2.4738077,46.6638823],[-1.6676954,46.1055717],[-1.334807,45.5141125],[-1.4914604,44.1627003],[-1.9940567,43.3708146],[-0.956228,42.7364747],[2.2029487,42.2841894],[3.2342502,42.5444129],[3.2407774,43.1140543],[4.0436261,43.3280964],[6.4325902,42.808345],[7.6270723,43.5934102],[7.8163619,44.1720643],[7.0396221,44.41967],[7.268075,45.4958141],[7.1244761,46.2140775],[6.5631347,46.771283],[7.6571492,47.59128],[7.6527839,47.5941813],[7.6224698,47.5776739],[7.6047297,47.578221],[7.5877054,47.5901532],[7.521558,47.65161],[7.503992,47.70235],[7.520958,47.77685],[7.557124,47.84839],[7.549463,47.879205],[7.574615,47.93028],[7.613179,47.96804],[7.611904,47.9871],[7.5612401,48.0383618],[7.574915,48.1258],[7.595338,48.15977],[7.633047,48.19717],[7.662748,48.22473],[7.684659,48.30305],[7.763463,48.49158],[7.8004602,48.5125977],[7.799582,48.5878],[7.834088,48.64439],[7.9121073,48.6889897],[7.9672295,48.7571585],[8.020692,48.78879],[8.043024,48.7956],[8.0864658,48.8130551],[8.1364418,48.8978239],[8.1970586,48.96021],[8.2816129,48.9948995],[8.2996723,49.025966],[8.3124269,49.0599642],[8.3247852,49.0891892]],[[9.3609615,43.1345098],[8.4393174,42.48439],[8.4836272,41.8175373],[8.8469677,41.3768281],[9.2058772,41.3136241],[9.48946,41.5461776],[9.6356823,42.1994563],[9.6046655,42.901254],[9.3609615,43.1345098]]],"terms_url":"http://wiki.openstreetmap.org/wiki/WikiProject_Cadastre_Fran%C3%A7ais/Conditions_d%27utilisation","terms_text":"cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre. Mise à jour : 2015"},{"id":"Freemap.sk-Car","name":"Freemap.sk Car","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/A/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Freemap.sk-Cyclo","name":"Freemap.sk Cyclo","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/C/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Freemap.sk-Hiking","name":"Freemap.sk Hiking","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/T/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Freemap.sk-Ski","name":"Freemap.sk Ski","type":"tms","template":"http://t{switch:1,2,3,4}.freemap.sk/K/{zoom}/{x}/{y}.jpeg","scaleExtent":[8,16],"polygon":[[[19.83682,49.25529],[19.80075,49.42385],[19.60437,49.48058],[19.49179,49.63961],[19.21831,49.52604],[19.16778,49.42521],[19.00308,49.42236],[18.97611,49.5308],[18.54685,49.51425],[18.31432,49.33818],[18.15913,49.2961],[18.05564,49.11134],[17.56396,48.84938],[17.17929,48.88816],[17.058,48.81105],[16.90426,48.61947],[16.79685,48.38561],[17.06762,48.01116],[17.32787,47.97749],[17.51699,47.82535],[17.74776,47.73093],[18.29515,47.72075],[18.67959,47.75541],[18.89755,47.81203],[18.79463,47.88245],[18.84318,48.04046],[19.46212,48.05333],[19.62064,48.22938],[19.89585,48.09387],[20.33766,48.2643],[20.55395,48.52358],[20.82335,48.55714],[21.10271,48.47096],[21.45863,48.55513],[21.74536,48.31435],[22.15293,48.37179],[22.61255,49.08914],[22.09997,49.23814],[21.9686,49.36363],[21.6244,49.46989],[21.06873,49.46402],[20.94336,49.31088],[20.73052,49.44006],[20.22804,49.41714],[20.05234,49.23052],[19.83682,49.25529]]],"terms_text":"Copyright ©2007-2012 Freemap Slovakia (www.freemap.sk). Some rights reserved."},{"id":"Geodatastyrelsen_Denmark","name":"Geodatastyrelsen (Denmark)","type":"tms","template":"http://osmtools.septima.dk/mapproxy/tiles/1.0.0/kortforsyningen_ortoforaar/EPSG3857/{zoom}/{x}/{y}.jpeg","scaleExtent":[0,21],"polygon":[[[8.3743941,54.9551655],[8.3683809,55.4042149],[8.2103997,55.4039795],[8.2087314,55.4937345],[8.0502655,55.4924731],[8.0185123,56.7501399],[8.1819161,56.7509948],[8.1763274,57.0208898],[8.3413329,57.0219872],[8.3392467,57.1119574],[8.5054433,57.1123212],[8.5033923,57.2020499],[9.3316304,57.2027636],[9.3319079,57.2924835],[9.4978864,57.2919578],[9.4988593,57.3820608],[9.6649749,57.3811615],[9.6687295,57.5605591],[9.8351961,57.5596265],[9.8374896,57.6493322],[10.1725726,57.6462818],[10.1754245,57.7367768],[10.5118282,57.7330269],[10.5152095,57.8228945],[10.6834853,57.8207722],[10.6751613,57.6412021],[10.5077045,57.6433097],[10.5039992,57.5535088],[10.671038,57.5514113],[10.6507805,57.1024538],[10.4857673,57.1045138],[10.4786236,56.9249051],[10.3143981,56.9267573],[10.3112341,56.8369269],[10.4750295,56.83509],[10.4649016,56.5656681],[10.9524239,56.5589761],[10.9479249,56.4692243],[11.1099335,56.4664675],[11.1052639,56.376833],[10.9429901,56.3795284],[10.9341235,56.1994768],[10.7719685,56.2020244],[10.7694751,56.1120103],[10.6079695,56.1150259],[10.4466742,56.116717],[10.2865948,56.118675],[10.2831527,56.0281851],[10.4439274,56.0270388],[10.4417713,55.7579243],[10.4334961,55.6693533],[10.743814,55.6646861],[10.743814,55.5712253],[10.8969041,55.5712253],[10.9051793,55.3953852],[11.0613726,55.3812841],[11.0593038,55.1124061],[11.0458567,55.0318621],[11.2030844,55.0247474],[11.2030844,55.117139],[11.0593038,55.1124061],[11.0613726,55.3812841],[11.0789572,55.5712253],[10.8969041,55.5712253],[10.9258671,55.6670198],[10.743814,55.6646861],[10.7562267,55.7579243],[10.4417713,55.7579243],[10.4439274,56.0270388],[10.4466742,56.116717],[10.6079695,56.1150259],[10.6052053,56.0247462],[10.9258671,56.0201215],[10.9197132,55.9309388],[11.0802782,55.92792],[11.0858066,56.0178284],[11.7265047,56.005058],[11.7319981,56.0952142],[12.0540333,56.0871256],[12.0608477,56.1762576],[12.7023469,56.1594405],[12.6611131,55.7114318],[12.9792318,55.7014026],[12.9612912,55.5217294],[12.3268659,55.5412096],[12.3206071,55.4513655],[12.4778226,55.447067],[12.4702432,55.3570479],[12.6269738,55.3523837],[12.6200898,55.2632576],[12.4627339,55.26722],[12.4552949,55.1778223],[12.2987046,55.1822303],[12.2897344,55.0923641],[12.6048608,55.0832904],[12.5872011,54.9036285],[12.2766618,54.9119031],[12.2610181,54.7331602],[12.1070691,54.7378161],[12.0858621,54.4681655],[11.7794953,54.4753579],[11.7837381,54.5654783],[11.1658525,54.5782155],[11.1706443,54.6686508],[10.8617173,54.6733956],[10.8651245,54.7634667],[10.7713646,54.7643888],[10.7707276,54.7372807],[10.7551428,54.7375776],[10.7544039,54.7195666],[10.7389074,54.7197588],[10.7384368,54.7108482],[10.7074486,54.7113045],[10.7041094,54.6756741],[10.5510973,54.6781698],[10.5547184,54.7670245],[10.2423994,54.7705935],[10.2459845,54.8604673],[10.0902268,54.8622134],[10.0873731,54.7723851],[9.1555798,54.7769557],[9.1562752,54.8675369],[8.5321973,54.8663765],[8.531432,54.95516],[8.3743941,54.9551655]],[[11.4577738,56.819554],[11.7849181,56.8127385],[11.7716715,56.6332796],[11.4459621,56.6401087],[11.4577738,56.819554]],[[11.3274736,57.3612962],[11.3161808,57.1818004],[11.1508692,57.1847276],[11.1456628,57.094962],[10.8157703,57.1001693],[10.8290599,57.3695272],[11.3274736,57.3612962]],[[11.5843266,56.2777928],[11.5782882,56.1880397],[11.7392309,56.1845765],[11.7456428,56.2743186],[11.5843266,56.2777928]],[[14.6825922,55.3639405],[14.8395247,55.3565231],[14.8263755,55.2671261],[15.1393406,55.2517359],[15.1532015,55.3410836],[15.309925,55.3330556],[15.295719,55.2437356],[15.1393406,55.2517359],[15.1255631,55.1623802],[15.2815819,55.1544167],[15.2535578,54.9757646],[14.6317464,55.0062496],[14.6825922,55.3639405]]],"terms_url":"http://download.kortforsyningen.dk/content/vilkaar-og-betingelser","terms_text":"Geodatastyrelsen og Danske Kommuner","best":true},{"id":"Geoportal-PL-aerial_image","name":"Geoportal.gov.pl (Orthophotomap)","type":"tms","template":"http://wms.misek.pl/geoportal.orto/tms/{zoom}/{x}/{y}","scaleExtent":[6,24],"polygon":[[[15.9751041,54.3709213],[16.311164,54.5561775],[17.1391878,54.7845723],[18.3448458,54.9022727],[19.6613689,54.4737213],[20.2815206,54.4213456],[21.4663914,54.3406369],[22.7759855,54.3769755],[22.8625989,54.4233613],[23.2956657,54.2678633],[23.5347186,54.0955258],[23.5208604,53.9775182],[23.7183389,53.4629603],[23.9296755,53.1856735],[23.9296755,52.6887269],[23.732197,52.6067497],[23.5658994,52.5878101],[23.2090523,52.3302642],[23.1951942,52.2370089],[23.5035377,52.1860596],[23.6906226,52.0030113],[23.5970802,51.739903],[23.6629063,51.3888562],[23.9366046,50.9827781],[24.1687284,50.8604752],[24.0197534,50.8035823],[24.1098313,50.6610467],[24.0578633,50.4188439],[23.6178674,50.3083403],[22.6824431,49.5163532],[22.7378756,49.2094935],[22.9041733,49.0780441],[22.8625989,48.9940062],[22.6096878,49.0371785],[22.0761495,49.2004392],[21.8474902,49.3721872],[21.3763135,49.4488281],[21.1026153,49.3721872],[20.9120659,49.3022043],[20.6452967,49.3902311],[20.1845136,49.3315641],[20.1186875,49.2004392],[19.9419962,49.1302123],[19.765305,49.2117568],[19.7479823,49.3992506],[19.6024718,49.4150307],[19.5089294,49.5815389],[19.4292451,49.5905232],[19.2317666,49.4150307],[18.9961783,49.387976],[18.9338167,49.4916048],[18.8368097,49.4938552],[18.8021643,49.6623381],[18.6427958,49.7094091],[18.521537,49.8994693],[18.0815412,50.0109209],[17.8875272,49.9886512],[17.7385522,50.0687739],[17.6068999,50.1709584],[17.7454813,50.2153184],[17.710836,50.3017019],[17.4163505,50.2640668],[16.9486384,50.4453265],[16.8932058,50.4033889],[17.0006064,50.3105529],[17.017929,50.2241854],[16.8135215,50.186489],[16.6402948,50.0976742],[16.4324227,50.2862087],[16.1968344,50.4276731],[16.4220291,50.5885165],[16.3388803,50.6632429],[16.2280152,50.6368824],[16.0547884,50.6127057],[15.5732181,50.7641544],[15.2683391,50.8976368],[15.2440873,50.980597],[15.0292862,51.0133036],[15.0015699,50.8582883],[14.8110205,50.8735944],[14.956531,51.0721176],[15.0188926,51.2914636],[14.9392083,51.4601459],[14.7209426,51.5571799],[14.7521234,51.6260562],[14.5996839,51.8427626],[14.70362,52.0733396],[14.5581095,52.2497371],[14.5165351,52.425436],[14.6031485,52.5878101],[14.1146491,52.8208272],[14.152759,52.9733951],[14.3502374,53.0734212],[14.4229927,53.2665624],[14.1977979,53.8734759],[14.2220497,53.9958517],[15.9751041,54.3709213]]],"terms_text":"Copyright © Główny Urząd Geodezji i Kartografii.","best":true},{"id":"IBGE_DF_Addresses","name":"IBGE Distrito Federal","type":"tms","template":"https://api.mapbox.com/styles/v1/wille/cirnnxni1000jg8nfppc8g7pm/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoid2lsbGUiLCJhIjoicFNVWk5VWSJ9.hluCd0YGvYHNlFi_utWe2g","description":"Addresses data from IBGE","scaleExtent":[0,19],"polygon":[[[-48.2444,-16.0508],[-48.2444,-15.5005],[-47.5695,-15.5005],[-47.5695,-16.0508],[-48.2444,-16.0508]]],"overlay":true},{"id":"IBGE_Setores_Rurais","name":"IBGE Mapa de Setores Rurais","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/tmpsantos.i00mo1kj/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","scaleExtent":[0,14],"polygon":[[[-29.3325,2.335959],[-28.72472,2.031551],[-27.76041,-8.937033],[-27.67249,-22.20839],[-51.11495,-35.46552],[-53.39394,-33.85064],[-53.62553,-33.72493],[-53.62503,-33.15428],[-53.24498,-32.73392],[-53.65747,-32.51873],[-53.8329,-32.16592],[-54.64174,-31.55507],[-55.29638,-31.3429],[-55.57371,-30.99691],[-56.06384,-31.16749],[-56.10468,-30.86436],[-56.86862,-30.20752],[-57.39671,-30.40464],[-57.74384,-30.22142],[-55.83724,-28.16598],[-54.86969,-27.44994],[-53.9016,-27.02998],[-53.74972,-26.25781],[-53.97158,-25.74513],[-54.44723,-25.79609],[-54.67802,-25.64668],[-54.36097,-24.35145],[-54.41679,-24.06527],[-54.64355,-23.94107],[-55.22163,-24.11355],[-55.49138,-24.02797],[-55.71734,-22.68488],[-55.90555,-22.39886],[-56.45255,-22.21731],[-56.8256,-22.4002],[-57.34109,-22.34351],[-58.08472,-22.13075],[-57.95766,-20.99818],[-58.26551,-20.24147],[-58.03577,-19.95871],[-58.23083,-19.75211],[-57.64739,-18.19828],[-57.89356,-17.57377],[-58.16997,-17.53519],[-58.48825,-17.21961],[-58.57691,-16.81466],[-58.45563,-16.42158],[-60.2541,-16.32571],[-60.33481,-15.51483],[-60.67423,-15.1122],[-60.34999,-14.99707],[-60.63603,-13.84119],[-61.07283,-13.62569],[-61.9025,-13.62647],[-62.21395,-13.25048],[-62.80185,-13.10905],[-63.17194,-12.76568],[-63.74229,-12.54071],[-64.32845,-12.59578],[-65.10261,-12.0682],[-65.45781,-11.27865],[-65.41641,-9.838943],[-66.52331,-9.985873],[-67.66452,-10.80093],[-67.99778,-10.75991],[-68.52286,-11.20807],[-69.88988,-11.02776],[-70.30957,-11.1699],[-70.71896,-11.02003],[-70.68128,-9.669083],[-71.27536,-10.08971],[-72.18053,-10.09967],[-72.41623,-9.587397],[-73.29207,-9.454149],[-73.0625,-9.017267],[-73.61432,-8.40982],[-74.09056,-7.527548],[-74.03652,-7.27885],[-73.84718,-7.238285],[-73.78618,-6.774872],[-73.22362,-6.430106],[-73.33719,-6.029736],[-72.93016,-5.038711],[-71.93973,-4.425027],[-70.96802,-4.248294],[-70.79598,-4.064931],[-70.02393,-4.167345],[-69.51025,-1.134089],[-69.70776,-0.567619],[-70.13645,-0.226161],[-70.14083,0.5844],[-69.26594,0.806502],[-69.34226,0.968924],[-69.92481,1.015705],[-69.92343,1.773851],[-68.38511,1.82943],[-68.24848,2.119808],[-67.94571,1.948424],[-67.37696,2.327468],[-67.05751,1.858336],[-67.00579,1.291603],[-66.79967,1.314684],[-66.28683,0.857709],[-65.67671,1.111146],[-65.42494,0.966549],[-65.15671,1.24203],[-64.27483,1.601591],[-64.0486,2.065137],[-63.47236,2.279358],[-64.13446,2.433909],[-64.10005,2.723778],[-64.32628,3.118275],[-64.28142,3.541983],[-64.88451,4.117671],[-64.88064,4.342461],[-64.13653,4.223152],[-63.95465,4.021316],[-63.17706,4.048301],[-62.96093,3.763658],[-62.82024,4.106019],[-62.49922,4.270815],[-61.91181,4.26284],[-61.35393,4.630097],[-61.04904,4.623115],[-60.70452,4.969851],[-60.78709,5.296764],[-60.22457,5.371207],[-59.89857,5.107541],[-59.97549,4.603025],[-59.59676,4.439875],[-59.41942,3.96994],[-59.71017,3.542008],[-59.88955,2.72301],[-59.63006,2.316332],[-59.63382,1.966581],[-59.18812,1.478079],[-58.80545,1.320732],[-58.35933,1.689932],[-57.6,1.803907],[-57.39854,2.065119],[-57.12392,2.128758],[-56.02925,1.949445],[-56.23884,2.263348],[-55.98195,2.628657],[-55.64816,2.519953],[-54.93958,2.682515],[-54.24988,2.25056],[-53.73937,2.473731],[-52.98578,2.280494],[-52.65712,2.564069],[-52.41739,3.22121],[-51.73983,4.119158],[-51.7246,4.556867],[-51.0112,5.522895],[-43.48209,5.335832],[-29.3325,2.335959]]]},{"id":"IBGE_Setores_Urbanos","name":"IBGE Mapa de Setores Urbanos","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/tmpsantos.hgda0m6h/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","scaleExtent":[0,19],"polygon":[[[-29.3325,2.335959],[-28.72472,2.031551],[-27.76041,-8.937033],[-27.67249,-22.20839],[-51.11495,-35.46552],[-53.39394,-33.85064],[-53.62553,-33.72493],[-53.62503,-33.15428],[-53.24498,-32.73392],[-53.65747,-32.51873],[-53.8329,-32.16592],[-54.64174,-31.55507],[-55.29638,-31.3429],[-55.57371,-30.99691],[-56.06384,-31.16749],[-56.10468,-30.86436],[-56.86862,-30.20752],[-57.39671,-30.40464],[-57.74384,-30.22142],[-55.83724,-28.16598],[-54.86969,-27.44994],[-53.9016,-27.02998],[-53.74972,-26.25781],[-53.97158,-25.74513],[-54.44723,-25.79609],[-54.67802,-25.64668],[-54.36097,-24.35145],[-54.41679,-24.06527],[-54.64355,-23.94107],[-55.22163,-24.11355],[-55.49138,-24.02797],[-55.71734,-22.68488],[-55.90555,-22.39886],[-56.45255,-22.21731],[-56.8256,-22.4002],[-57.34109,-22.34351],[-58.08472,-22.13075],[-57.95766,-20.99818],[-58.26551,-20.24147],[-58.03577,-19.95871],[-58.23083,-19.75211],[-57.64739,-18.19828],[-57.89356,-17.57377],[-58.16997,-17.53519],[-58.48825,-17.21961],[-58.57691,-16.81466],[-58.45563,-16.42158],[-60.2541,-16.32571],[-60.33481,-15.51483],[-60.67423,-15.1122],[-60.34999,-14.99707],[-60.63603,-13.84119],[-61.07283,-13.62569],[-61.9025,-13.62647],[-62.21395,-13.25048],[-62.80185,-13.10905],[-63.17194,-12.76568],[-63.74229,-12.54071],[-64.32845,-12.59578],[-65.10261,-12.0682],[-65.45781,-11.27865],[-65.41641,-9.838943],[-66.52331,-9.985873],[-67.66452,-10.80093],[-67.99778,-10.75991],[-68.52286,-11.20807],[-69.88988,-11.02776],[-70.30957,-11.1699],[-70.71896,-11.02003],[-70.68128,-9.669083],[-71.27536,-10.08971],[-72.18053,-10.09967],[-72.41623,-9.587397],[-73.29207,-9.454149],[-73.0625,-9.017267],[-73.61432,-8.40982],[-74.09056,-7.527548],[-74.03652,-7.27885],[-73.84718,-7.238285],[-73.78618,-6.774872],[-73.22362,-6.430106],[-73.33719,-6.029736],[-72.93016,-5.038711],[-71.93973,-4.425027],[-70.96802,-4.248294],[-70.79598,-4.064931],[-70.02393,-4.167345],[-69.51025,-1.134089],[-69.70776,-0.567619],[-70.13645,-0.226161],[-70.14083,0.5844],[-69.26594,0.806502],[-69.34226,0.968924],[-69.92481,1.015705],[-69.92343,1.773851],[-68.38511,1.82943],[-68.24848,2.119808],[-67.94571,1.948424],[-67.37696,2.327468],[-67.05751,1.858336],[-67.00579,1.291603],[-66.79967,1.314684],[-66.28683,0.857709],[-65.67671,1.111146],[-65.42494,0.966549],[-65.15671,1.24203],[-64.27483,1.601591],[-64.0486,2.065137],[-63.47236,2.279358],[-64.13446,2.433909],[-64.10005,2.723778],[-64.32628,3.118275],[-64.28142,3.541983],[-64.88451,4.117671],[-64.88064,4.342461],[-64.13653,4.223152],[-63.95465,4.021316],[-63.17706,4.048301],[-62.96093,3.763658],[-62.82024,4.106019],[-62.49922,4.270815],[-61.91181,4.26284],[-61.35393,4.630097],[-61.04904,4.623115],[-60.70452,4.969851],[-60.78709,5.296764],[-60.22457,5.371207],[-59.89857,5.107541],[-59.97549,4.603025],[-59.59676,4.439875],[-59.41942,3.96994],[-59.71017,3.542008],[-59.88955,2.72301],[-59.63006,2.316332],[-59.63382,1.966581],[-59.18812,1.478079],[-58.80545,1.320732],[-58.35933,1.689932],[-57.6,1.803907],[-57.39854,2.065119],[-57.12392,2.128758],[-56.02925,1.949445],[-56.23884,2.263348],[-55.98195,2.628657],[-55.64816,2.519953],[-54.93958,2.682515],[-54.24988,2.25056],[-53.73937,2.473731],[-52.98578,2.280494],[-52.65712,2.564069],[-52.41739,3.22121],[-51.73983,4.119158],[-51.7246,4.556867],[-51.0112,5.522895],[-43.48209,5.335832],[-29.3325,2.335959]]]},{"id":"Haiti-Drone","name":"Imagerie Drone (Haiti)","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/iomhaiti/{zoom}/{x}/{y}","polygon":[[[-72.1547401,19.6878969],[-72.162234,19.689011],[-72.164995,19.6932445],[-72.1657838,19.6979977],[-72.161603,19.7035677],[-72.1487449,19.7028993],[-72.1477194,19.7026765],[-72.1485082,19.7001514],[-72.1436963,19.7011169],[-72.1410143,19.7000029],[-72.139476,19.6973664],[-72.1382533,19.6927617],[-72.1386872,19.6923161],[-72.1380561,19.6896423],[-72.1385294,19.6894938],[-72.1388055,19.6901251],[-72.1388844,19.6876741],[-72.1378195,19.6872656],[-72.13778,19.6850003],[-72.1369517,19.6855945],[-72.136794,19.6840719],[-72.135729,19.6835148],[-72.1355713,19.6740817],[-72.1366362,19.6708133],[-72.1487843,19.6710733],[-72.1534779,19.6763843],[-72.1530835,19.6769414],[-72.1533251,19.6769768],[-72.1532807,19.6796525],[-72.1523834,19.6797175],[-72.1522749,19.6803488],[-72.1519101,19.6803395],[-72.1518608,19.6805067],[-72.1528173,19.6806552],[-72.1522299,19.6833011],[-72.1507801,19.6831499],[-72.1504457,19.6847862],[-72.1508591,19.6843492],[-72.1530087,19.6849898],[-72.1546258,19.6854354],[-72.1543103,19.6870694],[-72.1547244,19.6868466],[-72.1548501,19.6877564],[-72.1545814,19.6877982],[-72.1547401,19.6878969]],[[-72.1310601,19.6718929],[-72.1259842,19.6772765],[-72.1255379,19.6776179],[-72.1216891,19.6776442],[-72.1149677,19.672602],[-72.1152745,19.6687152],[-72.1198205,19.6627535],[-72.1227768,19.6625696],[-72.1248965,19.662701],[-72.1285779,19.6645394],[-72.1308091,19.6661677],[-72.1316737,19.668794],[-72.1315621,19.671],[-72.1310601,19.6718929]],[[-71.845795,19.6709758],[-71.8429354,19.6759525],[-71.8410027,19.6759525],[-71.8380249,19.6755254],[-71.8378671,19.6745041],[-71.8390504,19.6743927],[-71.8390109,19.6741141],[-71.8398392,19.673947],[-71.8389123,19.6736127],[-71.8380249,19.67209],[-71.8380052,19.6726285],[-71.8376699,19.6727214],[-71.8376305,19.672545],[-71.8354414,19.6732135],[-71.835333,19.6729999],[-71.8331242,19.6734642],[-71.8326706,19.6716815],[-71.8321579,19.67209],[-71.8307183,19.6694902],[-71.8306009,19.6697594],[-71.8302174,19.6698907],[-71.8291833,19.6672095],[-71.8290749,19.6672095],[-71.8289122,19.6667916],[-71.8289516,19.6666199],[-71.8288333,19.6663506],[-71.8285572,19.6664759],[-71.8288678,19.6672466],[-71.8287593,19.6674138],[-71.8277979,19.6678177],[-71.8277112,19.6678586],[-71.8278263,19.6679637],[-71.8271831,19.6681212],[-71.8271761,19.6680917],[-71.8264405,19.6683921],[-71.8264074,19.6683231],[-71.8261954,19.6684253],[-71.8261806,19.6683556],[-71.8258946,19.6684206],[-71.8258897,19.6686574],[-71.8251551,19.6687549],[-71.8254509,19.6691588],[-71.8229332,19.6695739],[-71.822713,19.6696658],[-71.8227688,19.6697577],[-71.8201751,19.6709855],[-71.8198474,19.6704537],[-71.8197985,19.6706014],[-71.8194674,19.6707557],[-71.8182472,19.6713433],[-71.8181426,19.6711431],[-71.8175813,19.6714254],[-71.816959,19.6707672],[-71.8176388,19.6718965],[-71.8171403,19.6720376],[-71.8158225,19.6718045],[-71.8138354,19.6711874],[-71.8123259,19.6706982],[-71.8121759,19.6704258],[-71.8124304,19.6701467],[-71.8119184,19.6700141],[-71.8118765,19.6705828],[-71.811169,19.6703483],[-71.8095938,19.6698516],[-71.8077992,19.6692829],[-71.8056028,19.668612],[-71.8051443,19.6668942],[-71.8051196,19.6652322],[-71.8052315,19.661979],[-71.8065603,19.6523921],[-71.8073412,19.6482946],[-71.8099686,19.6468292],[-71.8147517,19.6454502],[-71.8147726,19.6455619],[-71.8150027,19.6455093],[-71.8149469,19.6453846],[-71.8159928,19.6450234],[-71.8158882,19.6448855],[-71.8165854,19.6446097],[-71.8190119,19.643802],[-71.8211524,19.643454],[-71.8221564,19.6433292],[-71.8269046,19.643211],[-71.8280481,19.6432241],[-71.8304466,19.6440778],[-71.8306419,19.6448592],[-71.8295263,19.6450365],[-71.8296064,19.6456111],[-71.8299411,19.6455651],[-71.8303699,19.6451744],[-71.830471,19.6453452],[-71.8308092,19.6451974],[-71.8310184,19.6451088],[-71.8312519,19.6458541],[-71.8311125,19.6458245],[-71.831367,19.6465862],[-71.8328939,19.646189],[-71.8344566,19.6457062],[-71.8344664,19.6463052],[-71.834215,19.6461938],[-71.8342002,19.6465513],[-71.8346702,19.6463],[-71.8349118,19.6463905],[-71.8347984,19.6462187],[-71.8354393,19.6458496],[-71.8355034,19.6458032],[-71.8364747,19.6461328],[-71.8376382,19.6472658],[-71.8379143,19.647888],[-71.8390483,19.6508039],[-71.8456942,19.6696203],[-71.845795,19.6709758]],[[-72.098878,18.54843],[-72.096993,18.5501994],[-72.0972888,18.5503209],[-72.0968451,18.5503489],[-72.0955632,18.551854],[-72.0956428,18.5526742],[-72.0959914,18.5533748],[-72.0962145,18.553203],[-72.0962842,18.5535665],[-72.0964446,18.5535533],[-72.0965352,18.5539764],[-72.0965056,18.554173],[-72.0966085,18.5541747],[-72.0965178,18.5542127],[-72.0968769,18.5546588],[-72.0979018,18.5552141],[-72.1006211,18.5555875],[-72.1014926,18.5556206],[-72.1024339,18.5555016],[-72.103417,18.5543515],[-72.1034798,18.5516215],[-72.1030789,18.5516149],[-72.1033752,18.5515224],[-72.1035042,18.5515224],[-72.1035239,18.5502417],[-72.1028701,18.5503062],[-72.1029015,18.55025],[-72.1028457,18.5501773],[-72.1035081,18.5500252],[-72.103491,18.5497396],[-72.1035181,18.5497361],[-72.1035398,18.5489039],[-72.1034317,18.5487056],[-72.102717,18.5481437],[-72.1025601,18.5481536],[-72.10229,18.5482751],[-72.1022891,18.5482569],[-72.1025201,18.5481396],[-72.1023388,18.5481321],[-72.0999082,18.5480901],[-72.09907,18.5483799],[-72.098878,18.54843]],[[-72.2542503,18.568262],[-72.2560252,18.5717765],[-72.2557886,18.5748049],[-72.2535009,18.5755526],[-72.2522782,18.5755526],[-72.2499906,18.5740945],[-72.2473874,18.5698323],[-72.2460069,18.566729],[-72.2458492,18.5629527],[-72.2479396,18.5625414],[-72.2501483,18.5628031],[-72.2519232,18.5650839],[-72.2542503,18.568262]],[[-72.303145,18.5332749],[-72.3031275,18.5331799],[-72.3048311,18.5311081],[-72.3097397,18.5311081],[-72.3164332,18.5324302],[-72.3234056,18.5366083],[-72.3261388,18.5387765],[-72.3261946,18.5426371],[-72.3170468,18.5540596],[-72.3130864,18.5540596],[-72.2987511,18.5453342],[-72.2988627,18.5407333],[-72.2962969,18.5404689],[-72.2954602,18.5395169],[-72.2961853,18.5338582],[-72.2971893,18.5332235],[-72.3007034,18.5332764],[-72.3022652,18.5342284],[-72.3028486,18.5335189],[-72.303104,18.5333361],[-72.303181,18.5334007],[-72.3035793,18.5335614],[-72.3030793,18.5346463],[-72.303715,18.5339873],[-72.3045286,18.5344052],[-72.3044015,18.5345097],[-72.3062747,18.5352571],[-72.3063107,18.5352741],[-72.3061219,18.5357628],[-72.3061219,18.5358196],[-72.30637,18.5358928],[-72.3062726,18.5354869],[-72.3066688,18.5350891],[-72.3061963,18.5349706],[-72.3058869,18.5349385],[-72.3055373,18.5346833],[-72.3054864,18.534613],[-72.3055585,18.5345065],[-72.3046749,18.5342293],[-72.3047617,18.5338817],[-72.3043252,18.5337511],[-72.3042595,18.5336346],[-72.303145,18.5332749]],[[-72.2981405,18.477502],[-72.2935652,18.4948587],[-72.2922242,18.4964297],[-72.2931708,18.4972526],[-72.2892266,18.5057058],[-72.2878067,18.5080996],[-72.2850458,18.5119893],[-72.2840203,18.5113161],[-72.2808649,18.515879],[-72.2773151,18.5175994],[-72.2723454,18.5175246],[-72.2662714,18.5144578],[-72.2665869,18.5066783],[-72.2692643,18.5046154],[-72.2661965,18.5029756],[-72.2688181,18.4965222],[-72.2691528,18.4959403],[-72.2702684,18.4961519],[-72.2702684,18.4955964],[-72.2690691,18.49557],[-72.2692922,18.4937714],[-72.2736988,18.4859951],[-72.2746749,18.4850429],[-72.2751769,18.483403],[-72.2765435,18.4813398],[-72.2773523,18.4814985],[-72.2783006,18.4809694],[-72.2778544,18.4807049],[-72.2771013,18.480123],[-72.2789978,18.4775836],[-72.279723,18.4772927],[-72.2806433,18.4776365],[-72.2813685,18.4771604],[-72.2808386,18.4769752],[-72.2812848,18.4758378],[-72.2823167,18.4751765],[-72.2851615,18.4750971],[-72.2849941,18.4763668],[-72.2854404,18.4769752],[-72.286277,18.4756262],[-72.2869325,18.4754675],[-72.2865978,18.4751897],[-72.2865978,18.4750046],[-72.2909765,18.4747268],[-72.2946579,18.4749384],[-72.2973911,18.476843],[-72.2981405,18.477502]],[[-72.3466657,18.5222375],[-72.346833,18.5244325],[-72.3475303,18.5277645],[-72.3455501,18.5291131],[-72.3403069,18.5292189],[-72.3383267,18.5280289],[-72.3369043,18.530118],[-72.3338086,18.5296684],[-72.3289279,18.5270769],[-72.328649,18.5253316],[-72.3292068,18.5232689],[-72.330406,18.5220524],[-72.3321631,18.5221847],[-72.3322467,18.5191963],[-72.3369183,18.5183633],[-72.3382012,18.5184691],[-72.3381454,18.5181782],[-72.3411993,18.5177947],[-72.3454943,18.5171997],[-72.3492595,18.517279],[-72.3504308,18.5188922],[-72.3503472,18.5206112],[-72.3496778,18.5220392],[-72.3466657,18.5222375]],[[-72.3303078,18.5486462],[-72.3429687,18.5508149],[-72.3433236,18.5530585],[-72.3413121,18.5614341],[-72.3390639,18.5613593],[-72.3384723,18.5638271],[-72.3375257,18.5654348],[-72.3348436,18.5650609],[-72.3311755,18.5638271],[-72.3312149,18.5616211],[-72.3232082,18.5606863],[-72.3212361,18.559602],[-72.3208023,18.5587046],[-72.3208811,18.557882],[-72.3259493,18.5580274],[-72.3266186,18.5581993],[-72.3259214,18.5577498],[-72.3250986,18.5573797],[-72.3233767,18.552263],[-72.3245994,18.5478507],[-72.3288986,18.5483742],[-72.329979,18.5489548],[-72.3303078,18.5486462]],[[-72.3231383,18.5269828],[-72.3223434,18.528067],[-72.3209629,18.5279745],[-72.3207816,18.5271282],[-72.3208513,18.5253697],[-72.3214649,18.5249598],[-72.3225666,18.5248937],[-72.3228454,18.52533],[-72.3232359,18.5264804],[-72.3231383,18.5269828]],[[-72.2160832,18.6457752],[-72.2159649,18.6553795],[-72.2030279,18.6558279],[-72.1947057,18.6553421],[-72.1922208,18.6545573],[-72.1920631,18.6521283],[-72.193483,18.6477559],[-72.201253,18.6385249],[-72.2069327,18.6388239],[-72.2120996,18.6424117],[-72.2118068,18.6430591],[-72.2121693,18.6426892],[-72.2127968,18.6427552],[-72.2134662,18.6431252],[-72.2135638,18.6437462],[-72.2154176,18.6443947],[-72.2158909,18.6450301],[-72.2160832,18.6457752]],[[-72.2867654,18.6482017],[-72.2900977,18.6527446],[-72.28981,18.6536532],[-72.2900738,18.6542664],[-72.290721,18.6537667],[-72.2910327,18.6544709],[-72.2912485,18.654221],[-72.29168,18.6558905],[-72.2912245,18.656606],[-72.2922673,18.65597],[-72.2926869,18.6567536],[-72.2930705,18.6567309],[-72.2941253,18.6581846],[-72.2960192,18.6608421],[-72.2959713,18.6619096],[-72.2932862,18.664567],[-72.2906731,18.6659979],[-72.2895943,18.6661342],[-72.2895943,18.6665657],[-72.2877004,18.6664749],[-72.2875805,18.6676559],[-72.2831214,18.6697227],[-72.2796453,18.6696546],[-72.2784311,18.6690787],[-72.2783972,18.6687736],[-72.277736,18.6691671],[-72.2774394,18.669143],[-72.2770071,18.6683159],[-72.2765575,18.6681125],[-72.2765385,18.6680583],[-72.2752319,18.6685239],[-72.2749292,18.6674649],[-72.2746416,18.6674309],[-72.2734668,18.6682145],[-72.2732271,18.6682712],[-72.2726757,18.6671583],[-72.2719147,18.6674288],[-72.2718808,18.6673405],[-72.2688149,18.6681868],[-72.2688269,18.6671761],[-72.2690786,18.6668241],[-72.2688149,18.66679],[-72.2681077,18.6670739],[-72.2676282,18.6673805],[-72.2675563,18.6666878],[-72.266861,18.666949],[-72.2655904,18.6673578],[-72.2654466,18.6670058],[-72.2647514,18.6674146],[-72.2629893,18.6681868],[-72.2628455,18.6681754],[-72.2626537,18.6676076],[-72.2623001,18.6677098],[-72.2624799,18.6679199],[-72.2624799,18.6682322],[-72.262306,18.6682606],[-72.2620963,18.6679654],[-72.2622761,18.6689193],[-72.2601484,18.6688966],[-72.2542749,18.6687944],[-72.2505388,18.6683476],[-72.2504371,18.669536],[-72.2477926,18.6698893],[-72.2415204,18.669793],[-72.2414187,18.6741933],[-72.2389167,18.6739759],[-72.2387249,18.6734649],[-72.2383653,18.6733059],[-72.2387009,18.6739532],[-72.2375502,18.6738964],[-72.2374183,18.6735103],[-72.237742,18.67334],[-72.2375142,18.6732605],[-72.236843,18.6734876],[-72.2364354,18.6724088],[-72.2355124,18.6726019],[-72.2354045,18.6724202],[-72.2353027,18.6729028],[-72.2345475,18.6726871],[-72.2343077,18.6724599],[-72.2342358,18.6734706],[-72.2334087,18.6734592],[-72.2332889,18.6733003],[-72.2327375,18.6732889],[-72.2327135,18.6735047],[-72.227703,18.6725281],[-72.2265283,18.6716537],[-72.226804,18.6715742],[-72.2274993,18.6715855],[-72.2274873,18.6714493],[-72.2272899,18.6714623],[-72.2272814,18.6712977],[-72.2272094,18.671358],[-72.2261785,18.6713693],[-72.2256032,18.670881],[-72.2255073,18.6694502],[-72.2261066,18.6696886],[-72.2261785,18.6695949],[-72.2259837,18.6695495],[-72.225777,18.6691379],[-72.2253335,18.6694643],[-72.2249739,18.66947],[-72.2245783,18.6678802],[-72.2235525,18.6677046],[-72.2235907,18.6675921],[-72.2224634,18.6676283],[-72.2223659,18.667022],[-72.2223277,18.6670943],[-72.2219209,18.667026],[-72.2208105,18.6669015],[-72.220809,18.6665325],[-72.2208705,18.6663593],[-72.2206023,18.6668107],[-72.2203895,18.6666361],[-72.2184341,18.6650535],[-72.21829,18.6640979],[-72.2183493,18.6608376],[-72.2187223,18.6606541],[-72.2186894,18.660603],[-72.2187253,18.6604525],[-72.2189771,18.6603247],[-72.2187823,18.6601998],[-72.2186984,18.6602367],[-72.2185815,18.6600352],[-72.2186085,18.6600039],[-72.2187823,18.6601345],[-72.218995,18.6600181],[-72.2189111,18.6599131],[-72.2189681,18.6597938],[-72.2183807,18.6595837],[-72.2184728,18.6539662],[-72.2201001,18.6511554],[-72.225796,18.6469472],[-72.2283048,18.6457265],[-72.2379335,18.645855],[-72.237764,18.6446985],[-72.2400355,18.6432529],[-72.2455958,18.6433493],[-72.2482742,18.6450358],[-72.2487488,18.6436705],[-72.2511067,18.6429775],[-72.2512385,18.6433409],[-72.2512625,18.6431592],[-72.2514843,18.6431365],[-72.2513284,18.6429718],[-72.2533602,18.6423471],[-72.253516,18.6426765],[-72.2539535,18.6425402],[-72.2541453,18.642932],[-72.2543851,18.6428696],[-72.2543791,18.6427503],[-72.2564168,18.6423244],[-72.2566925,18.6431365],[-72.2568783,18.6428582],[-72.2568184,18.6425288],[-72.258843,18.6420991],[-72.258885,18.6422467],[-72.2592626,18.6422297],[-72.2596461,18.6424057],[-72.2592206,18.6406907],[-72.2599545,18.6404815],[-72.2601156,18.6406341],[-72.2601156,18.6399393],[-72.2615268,18.6394669],[-72.2626056,18.6391034],[-72.2654465,18.6387286],[-72.2719433,18.6386832],[-72.272201,18.6388649],[-72.2730341,18.6394158],[-72.273166,18.6412558],[-72.2738732,18.6410286],[-72.2742208,18.6416079],[-72.2752187,18.6416987],[-72.2754524,18.6415738],[-72.2755513,18.6416874],[-72.2755394,18.6417527],[-72.2764713,18.6418634],[-72.276753,18.6418975],[-72.2762953,18.6426002],[-72.2774226,18.6429978],[-72.277982,18.6427247],[-72.2785796,18.6431303],[-72.2785669,18.6432307],[-72.2789017,18.6433471],[-72.279851,18.6439655],[-72.2858703,18.6469651],[-72.2867654,18.6482017]],[[-72.5557247,18.5305893],[-72.5555866,18.5367036],[-72.554995,18.537975],[-72.5488026,18.537919],[-72.5486646,18.5372832],[-72.548842,18.5306267],[-72.5493745,18.5301031],[-72.555133,18.5301218],[-72.5557247,18.5305893]],[[-72.6235278,18.5079877],[-72.6234441,18.5095217],[-72.6226074,18.5104341],[-72.6204878,18.511849],[-72.6183403,18.5107514],[-72.6162207,18.5083183],[-72.6162625,18.506467],[-72.618661,18.5044438],[-72.6204041,18.5044967],[-72.6228305,18.506996],[-72.6235278,18.5079877]]]},{"id":"osmim-imagicode-LC80700162014211LGN00","name":"imagico.de OSM images for mapping: Alaska Range","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80700162014211LGN00&z={zoom}&x={x}&y={-y}","description":"LC80700162014211LGN00, 2014-07-31 channels 234 (true color), Recent summer image of the Alaska Range for mapping natural features","scaleExtent":[0,12],"polygon":[[[-152.708729431479,62.3036424122946],[-152.708729431479,63.5464553885127],[-148.994366411548,63.5464553885127],[-148.994366411548,62.3036424122946],[-152.708729431479,62.3036424122946]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81190582014075LGN00","name":"imagico.de OSM images for mapping: Bakun Reservoir","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81190582014075LGN00&z={zoom}&x={x}&y={-y}","description":"LC81190582014075LGN00/LC81180582015183LGN00, 2014-03-16, channels 234 (true color), Missing in older pre-2011 images","scaleExtent":[0,13],"polygon":[[[113.53447549873,2.02707458823865],[113.53447549873,3.07076712442006],[114.765167437974,3.07076712442006],[114.765167437974,2.02707458823865],[113.53447549873,2.02707458823865]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81250592016107LGN00","name":"imagico.de OSM images for mapping: Batam","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81250592016107LGN00&z={zoom}&x={x}&y={-y}","description":"LC81250592016107LGN00, LC81250602015184LGN00, LC81240602014174LGN00, 2014-2016, channels 234 (true color), Missing Islands in OSM","scaleExtent":[0,13],"polygon":[[[104.001374040597,0],[104.001374040597,1.45116299803241],[104.910109782012,1.45116299803241],[104.910109782012,0],[104.001374040597,0]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81800982013291LGN00","name":"imagico.de OSM images for mapping: Bouvet Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81800982013291LGN00&z={zoom}&x={x}&y={-y}","description":"LC81800982013291LGN00, 2013-10-18, channels 234 (true color), For more accurate coastline and glacier mapping","scaleExtent":[0,13],"polygon":[[[3.24652940311363,-54.4705168479877],[3.24652940311363,-54.3753916879791],[3.46391271871771,-54.3753916879791],[3.46391271871771,-54.4705168479877],[3.24652940311363,-54.4705168479877]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","best":true},{"id":"osmim-imagicode-LC82050982015344LGN00","name":"imagico.de OSM images for mapping: Clerke Rocks","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82050982015344LGN00&z={zoom}&x={x}&y={-y}","description":"LC82050982015344LGN00, 2015-12-10, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-35.1959928318028,-55.2968852515402],[-35.1959928318028,-54.7209735214882],[-34.1252010131324,-54.7209735214882],[-34.1252010131324,-55.2968852515402],[-35.1959928318028,-55.2968852515402]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R022_N06_20151221T103009","name":"imagico.de OSM images for mapping: Cotonou","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R022_N06_20151221T103009&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20151222T164644_R022_V20151221T103009_20151221T103009, 2015-12-21, channels 234 (true color), Patchy and partly cloudy coverage in usual sources","scaleExtent":[0,14],"polygon":[[[1.83974970187678,6.25776229826032],[1.83974970187678,7.1142717924319],[2.5494187763312,7.1142717924319],[2.5494187763312,6.25776229826032],[1.83974970187678,6.25776229826032]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80360072014245LGN00","name":"imagico.de OSM images for mapping: Eastern Devon Island coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80360072014245LGN00&z={zoom}&x={x}&y={-y}","description":"LC80360072014245LGN00/LC80380062014243LGN00, 2014-09-02, channel 654 (false color IR), Coastline mostly mapped meanwhile","scaleExtent":[0,11],"polygon":[[[-84.3479873388655,74.3894989734754],[-84.3479873388655,75.8903032392084],[-79.1485833901459,75.8903032392084],[-79.1485833901459,74.3894989734754],[-84.3479873388655,74.3894989734754]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82160152013239LGN00","name":"imagico.de OSM images for mapping: Eastern Iceland","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82160152013239LGN00&z={zoom}&x={x}&y={-y}","description":"LC82160152013239LGN00, 2013-08-27, channels 234 (true color), Missing islets and inaccurate coast","scaleExtent":[0,12],"polygon":[[[-15.1680535723581,64.2088554380107],[-15.1680535723581,64.8157280042209],[-13.0435379254154,64.8157280042209],[-13.0435379254154,64.2088554380107],[-15.1680535723581,64.2088554380107]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-AST_L1T_00302052007154424_20150518041444_91492","name":"imagico.de OSM images for mapping: El Altar","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=AST_L1T_00302052007154424_20150518041444_91492&z={zoom}&x={x}&y={-y}","description":"AST_L1T_00302052007154424_20150518041444_91492, 2012-02-05, channels 12x (true color with estimated blue), 2007 ASTER image offering better glacier coverage than common sources","scaleExtent":[0,14],"polygon":[[[-78.531997745432,-1.8050814821624],[-78.531997745432,-1.60810556500124],[-78.3355811085593,-1.60810556500124],[-78.3355811085593,-1.8050814821624],[-78.531997745432,-1.8050814821624]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R009_S61_20160109","name":"imagico.de OSM images for mapping: Elephant Island/Clarence Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R009_S61_20160109&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160109T225906_R009_V20160109T130043_20160109T130043, 2016-01-09, channels 234 (true color), Fairly clear up-to-date image for updating glacier edges","scaleExtent":[0,13],"polygon":[[[-56.1347609072749,-61.634696838288],[-56.1347609072749,-60.8398161307814],[-53.723458105877,-60.8398161307814],[-53.723458105877,-61.634696838288],[-56.1347609072749,-61.634696838288]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82100502015347LGN00","name":"imagico.de OSM images for mapping: Fogo, Cape Verde","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82100502015347LGN00&z={zoom}&x={x}&y={-y}","description":"LC82100502015347LGN00, 2015-12-13, channels 234 (true color), Image from after the 2014/2015 eruption","scaleExtent":[0,14],"polygon":[[[-24.7587819559676,14.7481298855965],[-24.7587819559676,15.0924935449651],[-24.2670621357462,15.0924935449651],[-24.2670621357462,14.7481298855965],[-24.7587819559676,14.7481298855965]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-greenland","name":"imagico.de OSM images for mapping: Greenland mosaic","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=greenland&z={zoom}&x={x}&y={-y}","description":"mostly Landsat 8 2013-2015 channels 234 (true color), Landsat mosaic of Greenland","scaleExtent":[0,12],"polygon":[[[-43.335169388775576,59.78884556778711],[-43.5940638938192,59.723921705576714],[-43.840898275878764,59.67490148496335],[-44.23515133460447,59.653417915878954],[-44.657213255061194,59.680989005977885],[-45.81015180316172,59.81951972989828],[-46.81057076187592,59.98139710469466],[-47.20837894817284,60.150960472742064],[-47.22064190066637,60.33805731472787],[-47.255916208498,60.42332684576548],[-47.34990349056956,60.446387835215525],[-47.51603887007207,60.45119769375011],[-47.65139646003081,60.48896403744677],[-47.79170835578903,60.52050863908786],[-49.10695022655055,60.73414367492607],[-49.52399924941209,60.97440124547532],[-50.493558334841985,61.089523147855694],[-51.1011476720755,61.3931538528416],[-51.226493283028084,61.8368218735183],[-51.66491000695862,62.06066494936552],[-51.98744899262875,62.355028063412306],[-52.04791761614332,62.676138274608135],[-52.68385390751712,62.89777335327022],[-53.00141158114564,63.22960936121321],[-52.98804591383922,63.665519960839994],[-53.37455124039754,63.88257990608798],[-53.462018437442744,64.21700667649995],[-53.625006563694996,64.39608940752123],[-53.62418230433685,64.87666336480167],[-53.92737410039694,65.14174166474336],[-54.58568916434171,65.51879633173807],[-55.020580045260964,66.04786962007503],[-54.974959716968506,66.43747058777413],[-55.04621700056885,66.81068389526814],[-55.18883177742317,67.07445292724583],[-55.295917291513724,67.2980754937805],[-55.49386806070968,67.62765205772878],[-55.58982586875712,67.74762927352513],[-55.800191618857184,68.05623485476666],[-56.166042896634444,68.44155152338232],[-56.086954623441976,68.68479069915158],[-55.692397350070934,69.09499941753234],[-55.78268862269791,69.35591450732602],[-55.97508469715559,69.51460160299163],[-56.22131441053026,69.61961934478276],[-56.28674985487528,69.75311038137812],[-56.27734150260429,69.86115681621736],[-56.47867255356253,69.98628865160101],[-56.729667549723445,70.20797294037203],[-56.780049018329095,70.4030123058809],[-56.66995480486827,70.53429026926025],[-56.76965573535976,70.59936425752305],[-56.750047814068225,70.67605894741244],[-56.630475021762926,70.75228057874938],[-56.63957096755714,70.79345598378389],[-56.95453022049966,70.92185386457368],[-57.682941688207656,71.10356260725686],[-57.9990573064922,71.18275256548473],[-58.06673093129251,71.31878823942327],[-57.73776694812512,71.73468567987527],[-57.688607830732714,71.96425305773354],[-57.29627634430133,72.25939767922573],[-57.027097307050845,72.49722993388094],[-57.22262816078322,72.61296218481311],[-57.61910829550675,72.72652221937263],[-58.05813139640902,73.01331566875426],[-58.76645057271363,73.2808359719379],[-59.14761885260487,73.53482225342569],[-59.03651118375505,73.80651043385626],[-58.8823279108656,74.19210040380365],[-59.24788269229215,74.4273495816669],[-59.99510425025614,74.65678100854564],[-60.806460490534164,74.7868931828055],[-61.54936387752781,74.99717139513008],[-62.44046860998914,75.00073689358435],[-62.985115364477565,75.11722591645595],[-63.51928606785155,75.31691397958907],[-63.64288486720879,75.52488932122031],[-64.1242392273263,75.5921799154749],[-64.58761243996756,75.53593567213079],[-65.31057987327657,75.42103306523184],[-65.99461388511591,75.4041967649632],[-66.28964875049822,75.41792163747078],[-68.76453492310549,75.13410011250316],[-71.04622564987365,74.79937286637706],[-73.5067977908339,75.97399646374085],[-74.5601685819203,76.43273848659732],[-74.5601685819203,82.6959322619224],[-12.86174239943403,82.6959322619224],[-11.878165975221727,82.54102593940235],[-10.7797834094343,82.51187042401891],[-10.7797834094343,78.34458993192563],[-10.838211677734567,78.32665786610472],[-12.549216515959552,77.9578508228317],[-12.803493182847879,77.85845362808246],[-12.916087338718654,77.65848905807152],[-13.070950321133406,77.52877948776312],[-13.47955419255021,77.40221679143431],[-14.13060832134256,77.30552053875587],[-14.69541342101231,77.14674387861214],[-14.882617750618206,76.84736003108713],[-14.323648701941867,76.53205658256601],[-12.810144796765599,76.24823964501138],[-12.151831546734856,75.86267532270129],[-12.987745033472448,75.38717284756257],[-14.066766809859267,74.8451997920592],[-15.423357647282502,74.4551642069618],[-17.28174157007599,74.24584688808936],[-19.113380020736102,73.72978765991853],[-20.062373344103577,73.11108267968514],[-20.162312506727517,72.6186060300425],[-19.85354831628143,72.0718529721276],[-19.943252248300748,71.55019790921727],[-20.918542646451737,70.67423312425346],[-21.379621573201593,70.27938590726379],[-21.725469254364587,70.05299977015657],[-21.93869730345768,69.92215619574657],[-22.463306498894173,69.6235894257334],[-23.059252433112615,69.5491649852365],[-23.860796144964162,69.34443527043162],[-24.74741743781591,68.93340370554307],[-25.481987646795183,68.76711754662492],[-25.815395630476477,68.51279831615729],[-26.344103298317982,68.32443780018751],[-27.449680541202035,68.19315579455328],[-28.42826258633533,67.66140945836786],[-29.237141834543507,67.60310787132272],[-30.062476147434136,67.41414423917192],[-31.96817868027385,66.21262359095492],[-33.33718066100074,65.93894291103432],[-33.86781919039464,65.7415652217968],[-34.94415141573626,65.29121928843726],[-36.438872573697054,65.22802281646563],[-36.716767002697864,65.14683055370199],[-36.97927615837815,64.90967633661491],[-37.473922616631825,64.38546237809376],[-38.95785728548117,62.7419538908273],[-39.61555442323402,61.96904156671025],[-40.549088272349444,60.92614046823071],[-41.17137829347243,60.43812852329213],[-42.07544989793619,60.311876129737485],[-42.734129957211564,60.001556976048406],[-43.335169388775576,59.78884556778711]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R047_S54_20160411T044330","name":"imagico.de OSM images for mapping: Heard Island coast","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R047_S54_20160411T044330&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160412T212111_R047_V20160411T044330_20160411T044330, 2016-04-12, channels 234 (true color), Recent image of Heard island with interior mostly cloud covered but mostly well visible coast","scaleExtent":[0,13],"polygon":[[[73.0689652102818,-53.2705500548086],[73.0689652102818,-52.8754896362687],[74.0885530577575,-52.8754896362687],[74.0885530577575,-53.2705500548086],[73.0689652102818,-53.2705500548086]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82280982013259LGN00","name":"imagico.de OSM images for mapping: Isla Londonderry","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82280982013259LGN00&z={zoom}&x={x}&y={-y}","description":"LC82280982013259LGN00, 2013-09-16, channel 654 (false color IR), A lot of very coarse coastlines could be improved here, much snow cover though so no use for glacier mapping","scaleExtent":[0,12],"polygon":[[[-72.2652065929688,-55.5594608405404],[-72.2652065929688,-54.178890106312],[-69.4910293325508,-54.178890106312],[-69.4910293325508,-55.5594608405404],[-72.2652065929688,-55.5594608405404]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-AST_L1T_00311162013112731_20150618142416_109190","name":"imagico.de OSM images for mapping: Leskov Island ASTER","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=AST_L1T_00311162013112731_20150618142416_109190&z={zoom}&x={x}&y={-y}","description":"AST_L1T_00311162013112731_20150618142416_109190, 2013-11-16, channels 12x (true color with estimated blue), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-28.2107470814065,-56.721108415345],[-28.2107470814065,-56.6249750430891],[-27.9696123096903,-56.6249750430891],[-27.9696123096903,-56.721108415345],[-28.2107470814065,-56.721108415345]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81991002015286LGN00","name":"imagico.de OSM images for mapping: Leskov Island Landsat","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81991002015286LGN00&z={zoom}&x={x}&y={-y}","description":"LC81991002015286LGN00, 2015-10-13, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-28.2277611728877,-56.7347696464053],[-28.2277611728877,-56.6007525373185],[-27.9690463710613,-56.6007525373185],[-27.9690463710613,-56.7347696464053],[-28.2277611728877,-56.7347696464053]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-ls_polar","name":"imagico.de OSM images for mapping: May 2013 off-nadir Landsat","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ls_polar&z={zoom}&x={x}&y={-y}","description":"LC80372442013137LGN01-LC80530012013137LGN01, 2013-05-17, channels 234 (true color), Only available image north of the regular Landsat limit, mostly with seasonal snow cover so difficult to interpret","scaleExtent":[0,10],"polygon":[[[-89.8315284119521,81.3934028410464],[-89.8315284119521,83.7045077508689],[-17.9663056823904,83.7045077508689],[-17.9663056823904,81.3934028410464],[-89.8315284119521,81.3934028410464]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80940622015159LGN00","name":"imagico.de OSM images for mapping: New Ireland","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80940622015159LGN00&z={zoom}&x={x}&y={-y}","description":"LC80940622015159LGN00, 2015-06-08, channels 234 (true color), Many missing islands in OSM (mostly mapped meanwhile)","scaleExtent":[0,14],"polygon":[[[150.388533766196,-2.80056783608088],[150.388533766196,-2.38339617820643],[150.833478309574,-2.38339617820643],[150.833478309574,-2.80056783608088],[150.388533766196,-2.80056783608088]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-nellesmere_ast","name":"imagico.de OSM images for mapping: Northern Ellesmere Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=nellesmere_ast&z={zoom}&x={x}&y={-y}","description":"ASTER L1T, 2012-07-09/2012-07-15, channels 12x (true color with estimated blue), Assembled from July 2012 ASTER imagery","scaleExtent":[0,10],"polygon":[[[-83.0313625595429,82.4597689567848],[-83.0313625595429,83.0958397705009],[-65.6583851391606,83.0958397705009],[-65.6583851391606,82.4597689567848],[-83.0313625595429,82.4597689567848]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81960222015233LGN00vis","name":"imagico.de OSM images for mapping: Northern German west coast tidalflats","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00vis&z={zoom}&x={x}&y={-y}","description":"LC81960222015233LGN00, 2015-08-21 channels 134 (true color), Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals","scaleExtent":[0,12],"polygon":[[[7.63567991501593,53.2802190281286],[7.63567991501593,55.502457780526],[9.20773166222509,55.502457780526],[9.20773166222509,53.2802190281286],[7.63567991501593,53.2802190281286]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81960222015233LGN00ir","name":"imagico.de OSM images for mapping: Northern German west coast tidalflats (infrared)","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81960222015233LGN00ir&z={zoom}&x={x}&y={-y}","description":"LC81960222015233LGN00, 2015-08-21 channel 654 (false color IR), Up-to-date low tide imagery of the coast for updating mapping of tidalflats and shoals","scaleExtent":[0,12],"polygon":[[[7.63567991501593,53.2802190281286],[7.63567991501593,55.502457780526],[9.20773166222509,55.502457780526],[9.20773166222509,53.2802190281286],[7.63567991501593,53.2802190281286]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-ngreenland_ast","name":"imagico.de OSM images for mapping: Northern Greenland ASTER","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ngreenland_ast&z={zoom}&x={x}&y={-y}","description":"ASTER L1T, 2005-06-21 to 2012-08-13, channels 12x (true color with estimated blue), Assembled from mostly 2012 ASTER imagery, some 2005 images mainly in the northeast","scaleExtent":[0,10],"polygon":[[[-52.49221819431,82.4897991404581],[-52.49221819431,83.7321400994933],[-21.1842327268577,83.7321400994933],[-21.1842327268577,82.4897991404581],[-52.49221819431,82.4897991404581]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-EO1A1350972013086110KF","name":"imagico.de OSM images for mapping: Northwest Heard Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A1350972013086110KF&z={zoom}&x={x}&y={-y}","description":"EO1A1350972013086110KF, 2013-03-13, channels 973 (false color IR), Glaciers of Northwest Heard Island (mapped meanwhile)","scaleExtent":[0,13],"polygon":[[[73.2279041335011,-53.2033655831056],[73.2279041335011,-52.9494391381048],[73.7898811920934,-52.9494391381048],[73.7898811920934,-53.2033655831056],[73.2279041335011,-53.2033655831056]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R111_N09_20160604T154554","name":"imagico.de OSM images for mapping: Panama Canal","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R111_N09_20160604T154554&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160607T121312_R111_V20160604T154554_20160604T154554, 2016-06-07, channels 234 (true color), Images of the new locks (but partly cloudy)","scaleExtent":[0,14],"polygon":[[[-80.0165356176622,8.84894832639322],[-80.0165356176622,9.41480707574399],[-79.4685632943493,9.41480707574399],[-79.4685632943493,8.84894832639322],[-80.0165356176622,8.84894832639322]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81511242016033LGN00","name":"imagico.de OSM images for mapping: Pensacola Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81511242016033LGN00&z={zoom}&x={x}&y={-y}","description":"LC81511242016033LGN00/LC81511232016033LGN00, 2016-02-02, channels 234 (true color), Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox","scaleExtent":[0,10],"polygon":[[[-60.6153778814062,-84.1252820431153],[-60.6153778814062,-82.299687854391],[-44.5135525206644,-82.299687854391],[-44.5135525206644,-84.1252820431153],[-60.6153778814062,-84.1252820431153]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R136_N41_20150831T093006","name":"imagico.de OSM images for mapping: Prokletije Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R136_N41_20150831T093006&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160316T034950_R136_V20150831T093006_20150831T093006, 2015-08-31, channels 234 (true color), Late summer imagery where usual sources are severely limited by clouds and snow","scaleExtent":[0,14],"polygon":[[[19.0842590534772,42.1531616550022],[19.0842590534772,43.0960297809089],[20.6378953373619,43.0960297809089],[20.6378953373619,42.1531616550022],[19.0842590534772,42.1531616550022]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-DMS_1142622_03746_20110415_17533956","name":"imagico.de OSM images for mapping: Qasigiannguit","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=DMS_1142622_03746_20110415_17533956&z={zoom}&x={x}&y={-y}","description":"DMS_1142622_03746_20110415_17533956, 2011-04-15, true color, Icebridge DMS image of the settlement - alignment might be poor","scaleExtent":[0,15],"polygon":[[[-51.2433353705628,68.7997259148871],[-51.2433353705628,68.8530261295114],[-51.140370472697,68.8530261295114],[-51.140370472697,68.7997259148871],[-51.2433353705628,68.7997259148871]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81510432015030LGN00","name":"imagico.de OSM images for mapping: Rann of Kutch","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81510432015030LGN00&z={zoom}&x={x}&y={-y}","description":"various Landsat early 2015, channel 654 (false color IR), Land/water distinction difficult to properly map based on Bing/Mapbox images","scaleExtent":[0,12],"polygon":[[[67.8623118572194,22.3626187997331],[67.8623118572194,24.8869308169273],[71.4900144016907,24.8869308169273],[71.4900144016907,22.3626187997331],[67.8623118572194,22.3626187997331]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R093_N41_20150828T092005","name":"imagico.de OSM images for mapping: Rila and Pirin Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R093_N41_20150828T092005&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160412T121341_R093_V20150828T092005_20150828T092005, 2015-08-28, channels 234 (true color), Late summer imagery where usual sources are severely limited by clouds and snow","scaleExtent":[0,14],"polygon":[[[22.9923796970391,41.5848941590232],[22.9923796970391,42.2998374736026],[23.9940012388324,42.2998374736026],[23.9940012388324,41.5848941590232],[22.9923796970391,41.5848941590232]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81730602015040LGN00","name":"imagico.de OSM images for mapping: Rwenzori Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81730602015040LGN00&z={zoom}&x={x}&y={-y}","description":"LC81730602015040LGN00, 2015-02-09, channel 654 (false color IR), Recent image of most of the remaining Rwenzori Mountains glaciers","scaleExtent":[0,13],"polygon":[[[29.7662967768464,0.20687257729646],[29.7662967768464,0.509176367154027],[30.0346684679771,0.509176367154027],[30.0346684679771,0.20687257729646],[29.7662967768464,0.20687257729646]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80611072014036LGN00","name":"imagico.de OSM images for mapping: Scott Island","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80611072014036LGN00&z={zoom}&x={x}&y={-y}","description":"LC80611072014036LGN00, 2014-02-05, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-180,-67.4263452022474],[-180,-67.3252448474477],[-179.824753575046,-67.3252448474477],[-179.824753575046,-67.4263452022474],[-180,-67.4263452022474]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82100972015347LGN00","name":"imagico.de OSM images for mapping: Shag Rocks","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82100972015347LGN00&z={zoom}&x={x}&y={-y}","description":"LC82100972015347LGN00, 2015-12-13, channels 234 (true color), Missing in other image sources","scaleExtent":[0,13],"polygon":[[[-42.1462581850356,-53.7205050698923],[-42.1462581850356,-53.4458622334244],[-41.6557780399063,-53.4458622334244],[-41.6557780399063,-53.7205050698923],[-42.1462581850356,-53.7205050698923]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81130622013270LGN00","name":"imagico.de OSM images for mapping: Southeastern Sulawesi","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81130622013270LGN00&z={zoom}&x={x}&y={-y}","description":"LC81130622013270LGN00, 2013-09-27, channels 234 (true color), Missing islands and coarse coastline due to cloud cover in Bing, lakes could also use additional detail","scaleExtent":[0,13],"polygon":[[[120.843824420484,-3.59549835456283],[120.843824420484,-2.51468168634705],[122.626180758858,-2.51468168634705],[122.626180758858,-3.59549835456283],[120.843824420484,-3.59549835456283]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80281222016035LGN00","name":"imagico.de OSM images for mapping: Southern Transantarctic Mountains","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80281222016035LGN00&z={zoom}&x={x}&y={-y}","description":"LC80281222016035LGN00/LC80281212016035LGN00, 2016-02-04, channels 234 (true color), Outside regular Landsat coverage and therefore not in LIMA and Bing/Mapbox","scaleExtent":[0,10],"polygon":[[[154.508575968435,-84.5010049969839],[154.508575968435,-82.5848702651189],[177.005570718893,-82.5848702651189],[177.005570718893,-84.5010049969839],[154.508575968435,-84.5010049969839]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-DMS_1142636_160xx_20110507_1822xxxx","name":"imagico.de OSM images for mapping: Thule Air Base","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=DMS_1142636_160xx_20110507_1822xxxx&z={zoom}&x={x}&y={-y}","description":"DMS_1142636_16001_20110507_18221638-DMS_1142636_16076_20110507_18224996, 2011-05-07, true color, Icebridge DMS image - alignment might be poor","scaleExtent":[0,15],"polygon":[[[-68.9397691752981,76.5113260720978],[-68.9397691752981,76.5517569988038],[-68.5074010458985,76.5517569988038],[-68.5074010458985,76.5113260720978],[-68.9397691752981,76.5113260720978]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC80910682014358LGN00","name":"imagico.de OSM images for mapping: Vanatinai","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC80910682014358LGN00&z={zoom}&x={x}&y={-y}","description":"LC80910682014358LGN00, 2014-12-24, channels 234 (true color), Coarse coastline due to cloud cover in Bing/Mapbox","scaleExtent":[0,13],"polygon":[[[153.061381062565,-11.7892410342423],[153.061381062565,-11.0722925205757],[154.411998092239,-11.0722925205757],[154.411998092239,-11.7892410342423],[153.061381062565,-11.7892410342423]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC82330892016031LGN00","name":"imagico.de OSM images for mapping: Volcán Calbuco","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC82330892016031LGN00&z={zoom}&x={x}&y={-y}","description":"LC82330892016031LGN00, 2016-01-31, channels 234 (true color), Image from after the 2015 eruption","scaleExtent":[0,13],"polygon":[[[-72.8669610523419,-41.5174389446875],[-72.8669610523419,-41.045274923011],[-71.8751580966041,-41.045274923011],[-71.8751580966041,-41.5174389446875],[-72.8669610523419,-41.5174389446875]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-LC81490352013282LGN00","name":"imagico.de OSM images for mapping: Western Karakoram","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=LC81490352013282LGN00&z={zoom}&x={x}&y={-y}","description":"LC81490352013282LGN00, 2013-10-09, channels 234 (true color), Represents approximately minimum snow cover so can be well used for glacier mapping","scaleExtent":[0,13],"polygon":[[[73.9309166917002,34.9688073863467],[73.9309166917002,37.0985693236903],[76.5270029470414,37.0985693236903],[76.5270029470414,34.9688073863467],[73.9309166917002,34.9688073863467]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R039_S15_20160510T145731","name":"imagico.de OSM images for mapping: Willkanuta Mountains and Quelccaya Ice Cap","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R039_S15_20160510T145731&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160511T025410_R039_V20160510T145731_20160510T150701, 2016-05-10, channels 234 (true color), Poor and outdated imagery in other sources","scaleExtent":[0,14],"polygon":[[[-71.1807064830626,-14.4978825528812],[-71.1807064830626,-13.7102928800508],[-70.5563773605996,-13.7102928800508],[-70.5563773605996,-14.4978825528812],[-71.1807064830626,-14.4978825528812]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"bartholomew_qi1940","name":"Ireland Bartholomew Quarter-Inch 1940","type":"tms","template":"http://geo.nls.uk/maps/ireland/bartholomew/{zoom}/{x}/{-y}.png","scaleExtent":[5,13],"polygon":[[[-8.8312773,55.3963337],[-7.3221271,55.398605],[-7.2891331,55.4333162],[-7.2368042,55.4530757],[-7.18881,55.4497995],[-7.1528144,55.3968384],[-6.90561,55.394903],[-6.9047153,55.3842114],[-5.8485282,55.3922956],[-5.8378629,55.248676],[-5.3614762,55.2507024],[-5.3899172,53.8466464],[-5.8734141,53.8487436],[-5.8983,52.8256258],[-6.0191742,52.8256258],[-6.0262844,51.7712367],[-8.1131422,51.7712367],[-8.1273627,51.3268839],[-10.6052842,51.3091083],[-10.6271879,52.0328254],[-10.6469845,52.0322454],[-10.6469845,52.0440365],[-10.6271879,52.0448095],[-10.6290733,52.0745627],[-10.6699234,52.0743695],[-10.6702376,52.0876941],[-10.6312729,52.0898179],[-10.6393128,52.4147202],[-10.3137689,52.4185533],[-10.3166401,53.3341342],[-10.3699669,53.3330727],[-10.385965,54.3534472],[-8.8163777,54.3586265],[-8.8173427,54.6595721],[-8.8413398,54.6616284],[-8.8422286,54.6929749],[-8.8315632,54.7145436],[-8.8151208,54.7145436],[-8.8312773,55.3963337]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"GSGS3906","name":"Ireland British War Office 1:25k GSGS 3906","type":"tms","template":"http://mapwarper.net/layers/tile/101/{zoom}/{x}/{y}.png","scaleExtent":[0,18],"polygon":[[[-10.71,51.32],[-10.71,55.46],[-5.37,55.46],[-5.37,51.32],[-10.71,51.32]]],"terms_url":"http://wiki.openstreetmap.org/wiki/WikiProject_Ireland#Trinity_College_Dublin","terms_text":"Glucksman Map Library, Trinity College Dublin"},{"id":"GSGS4136","name":"Ireland British War Office One-Inch 1941-43 GSGS 4136","type":"tms","template":"http://geo.nls.uk/maps/ireland/gsgs4136/{zoom}/{x}/{-y}.png","scaleExtent":[5,15],"polygon":[[[-10.0847426,51.4147902],[-10.0906535,51.5064103],[-10.4564222,51.5003961],[-10.5005905,52.3043019],[-10.0837522,52.312741],[-10.0840973,52.3404698],[-10.055802,52.3408915],[-10.0768509,52.7628238],[-9.7780248,52.7684611],[-9.7818205,52.8577261],[-9.6337877,52.8596012],[-9.6449626,53.1294502],[-10.0919663,53.1227152],[-10.1051422,53.3912913],[-10.4052593,53.3866349],[-10.4530828,54.193502],[-10.2998523,54.1974988],[-10.3149801,54.4669592],[-8.9276095,54.4853897],[-8.9339534,54.7546562],[-8.7773069,54.755501],[-8.7826749,55.0252208],[-8.9402974,55.0238221],[-8.9451773,55.2934155],[-7.528039,55.2970274],[-7.525599,55.3874955],[-7.0541955,55.3841691],[-7.0556595,55.2939712],[-6.3241545,55.2859128],[-6.3217146,55.3253556],[-6.1035807,55.3223016],[-6.1045566,55.2828557],[-5.7985836,55.2772968],[-5.8117595,55.0087135],[-5.656577,55.0056351],[-5.6721928,54.7355021],[-5.3618278,54.729585],[-5.3964755,54.1917889],[-5.855679,54.2017807],[-5.9220464,52.8524504],[-6.070885,52.8551025],[-6.1030927,52.1373337],[-6.8331336,52.1463183],[-6.8355736,52.0578908],[-7.5641506,52.0617913],[-7.5661026,51.7921593],[-8.147305,51.792763],[-8.146329,51.7033331],[-8.2912636,51.7027283],[-8.2897996,51.5227274],[-9.1174397,51.516958],[-9.1179277,51.4625685],[-9.3692452,51.4616564],[-9.3672933,51.4254613],[-10.0847426,51.4147902]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"gsi.go.jp","name":"Japan GSI ortho Imagery","type":"tms","template":"http://cyberjapandata.gsi.go.jp/xyz/ort/{zoom}/{x}/{y}.jpg","scaleExtent":[12,19],"polygon":[[[141.85546875,44.64911632343077],[140.2294921875,43.96909818325174],[138.955078125,41.80407814427237],[139.482421875,40.17887331434696],[138.8671875,38.30718056188316],[136.31835937499997,37.19533058280065],[132.1435546875,35.137879119634185],[128.935546875,33.35806161277885],[129.5068359375,32.47269502206151],[129.77050781249997,31.690781806136822],[130.2099609375,30.90222470517144],[131.220703125,30.78903675126116],[131.66015625,32.32427558887655],[132.71484375,32.879587173066305],[133.76953125,33.17434155100208],[136.7578125,33.87041555094183],[139.306640625,35.06597313798418],[140.888671875,35.17380831799959],[141.15234374999997,36.56260003738548],[142.11914062499997,39.9434364619742],[141.767578125,42.68243539838623],[141.85546875,44.64911632343077]]]},{"id":"Aargau-AGIS-2011","name":"Kanton Aargau 25cm (AGIS 2011)","type":"tms","template":"http://tiles.poole.ch/AGIS/OF2011/{zoom}/{x}/{y}.png","scaleExtent":[14,19],"polygon":[[[7.7,47.12],[7.7,47.63],[8.5,47.63],[8.5,47.12],[7.7,47.12]]],"terms_text":"AGIS OF2011"},{"id":"Aargau-AGIS-2014","name":"Kanton Aargau 25cm (AGIS 2014)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/AGIS2014/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,19],"polygon":[[[8.222923278808594,47.604774168947614],[8.244209289550781,47.613569753973955],[8.294334411621094,47.60986653003798],[8.300857543945312,47.58625231278527],[8.329353332519531,47.569808674020344],[8.382568359375,47.56702895728551],[8.398017883300781,47.57490443821351],[8.424797058105469,47.56795554592218],[8.415184020996094,47.54663986006874],[8.389778137207031,47.5262428287156],[8.372268676757812,47.51233121261258],[8.358535766601562,47.503286684046664],[8.36402893066406,47.48078455918],[8.371238708496094,47.481016589036074],[8.373985290527344,47.47011007802331],[8.368148803710938,47.46825342516445],[8.387031555175781,47.44852243794931],[8.380851745605469,47.447593738482304],[8.384284973144531,47.4355191531953],[8.376388549804688,47.431803338643334],[8.377761840820312,47.42808726171425],[8.389434814453125,47.42739046807988],[8.391494750976562,47.41902822496511],[8.380165100097656,47.40462347023052],[8.364715576171875,47.4016026187529],[8.367118835449219,47.39881398671558],[8.380851745605469,47.39788440990287],[8.39424133300781,47.39439835079049],[8.399734497070312,47.372314620566925],[8.40728759765625,47.37068703239024],[8.404197692871094,47.34417352612498],[8.416213989257812,47.33416935720614],[8.414497375488281,47.32602502961836],[8.452606201171875,47.33254059215931],[8.444023132324219,47.31927592106609],[8.427543640136719,47.29925625338924],[8.390121459960938,47.28854494625744],[8.41175079345703,47.247076403108416],[8.393898010253906,47.227728840642065],[8.404884338378906,47.194845099780174],[8.401451110839844,47.17757880776958],[8.409690856933594,47.17314466448546],[8.412437438964844,47.13976002139446],[8.379478454589844,47.13929295458033],[8.361968994140625,47.14559801038333],[8.342742919921875,47.177112073280966],[8.3056640625,47.24987305653909],[8.295021057128906,47.26268916206698],[8.300514221191406,47.26991141830738],[8.278884887695312,47.28225686421767],[8.259315490722656,47.285983225286174],[8.243522644042969,47.280859411143915],[8.240432739257812,47.27130916053537],[8.228759765625,47.27270686584952],[8.219146728515625,47.25336866567523],[8.204727172851562,47.245444953748034],[8.203353881835938,47.22679624955806],[8.180007934570312,47.22143353240336],[8.171768188476562,47.2279619858493],[8.155975341796875,47.23961793870555],[8.175888061523436,47.24218190428504],[8.17657470703125,47.25406775981567],[8.136062622070312,47.24730946320093],[8.12164306640625,47.24218190428504],[8.10791015625,47.2447457457832],[8.097267150878906,47.259427174956194],[8.077354431152344,47.2603591917818],[8.059844970703125,47.25569894358661],[8.062591552734375,47.24614415248379],[8.016586303710938,47.242881146090085],[8.015899658203125,47.258961160390896],[7.997016906738281,47.2796948387185],[7.951698303222655,47.274337475394645],[7.960968017578125,47.25430078914495],[7.933845520019531,47.237053849043896],[7.911529541015624,47.24381345414034],[7.859344482421875,47.23425651880584],[7.83977508544922,47.23425651880584],[7.826042175292968,47.24427960201268],[7.828102111816407,47.25966018070071],[7.82398223876953,47.26548499105541],[7.8408050537109375,47.273405704663965],[7.848701477050781,47.28551744450745],[7.860374450683594,47.30461109337307],[7.871704101562499,47.31136207506936],[7.8888702392578125,47.31136207506936],[7.897453308105469,47.31904317780638],[7.895393371582031,47.327653995607086],[7.908439636230469,47.340451266106996],[7.9259490966796875,47.332773275955894],[7.94757843017578,47.331609846720866],[7.94757843017578,47.316715688820764],[8.007316589355467,47.33905535093827],[8.004913330078125,47.34533667855891],[8.011093139648438,47.35719936945847],[8.024139404296875,47.36719917429931],[8.032722473144531,47.38393878966209],[8.026885986328125,47.39602520707679],[8.010749816894531,47.3955603961201],[8.004570007324219,47.40671472747142],[7.975730895996094,47.41507892620099],[7.9657745361328125,47.42181578692778],[7.985343933105469,47.425764580393924],[7.971954345703124,47.46105827584221],[7.957534790039062,47.457344265054225],[7.940711975097656,47.46221885041022],[7.946891784667968,47.48403288391224],[7.907066345214844,47.48588897929538],[7.8936767578125,47.50653361720931],[7.873420715332031,47.51325876844644],[7.875480651855468,47.52253342509336],[7.865180969238281,47.51975120023913],[7.856254577636718,47.533660849056794],[7.833251953125,47.5325018525392],[7.834281921386719,47.51465007145751],[7.789649963378906,47.49377665301097],[7.789649963378906,47.518128167602484],[7.7515411376953125,47.52461999690649],[7.731285095214843,47.53203824675999],[7.708969116210937,47.54015075619555],[7.740898132324219,47.54362716173679],[7.761497497558593,47.54895720250044],[7.781410217285156,47.55289644950155],[7.797546386718749,47.55915229204993],[7.805442810058593,47.56563904359584],[7.814369201660155,47.575136052077276],[7.819175720214843,47.58648387645128],[7.8325653076171875,47.586715439092906],[7.843208312988281,47.581620824334166],[7.859344482421875,47.58602074809481],[7.8847503662109375,47.58764167941513],[7.903633117675781,47.58092606572345],[7.911872863769532,47.56749225365282],[7.90740966796875,47.55776216936179],[7.917709350585938,47.545712894408624],[7.929382324218749,47.54640812019053],[7.941741943359374,47.54432241518175],[7.9520416259765625,47.54965238525127],[7.9561614990234375,47.55683540041267],[7.9767608642578125,47.55544521625339],[7.997360229492187,47.556603705614094],[8.019676208496094,47.54965238525127],[8.049888610839844,47.55637200979099],[8.058815002441406,47.56285910557121],[8.072891235351562,47.56355410390809],[8.086967468261719,47.557067094186735],[8.100700378417969,47.56216409801383],[8.105506896972656,47.57976811421671],[8.113059997558594,47.583473468887405],[8.133659362792969,47.58301031389572],[8.138809204101562,47.59042030203756],[8.15185546875,47.59551406038282],[8.166275024414062,47.5941249027327],[8.177261352539062,47.6017648134425],[8.193740844726562,47.616346999837226],[8.2012939453125,47.62120682516921],[8.219490051269531,47.61958693358351],[8.223953247070312,47.61102381568743],[8.222923278808594,47.604774168947614]]],"terms_text":"AGIS OF2014","best":true},{"id":"KTBASELSTADT2015","name":"Kanton Basel-Stadt 2015","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTBASELSTADT2015/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[7.492,47.4817],[7.492,47.6342],[7.784,47.6342],[7.784,47.4817],[7.492,47.4817]]],"terms_text":"Kanton Basel-Stadt OF 2015"},{"id":"Solothurn-sogis2014-tms","name":"Kanton Solothurn 25cm (SOGIS 2014-2015)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/sogis2014/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[12,19],"polygon":[[[7.3404127,47.2175697],[7.4154818,47.2402115],[7.4173645,47.2537956],[7.4658424,47.2646513],[7.4946766,47.2882287],[7.5328638,47.294534],[7.5483333,47.3163566],[7.5709479,47.3263111],[7.5604584,47.342492],[7.5388991,47.3476266],[7.5396485,47.3601134],[7.5217459,47.3651488],[7.5237238,47.3720704],[7.4634937,47.3702566],[7.4361035,47.3781317],[7.4434011,47.4023143],[7.4774682,47.4012772],[7.4792364,47.3897076],[7.5022557,47.384807],[7.5213659,47.3912021],[7.5311724,47.4035251],[7.5252352,47.4116329],[7.5807413,47.414704],[7.5682954,47.4223349],[7.5689044,47.436897],[7.5812069,47.4287807],[7.6157989,47.4327479],[7.6260723,47.4629139],[7.6044949,47.4704455],[7.6072998,47.4893984],[7.640966,47.4827341],[7.6559259,47.4873946],[7.6521711,47.4958144],[7.6661209,47.4968682],[7.6683266,47.4863467],[7.699761,47.4806325],[7.709878,47.4693848],[7.6848538,47.4478436],[7.6798021,47.417514],[7.6327228,47.4100311],[7.633317,47.382914],[7.6417611,47.3804694],[7.6442033,47.3672084],[7.7279138,47.3688589],[7.751519,47.3443275],[7.7935609,47.3390523],[7.8021665,47.3610959],[7.8788122,47.3835105],[7.8691367,47.3955143],[7.883332,47.4060973],[7.9097377,47.398521],[7.9550377,47.4156057],[7.9618317,47.4218343],[7.9467846,47.4431934],[7.9682836,47.4628082],[7.9872707,47.4287435],[7.9854653,47.4227641],[7.9827035,47.4283325],[7.9631993,47.4223547],[8.0072617,47.4065858],[8.0100022,47.395418],[8.0265612,47.3956224],[8.0313669,47.3836856],[8.0038366,47.3453146],[8.0051906,47.3367516],[7.9479701,47.3171432],[7.9478307,47.3325169],[7.9192088,47.3339507],[7.9078055,47.341719],[7.889098,47.3114878],[7.8611018,47.3061239],[7.8418057,47.2744707],[7.8166423,47.2616706],[7.8028241,47.2684079],[7.7861469,47.256098],[7.7746009,47.267869],[7.7568187,47.258095],[7.7326672,47.2591133],[7.684769,47.2939919],[7.6482742,47.2819898],[7.5801066,47.2763483],[7.5936981,47.2662199],[7.5959384,47.245569],[7.6261802,47.2263143],[7.6405558,47.2297944],[7.6484666,47.2189525],[7.6472258,47.2017823],[7.6715278,47.1949714],[7.6711002,47.1845216],[7.6779881,47.1819259],[7.6728612,47.1683945],[7.6600808,47.1684026],[7.6451021,47.1489207],[7.6155322,47.1565739],[7.5861404,47.1475453],[7.5810534,47.16013],[7.5634674,47.1683541],[7.5257686,47.162205],[7.5203336,47.1588879],[7.5297508,47.1487369],[7.5097234,47.1255457],[7.4613252,47.1082327],[7.4750945,47.0867101],[7.454461,47.074927],[7.4354156,47.0801664],[7.4340002,47.1005003],[7.3820271,47.0957398],[7.3704914,47.1209312],[7.4401788,47.1237276],[7.4217922,47.1358605],[7.447783,47.1550805],[7.4728074,47.1525609],[7.4970383,47.1700873],[7.4804964,47.171738],[7.4708545,47.181324],[7.4757226,47.1906485],[7.4497638,47.1895691],[7.4476258,47.1810839],[7.4332849,47.1847269],[7.4118135,47.1624212],[7.3842442,47.1601249],[7.3821749,47.1651186],[7.391911,47.1662739],[7.3835137,47.1803011],[7.3654609,47.1944525],[7.3544799,47.1915316],[7.3404127,47.2175697]],[[7.420816,47.4803666],[7.4349836,47.4981011],[7.4707584,47.480734],[7.487277,47.4820136],[7.5116652,47.5026958],[7.5317892,47.4973989],[7.5366964,47.4850517],[7.5274454,47.4739062],[7.5306791,47.4611886],[7.4565122,47.4492558],[7.445214,47.4623781],[7.4557367,47.4733767],[7.420816,47.4803666]],[[7.3759458,47.4140995],[7.3821514,47.4330266],[7.4209041,47.4459442],[7.4378427,47.4463232],[7.4555765,47.4279232],[7.4437574,47.413444],[7.3759458,47.4140995]],[[7.6744234,47.1539707],[7.6853662,47.1662986],[7.7007985,47.1617746],[7.6901531,47.1525567],[7.6744234,47.1539707]]],"terms_text":"Orthofoto WMS Solothurn","best":true},{"id":"KTZUERICH2015","name":"Kanton Zürich 2015 10cm","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTZUERICH2015/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[8.807601928710938,47.66608099332474],[8.808631896972656,47.65475043477393],[8.830604553222656,47.648506014952225],[8.805885314941406,47.597597727711346],[8.749580383300781,47.61565270219988],[8.751983642578125,47.59505101193038],[8.807945251464844,47.585789182379905],[8.811721801757812,47.57467282332527],[8.840904235839844,47.57467282332527],[8.854637145996094,47.56216409801383],[8.8330078125,47.55382328811835],[8.845024108886719,47.53458802782819],[8.899612426757812,47.52786561031842],[8.895835876464844,47.491224888201955],[8.902702331542969,47.48588897929538],[8.887252807617188,47.475911695481756],[8.911285400390625,47.43969913094723],[8.934288024902344,47.43807362350206],[8.935317993164062,47.43017758727173],[8.917121887207031,47.42808726171425],[8.909912109375,47.404855836246135],[8.944587707519531,47.38905261221537],[8.945274353027344,47.379521907289295],[8.963127136230469,47.357664518690434],[8.973083496093748,47.35580389715929],[8.989906311035156,47.31857768821123],[8.973426818847656,47.30367985581531],[8.9593505859375,47.300653220457775],[8.941154479980469,47.2873805430142],[8.950080871582031,47.28458587064588],[8.940467834472656,47.259194168186234],[8.876266479492188,47.24847474828181],[8.876609802246092,47.243114224640834],[8.850173950195312,47.23961793870555],[8.849830627441406,47.247076403108416],[8.825111389160156,47.24824169331652],[8.800048828125,47.24031721435106],[8.804855346679688,47.23425651880584],[8.815155029296875,47.217702626593784],[8.793525695800781,47.21886856286133],[8.71490478515625,47.20021050593422],[8.685722351074219,47.18154588528182],[8.697395324707031,47.163108130899104],[8.660659790039062,47.15633823511178],[8.6572265625,47.16684287656919],[8.618087768554688,47.172444502751944],[8.622550964355469,47.17991241867412],[8.607101440429688,47.201376826785406],[8.595085144042969,47.19834433924206],[8.575859069824219,47.21513747655813],[8.541183471679688,47.2186353776589],[8.471488952636719,47.2053421258966],[8.441619873046875,47.22120035848172],[8.417243957519531,47.22120035848172],[8.383941650390625,47.292270864380086],[8.422050476074219,47.302282968719936],[8.442306518554688,47.32439601339355],[8.413810729980469,47.32299967378833],[8.408660888671875,47.33067908487908],[8.378448486328125,47.39718721653071],[8.360939025878906,47.39695481668995],[8.359222412109375,47.4053205652024],[8.379135131835938,47.40764414848437],[8.377418518066406,47.41624051540972],[8.384284973144531,47.42274494145051],[8.372611999511719,47.42808726171425],[8.372955322265625,47.437376962080776],[8.379478454589844,47.45037978769006],[8.36402893066406,47.46198673754625],[8.352012634277344,47.5079250985124],[8.373985290527344,47.517200697839414],[8.392181396484375,47.5366741201253],[8.417587280273436,47.56610235225701],[8.430290222167967,47.5693453981427],[8.491744995117188,47.581620824334166],[8.487625122070312,47.58648387645128],[8.463935852050781,47.58301031389572],[8.453292846679688,47.60315376826432],[8.479385375976562,47.617504142079596],[8.505821228027344,47.61958693358351],[8.513717651367188,47.635783590864854],[8.542213439941406,47.632776019724375],[8.545646667480469,47.627685889602006],[8.564186096191406,47.6256034207548],[8.566932678222656,47.61935551640258],[8.576202392578125,47.613569753973955],[8.564872741699219,47.60037582174319],[8.535346984863281,47.586715439092906],[8.550109863281248,47.5714301073211],[8.555259704589844,47.55498181333744],[8.581008911132812,47.59551406038282],[8.598861694335936,47.61449551898437],[8.59130859375,47.64642437575518],[8.609848022460938,47.65521295468833],[8.620834350585938,47.646886969413],[8.618431091308594,47.65660048985082],[8.602981567382812,47.666312203609145],[8.610877990722656,47.67856488312544],[8.62323760986328,47.67856488312544],[8.621864318847656,47.69312564683551],[8.64898681640625,47.697516190510555],[8.667526245117188,47.68665469810477],[8.671646118164062,47.67602211074509],[8.692245483398438,47.65197522925437],[8.734817504882812,47.64526787368664],[8.777389526367188,47.65313158281113],[8.785629272460938,47.667930646923494],[8.807601928710938,47.66608099332474]]],"terms_text":"Kanton Zürich OF 2015","best":true},{"id":"kelowna_2012","name":"Kelowna 2012","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/kelowna2012/{zoom}/{x}/{y}.png","description":"High quality aerial imagery taken for the City of Kelowna","scaleExtent":[9,20],"polygon":[[[-119.5867318,49.7928087],[-119.5465655,49.7928097],[-119.5465661,49.8013837],[-119.5343374,49.8013841],[-119.5343376,49.8047321],[-119.5296211,49.8047322],[-119.5296216,49.8119555],[-119.5104463,49.811956],[-119.5115683,49.8744325],[-119.5108946,49.8744904],[-119.5114111,49.8843312],[-119.5114115,49.9221763],[-119.49386,49.9223477],[-119.4940505,49.9313031],[-119.4803936,49.9317529],[-119.4804572,49.9407474],[-119.4666732,49.9409927],[-119.4692775,49.9913717],[-119.4551337,49.9916078],[-119.4556736,50.0121242],[-119.4416673,50.0123895],[-119.4417308,50.0136345],[-119.4221492,50.0140377],[-119.4221042,50.0119306],[-119.4121303,50.012165],[-119.4126082,50.0216913],[-119.4123387,50.0216913],[-119.4124772,50.0250773],[-119.4120917,50.0250821],[-119.4121954,50.0270769],[-119.4126083,50.0270718],[-119.4128328,50.0321946],[-119.3936313,50.0326418],[-119.393529,50.0307781],[-119.3795727,50.0310116],[-119.3795377,50.0287584],[-119.3735764,50.0288621],[-119.371544,49.9793618],[-119.3573506,49.9793618],[-119.3548353,49.9256081],[-119.3268079,49.9257238],[-119.3256573,49.8804068],[-119.3138893,49.8806528],[-119.3137097,49.8771651],[-119.3132156,49.877223],[-119.3131482,49.8749652],[-119.312452,49.8749073],[-119.3122275,49.87236],[-119.3117558,49.872331],[-119.3115986,49.8696098],[-119.3112169,49.8694217],[-119.3109199,49.8632417],[-119.3103721,49.8632724],[-119.3095139,49.8512388],[-119.3106368,49.8512316],[-119.3103859,49.8462564],[-119.3245344,49.8459957],[-119.3246018,49.8450689],[-119.3367018,49.844875],[-119.3367467,49.8435136],[-119.337937,49.8434702],[-119.3378023,49.8382055],[-119.3383637,49.8381041],[-119.3383749,49.8351202],[-119.3390936,49.8351058],[-119.3388016,49.8321217],[-119.3391497,49.8320565],[-119.3391722,49.8293331],[-119.3394641,49.8293331],[-119.3395879,49.8267878],[-119.3500053,49.8265829],[-119.3493701,49.8180588],[-119.4046964,49.8163785],[-119.4045694,49.8099022],[-119.4101592,49.8099022],[-119.4102862,49.8072787],[-119.4319467,49.8069098],[-119.4322643,49.7907965],[-119.4459847,49.7905504],[-119.445286,49.7820201],[-119.4967376,49.7811587],[-119.4966105,49.7784927],[-119.5418371,49.7775082],[-119.5415892,49.7718277],[-119.5560296,49.7714941],[-119.5561194,49.7718422],[-119.5715704,49.7715086],[-119.5716153,49.7717262],[-119.5819235,49.7714941],[-119.5820133,49.7717697],[-119.5922991,49.7715231],[-119.592344,49.7718132],[-119.6003839,49.7715957],[-119.6011924,49.7839081],[-119.5864365,49.7843863],[-119.5867318,49.7928087]]]},{"id":"kelowna_roads","name":"Kelowna Roads overlay","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/kelowna_overlay/{zoom}/{x}/{y}.png","scaleExtent":[9,20],"polygon":[[[-119.5867318,49.7928087],[-119.5465655,49.7928097],[-119.5465661,49.8013837],[-119.5343374,49.8013841],[-119.5343376,49.8047321],[-119.5296211,49.8047322],[-119.5296216,49.8119555],[-119.5104463,49.811956],[-119.5115683,49.8744325],[-119.5108946,49.8744904],[-119.5114111,49.8843312],[-119.5114115,49.9221763],[-119.49386,49.9223477],[-119.4940505,49.9313031],[-119.4803936,49.9317529],[-119.4804572,49.9407474],[-119.4666732,49.9409927],[-119.4692775,49.9913717],[-119.4551337,49.9916078],[-119.4556736,50.0121242],[-119.4416673,50.0123895],[-119.4417308,50.0136345],[-119.4221492,50.0140377],[-119.4221042,50.0119306],[-119.4121303,50.012165],[-119.4126082,50.0216913],[-119.4123387,50.0216913],[-119.4124772,50.0250773],[-119.4120917,50.0250821],[-119.4121954,50.0270769],[-119.4126083,50.0270718],[-119.4128328,50.0321946],[-119.3936313,50.0326418],[-119.393529,50.0307781],[-119.3795727,50.0310116],[-119.3795377,50.0287584],[-119.3735764,50.0288621],[-119.371544,49.9793618],[-119.3573506,49.9793618],[-119.3548353,49.9256081],[-119.3268079,49.9257238],[-119.3256573,49.8804068],[-119.3138893,49.8806528],[-119.3137097,49.8771651],[-119.3132156,49.877223],[-119.3131482,49.8749652],[-119.312452,49.8749073],[-119.3122275,49.87236],[-119.3117558,49.872331],[-119.3115986,49.8696098],[-119.3112169,49.8694217],[-119.3109199,49.8632417],[-119.3103721,49.8632724],[-119.3095139,49.8512388],[-119.3106368,49.8512316],[-119.3103859,49.8462564],[-119.3245344,49.8459957],[-119.3246018,49.8450689],[-119.3367018,49.844875],[-119.3367467,49.8435136],[-119.337937,49.8434702],[-119.3378023,49.8382055],[-119.3383637,49.8381041],[-119.3383749,49.8351202],[-119.3390936,49.8351058],[-119.3388016,49.8321217],[-119.3391497,49.8320565],[-119.3391722,49.8293331],[-119.3394641,49.8293331],[-119.3395879,49.8267878],[-119.3500053,49.8265829],[-119.3493701,49.8180588],[-119.4046964,49.8163785],[-119.4045694,49.8099022],[-119.4101592,49.8099022],[-119.4102862,49.8072787],[-119.4319467,49.8069098],[-119.4322643,49.7907965],[-119.4459847,49.7905504],[-119.445286,49.7820201],[-119.4967376,49.7811587],[-119.4966105,49.7784927],[-119.5418371,49.7775082],[-119.5415892,49.7718277],[-119.5560296,49.7714941],[-119.5561194,49.7718422],[-119.5715704,49.7715086],[-119.5716153,49.7717262],[-119.5819235,49.7714941],[-119.5820133,49.7717697],[-119.5922991,49.7715231],[-119.592344,49.7718132],[-119.6003839,49.7715957],[-119.6011924,49.7839081],[-119.5864365,49.7843863],[-119.5867318,49.7928087]]],"overlay":true},{"id":"landsat_233055","name":"Landsat 233055","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/landsat_233055/{zoom}/{x}/{y}.png","description":"Recent Landsat imagery","scaleExtent":[5,14],"polygon":[[[-60.8550011,6.1765004],[-60.4762612,7.9188291],[-62.161689,8.2778675],[-62.5322549,6.5375488],[-60.8550011,6.1765004]]]},{"id":"landsat_047026","name":"Latest southwest British Columbia Landsat","type":"tms","template":"http://{switch:a,b,c,d}.tile.paulnorman.ca/landsat_047026/{zoom}/{x}/{y}.png","description":"Recent lower-resolution landsat imagery for southwest British Columbia","scaleExtent":[5,13],"polygon":[[[-121.9355512,47.7820648],[-121.5720582,48.6410125],[-121.2015461,49.4846247],[-121.8375516,49.6023246],[-122.4767046,49.7161735],[-123.118912,49.8268824],[-123.760228,49.9335836],[-124.0887706,49.0870469],[-124.4128889,48.2252567],[-123.792772,48.1197334],[-123.1727942,48.0109592],[-122.553553,47.8982299],[-121.9355512,47.7820648]]]},{"id":"ORT10LT","name":"Lithuania - NŽT ORT10LT","type":"tms","template":"http://mapproxy.openmap.lt/ort10lt/g/{zoom}/{x}/{y}.jpeg","scaleExtent":[4,18],"polygon":[[[26.2138385,55.850748],[26.3858298,55.7045315],[26.6303618,55.6806692],[26.6205349,55.5689227],[26.5242191,55.5099228],[26.5541476,55.388833],[26.4399286,55.3479351],[26.7919694,55.3212027],[26.8291304,55.2763488],[26.7434625,55.2539863],[26.6764846,55.158828],[26.4611191,55.1285624],[26.3577434,55.1505399],[26.2296342,55.1073177],[26.2713814,55.0775905],[26.2085126,54.997414],[26.0619117,54.9416094],[25.8578176,54.9276001],[25.7429827,54.8150641],[25.7626083,54.5769013],[25.5319352,54.3418175],[25.6771618,54.3238109],[25.7857293,54.2336242],[25.7858844,54.1550594],[25.5550843,54.1461918],[25.5109462,54.1750267],[25.5896725,54.2285838],[25.5136246,54.3078472],[25.2689287,54.2744706],[25.0705963,54.1336282],[24.9573726,54.1720575],[24.8133801,54.144862],[24.7790172,54.0999054],[24.8712786,54.034904],[24.819568,53.9977218],[24.6845912,53.9621091],[24.697865,54.0171421],[24.6259068,54.0105048],[24.4342619,53.9014424],[24.3520594,53.8967893],[24.2016059,53.9700069],[23.9683341,53.9266977],[23.9130177,53.9696842],[23.7781192,53.8989169],[23.7097655,53.9394502],[23.5370435,53.9430702],[23.4822428,53.9893848],[23.5273356,54.0473482],[23.4858579,54.1532339],[23.3867851,54.224838],[23.0421216,54.3159745],[23.0102115,54.3827959],[22.8546899,54.4104029],[22.7919963,54.3633227],[22.7023421,54.4528985],[22.6838586,54.585972],[22.7489713,54.6319792],[22.7429727,54.7268221],[22.8866837,54.8135001],[22.8204005,54.9119829],[22.6424041,54.9713362],[22.5892361,55.070243],[22.080597,55.0244812],[22.0324081,55.084098],[21.9130671,55.0816838],[21.6491949,55.1808113],[21.5015124,55.1868198],[21.3843708,55.2936996],[21.2709829,55.2450059],[21.0983616,55.2563884],[20.9421741,55.282453],[21.0863466,55.5618266],[21.0399547,55.8363584],[21.0640261,56.0699542],[21.2047804,56.0811668],[21.2307958,56.1623302],[21.5021038,56.2954952],[21.7235874,56.3138211],[21.8356623,56.37162],[21.9695397,56.3766515],[22.0153001,56.4242811],[22.4372717,56.406405],[22.6800028,56.3515884],[22.9191739,56.3790184],[22.9466759,56.4146477],[23.0932498,56.3046383],[23.1703443,56.3667721],[23.3064522,56.3830535],[23.5571715,56.3338187],[23.7647953,56.3733238],[23.7666897,56.3238079],[24.0189971,56.3297615],[24.1214631,56.2488984],[24.2857421,56.3006367],[24.4541496,56.2581579],[24.5794651,56.2882389],[24.6284061,56.3753322],[24.9023767,56.4805317],[25.1277405,56.2059091],[25.5771398,56.182414],[25.6731232,56.1493667],[26.2138385,55.850748]]],"terms_url":"http://www.geoportal.lt","terms_text":"NŽT ORT10LT","best":true},{"id":"mapbox_locator_overlay","name":"Locator Overlay","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/openstreetmap.map-inh76ba2/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","description":"Shows major features to help orient you.","scaleExtent":[0,16],"overzoom":false,"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true,"overlay":true},{"id":"NSW_LPI_BaseMap","name":"LPI NSW Base Map","type":"tms","template":"https://maps.six.nsw.gov.au/arcgis/rest/services/public/NSW_Base_Map/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,19],"polygon":[[[140.9948644,-28.952966],[148.9611382,-28.8997729],[148.9870097,-28.4862285],[151.013609,-28.4786485],[151.1084711,-28.7032909],[151.8759917,-28.683118],[151.9334839,-28.4078753],[152.25544,-28.2332683],[153.0660798,-28.2104723],[153.1408196,-28.1090981],[153.4735137,-28.1164808],[153.3576523,-27.693606],[159.4938303,-27.699252],[159.4856997,-37.8474137],[149.5256879,-37.8281502],[149.9159578,-37.4869999],[148.0485886,-36.8131741],[147.9680996,-36.1567945],[146.7147701,-36.2866613],[145.3004625,-36.1567945],[144.5300673,-36.1475101],[142.8397973,-35.0254303],[142.356863,-34.7802471],[141.9774146,-34.4016159],[140.9950258,-34.1371824],[140.9948644,-28.952966]]],"terms_url":"http://spatialservices.finance.nsw.gov.au/mapping_and_imagery/lpi_web_services","terms_text":"© Land and Property Information 2016"},{"id":"NSW_LPI_Imagery","name":"LPI NSW Imagery","type":"tms","template":"https://maps.six.nsw.gov.au/arcgis/rest/services/public/NSW_Imagery/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,21],"polygon":[[[140.9868688,-28.9887829],[148.9951472,-28.9727491],[148.9966717,-28.4915066],[151.0029027,-28.4930697],[151.0029027,-28.7261663],[151.4915093,-28.7323921],[151.4918687,-28.7155337],[151.9228213,-28.719635],[151.9251607,-28.4897139],[151.9955886,-28.4898718],[151.9989947,-28.1192742],[152.4967606,-28.122091],[152.4968241,-28.1146398],[153.0044563,-28.1154389],[153.0044563,-28.120397],[153.5038629,-28.119345],[153.5039264,-28.1227063],[153.5919395,-28.1223619],[153.5926582,-28.1776872],[153.6111186,-28.1757867],[153.6113881,-28.1825173],[153.7426846,-28.2162084],[153.7787253,-28.710911],[152.6237954,-32.5877239],[152.3123961,-32.6328837],[151.4141942,-33.5790388],[150.8929925,-35.2648721],[150.4620695,-35.7777256],[150.0156501,-37.5103569],[149.9918121,-37.5126787],[149.519778,-37.5130704],[149.5199577,-37.5216919],[149.4462958,-37.5353701],[149.063344,-37.5357975],[148.9836635,-37.5217631],[148.9816872,-37.5191982],[148.9863847,-37.2584972],[148.4875376,-37.265846],[148.4824774,-37.0092669],[147.994386,-37.014339],[147.988288,-36.5332184],[147.9529707,-36.5260725],[147.9486513,-36.0685992],[147.5034997,-36.0716798],[147.5047701,-36.2651047],[146.4919996,-36.266129],[146.4922536,-36.2565],[145.9929826,-36.2534267],[145.9965866,-36.0188147],[145.9831568,-36.0187058],[145.9624506,-36.0219026],[145.946236,-36.0120936],[145.9454275,-36.0060259],[145.5041534,-36.0013564],[145.5037941,-36.0109125],[145.0072008,-36.0036213],[145.0035404,-36.1520424],[144.4860806,-36.1423149],[144.4874127,-36.0137522],[143.9874676,-36.0024134],[143.9932853,-35.5723753],[143.4971691,-35.5837101],[143.4917967,-35.4065648],[143.4613438,-35.3674934],[143.4585591,-35.3555888],[143.4897755,-35.3396522],[143.4895509,-35.332214],[143.4316994,-35.2570613],[143.2505542,-35.2606556],[143.2438356,-35.0132729],[142.9933305,-35.0177207],[142.9919767,-34.7961882],[142.4971375,-34.8032323],[142.4973172,-34.8007613],[142.4211401,-34.8017571],[142.4209155,-34.7838306],[142.2330892,-34.7859191],[142.2307707,-34.7807542],[142.2269959,-34.5061271],[141.9975302,-34.5083733],[141.9945959,-34.2526687],[141.4982345,-34.2556921],[141.498171,-34.2522794],[140.9945397,-34.2528411],[140.9868688,-28.9887829]]],"terms_url":"http://spatialservices.finance.nsw.gov.au/mapping_and_imagery/lpi_web_services","terms_text":"© Land and Property Information 2016","best":true},{"id":"NSW_LPI_TopographicMap","name":"LPI NSW Topographic Map","type":"tms","template":"https://maps.six.nsw.gov.au/arcgis/rest/services/public/NSW_Topo_Map/MapServer/tile/{zoom}/{y}/{x}","scaleExtent":[0,16],"polygon":[[[140.9988422,-28.9992444],[148.9502438,-28.9993736],[148.9498845,-28.9665265],[148.9998308,-28.9665265],[149.0000917,-28.8165829],[149.1000729,-28.8165829],[149.0997046,-28.7488533],[148.9998504,-28.7497444],[148.9998169,-28.5000304],[151.0000514,-28.5005192],[151.0005904,-28.7325849],[151.0239466,-28.7327424],[151.0241262,-28.7418794],[151.0329297,-28.7418794],[151.033828,-28.7505431],[151.999984,-28.7495314],[151.999984,-28.7164478],[152.0334014,-28.7166053],[152.0332217,-28.683196],[152.0000739,-28.6833537],[151.9998769,-28.6416273],[151.9829886,-28.6413908],[151.9831683,-28.624912],[151.9331321,-28.6247543],[151.9334122,-28.500071],[151.9998875,-28.5002289],[151.9998556,-28.3749591],[152.2499739,-28.3750718],[152.2499356,-28.2500066],[152.9997192,-28.2498563],[152.9998989,-28.2832447],[153.1165002,-28.2834029],[153.11659,-28.2498563],[153.1666262,-28.2500146],[153.166716,-28.2331582],[153.2499898,-28.2332373],[153.2500265,-28.1249689],[153.6249628,-28.1250833],[153.6248398,-28.4999134],[153.7497955,-28.4999924],[153.7495877,-28.7497976],[153.6248117,-28.7501127],[153.6249745,-28.9999333],[153.4997672,-29.0000612],[153.4998417,-29.4995077],[153.3747962,-29.500055],[153.3754111,-29.8750302],[153.4999113,-29.8751403],[153.4999113,-30.0000922],[153.2498947,-29.9997621],[153.250025,-30.1917704],[153.2748185,-30.1916151],[153.2748185,-30.2168467],[153.2166077,-30.2166139],[153.2166077,-30.250065],[153.250025,-30.250065],[153.2497502,-30.3751935],[153.1243608,-30.3749743],[153.1246457,-30.6250359],[153.0331676,-30.6250482],[153.0333884,-30.8750837],[153.1249214,-30.8750291],[153.1249344,-31.1250505],[153.0082433,-31.1249736],[153.0082914,-31.2499759],[153.0000019,-31.250003],[152.9999392,-31.6249919],[152.8749386,-31.6250491],[152.8749572,-31.749954],[152.7832899,-31.7500034],[152.7831966,-31.8748579],[152.749914,-31.8750105],[152.7500397,-32.0000207],[152.6249044,-31.9999446],[152.6249078,-32.5000047],[152.4999757,-32.4999569],[152.5000336,-32.5666443],[152.4166699,-32.5663415],[152.4167598,-32.6249954],[152.3498477,-32.624991],[152.3498477,-32.6332294],[152.2830786,-32.6332218],[152.2832583,-32.6249755],[152.2494816,-32.6249755],[152.2498101,-32.874906],[151.8745693,-32.8750443],[151.8748535,-33.0000091],[151.7497706,-33.0001533],[151.7504669,-33.2500398],[151.6252418,-33.2497393],[151.6250828,-33.3751621],[151.499585,-33.3751442],[151.5003127,-33.6249385],[151.3741466,-33.6243658],[151.3727902,-34.001962],[151.2477819,-34.0011194],[151.2477819,-34.2493114],[150.9957327,-34.2501515],[151.0008143,-34.62483],[150.8717407,-34.6265026],[150.872757,-35.1242738],[150.7670589,-35.1234425],[150.7690916,-35.2463774],[150.6257894,-35.2496974],[150.6280314,-35.3751485],[150.4999742,-35.3751485],[150.4959088,-35.6275034],[150.3719169,-35.6250251],[150.3749658,-35.7537957],[150.2672351,-35.7513213],[150.2652024,-35.8741232],[150.2479249,-35.870829],[150.2458922,-36.374885],[150.1229166,-36.374885],[150.1259656,-36.6224345],[150.0253491,-36.6240658],[150.0283981,-36.7471337],[149.9928266,-36.7495768],[150.0040062,-37.1224477],[150.0588879,-37.1273097],[150.0568553,-37.37809],[149.9979083,-37.3732441],[149.9999409,-37.4830073],[149.987745,-37.4846202],[149.9857123,-37.5080043],[148.0684571,-36.80624],[147.9930603,-36.1379955],[147.8148345,-36.0055567],[147.3893924,-36.0113701],[147.3822059,-36.1310306],[146.9972549,-36.1275479],[146.9886311,-36.2528271],[146.4956356,-36.2447132],[146.5042595,-36.126387],[145.0011817,-36.0079505],[145.0154103,-36.2542074],[144.5072465,-36.2476506],[144.4991158,-36.0211037],[143.9965422,-35.9810531],[143.3382568,-35.2331794],[142.4097581,-34.7669434],[142.0361436,-34.3758837],[140.9965216,-34.1385805],[140.9988422,-28.9992444]]],"terms_url":"http://spatialservices.finance.nsw.gov.au/mapping_and_imagery/lpi_web_services","terms_text":"© Land and Property Information 2016"},{"id":"lu.geoportail.opendata.basemap","name":"Luxembourg Geoportail Basemap","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/basemap/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/carte-de-base-webservices-wms-et-wmts/","terms_text":"Administration du Cadastre et de la Topographie"},{"id":"lu.geoportail.opendata.cadastre","name":"Luxembourg Geoportail Cadastre","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/cadastre/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/plan-cadastral-numerise-pcn-webservices-wms-et-wmts/","terms_text":"Administration du Cadastre et de la Topographie"},{"id":"lu.geoportail.opendata.ortho2010","name":"Luxembourg Geoportail Ortho 2010","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2010/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/bd-l-ortho-webservices-wms-et-wmts","terms_text":"Administration du Cadastre et de la Topographie","best":true},{"id":"lu.geoportail.opendata.ortho2013","name":"Luxembourg Geoportail Ortho 2013","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2013/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.jpeg","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/bd-l-ortho-webservices-wms-et-wmts","terms_text":"Administration du Cadastre et de la Topographie","best":true},{"id":"lu.geoportail.opendata.topo","name":"Luxembourg Geoportail Topographical Map","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/topo/GLOBAL_WEBMERCATOR_4_V3/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[5.961753,50.17631],[6.026268,50.18496],[6.033182,50.16395],[6.060695,50.15536],[6.07668,50.15913],[6.078237,50.17255],[6.101762,50.17199],[6.122501,50.16437],[6.120101,50.15594],[6.127695,50.14993],[6.113228,50.13739],[6.123691,50.13719],[6.140929,50.1305],[6.135554,50.11899],[6.138082,50.10263],[6.131085,50.09964],[6.135473,50.09119],[6.121939,50.09059],[6.126335,50.07817],[6.131858,50.07348],[6.121171,50.064],[6.114444,50.06139],[6.115631,50.05817],[6.123611,50.06323],[6.136608,50.04178],[6.130343,50.02975],[6.148207,50.02307],[6.13868,50.01572],[6.135938,50.01485],[6.131384,50.01905],[6.130243,50.01819],[6.139343,50.01116],[6.151702,50.01058],[6.145464,49.99689],[6.139657,49.9994],[6.138524,49.99829],[6.142178,49.99535],[6.150227,49.99518],[6.156247,49.98867],[6.173045,49.98589],[6.17348,49.98344],[6.170353,49.98376],[6.165487,49.97115],[6.171512,49.96298],[6.176298,49.962],[6.179954,49.95386],[6.183393,49.9548],[6.179829,49.96307],[6.183312,49.9686],[6.192774,49.97158],[6.199783,49.95352],[6.207066,49.95672],[6.212689,49.9514],[6.225023,49.95039],[6.22044,49.94369],[6.228241,49.93726],[6.22635,49.92766],[6.219133,49.92354],[6.229862,49.92125],[6.236032,49.91355],[6.231867,49.91064],[6.227694,49.91062],[6.232286,49.9072],[6.23381,49.90028],[6.246919,49.89535],[6.257809,49.88724],[6.263008,49.88101],[6.276455,49.87725],[6.281126,49.87957],[6.291661,49.87548],[6.297699,49.86673],[6.309889,49.87107],[6.315324,49.8673],[6.314651,49.86057],[6.323611,49.85188],[6.321577,49.8409],[6.327406,49.83673],[6.336561,49.83998],[6.339366,49.8507],[6.364651,49.85164],[6.402203,49.82098],[6.426434,49.81629],[6.428071,49.81186],[6.43097,49.81129],[6.441608,49.81547],[6.443442,49.81233],[6.45366,49.81275],[6.464538,49.81975],[6.47057,49.82385],[6.496805,49.81277],[6.50669,49.80993],[6.511554,49.80238],[6.51485,49.80513],[6.519604,49.81446],[6.529808,49.81048],[6.532249,49.80686],[6.530829,49.80116],[6.506225,49.78899],[6.519171,49.78344],[6.511055,49.77422],[6.520563,49.76818],[6.520516,49.76134],[6.503734,49.75086],[6.502627,49.73298],[6.507266,49.72938],[6.518092,49.7242],[6.516417,49.72129],[6.511763,49.72016],[6.504791,49.725],[6.498913,49.72639],[6.495576,49.72443],[6.507122,49.71655],[6.507884,49.71215],[6.504598,49.71227],[6.427139,49.66237],[6.439899,49.66025],[6.442511,49.65591],[6.421781,49.61809],[6.398978,49.60094],[6.379408,49.59526],[6.375507,49.58809],[6.384426,49.5801],[6.381188,49.57509],[6.369093,49.5783],[6.357913,49.57166],[6.384902,49.55817],[6.380095,49.54856],[6.358555,49.53296],[6.359322,49.52481],[6.370763,49.50545],[6.370562,49.45732],[6.333403,49.46493],[6.321894,49.47244],[6.295034,49.47928],[6.287889,49.48379],[6.271912,49.49995],[6.241327,49.50693],[6.196692,49.50331],[6.173373,49.50577],[6.160858,49.50085],[6.167099,49.49006],[6.140179,49.48525],[6.129367,49.48803],[6.127247,49.47081],[6.101403,49.46726],[6.104826,49.45076],[6.081667,49.45417],[6.077222,49.46139],[6.059167,49.46306],[6.052222,49.46028],[6.044213,49.44553],[6.025294,49.44703],[6.021545,49.45127],[6.01574,49.44885],[5.994123,49.45301],[5.976569,49.44885],[5.977725,49.45955],[5.972317,49.46087],[5.968912,49.48202],[5.9616,49.49026],[5.915781,49.49835],[5.890334,49.4948],[5.863321,49.50006],[5.84897,49.50826],[5.84828,49.51397],[5.83641,49.51817],[5.831868,49.52639],[5.84308,49.53081],[5.835622,49.54114],[5.816251,49.53325],[5.805201,49.54272],[5.859432,49.57158],[5.868663,49.587],[5.862888,49.58525],[5.851102,49.58379],[5.847116,49.58961],[5.845652,49.5981],[5.869401,49.6106],[5.881819,49.63815],[5.899978,49.63907],[5.899339,49.66239],[5.856561,49.67628],[5.856283,49.68211],[5.875703,49.71118],[5.864811,49.72331],[5.843249,49.71822],[5.82191,49.72128],[5.824894,49.73767],[5.820728,49.74878],[5.786264,49.79079],[5.765172,49.78961],[5.750937,49.79094],[5.741591,49.82126],[5.745814,49.82435],[5.737197,49.83353],[5.740531,49.84142],[5.747012,49.84048],[5.746237,49.84783],[5.753989,49.84878],[5.740663,49.85152],[5.752288,49.85922],[5.749545,49.87554],[5.775668,49.87438],[5.775053,49.88057],[5.734598,49.89341],[5.733033,49.90285],[5.757834,49.91737],[5.760393,49.93252],[5.770728,49.93711],[5.768783,49.94239],[5.768802,49.96104],[5.786724,49.96816],[5.80524,49.96677],[5.806521,49.97321],[5.831293,49.97995],[5.834616,49.98656],[5.818057,49.99936],[5.815606,50.01437],[5.847923,50.02809],[5.861889,50.04581],[5.850872,50.0563],[5.857809,50.07186],[5.880997,50.08069],[5.891965,50.12041],[5.952856,50.13384],[5.961753,50.17631]]],"terms_url":"https://data.public.lu/en/datasets/cartes-topographiques-services-wms-et-wmts/","terms_text":"Administration du Cadastre et de la Topographie"},{"id":"Mapbox","name":"Mapbox Satellite","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/openstreetmap.map-inh7ifmo/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJncjlmd0t3In0.DmZsIeOW-3x-C5eX-wAqTw","description":"Satellite and aerial imagery.","scaleExtent":[0,19],"terms_url":"http://www.mapbox.com/about/maps/","terms_text":"Terms & Feedback","default":true},{"id":"geodata.md.gov-MD_SixInchImagery","name":"MD 2014 6 Inch Aerial Imagery","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/MD_SixInchImagery/http://geodata.md.gov/imap/services/Imagery/MD_SixInchImagery/MapServer/WmsServer","description":"Six Inch resolution aerial imagery for the State of Maryland","scaleExtent":[0,20],"polygon":[[[-76.234131,37.920368],[-76.598053,38.158317],[-76.940002,38.270532],[-77.038193,38.413786],[-77.23526,38.33627],[-77.312164,38.410558],[-77.262726,38.566422],[-77.042999,38.713376],[-77.049866,38.793697],[-76.92627,38.892503],[-77.040939,38.984499],[-77.12162,38.925229],[-77.150116,38.955137],[-77.252426,38.975425],[-77.259293,39.024252],[-77.34581,39.054918],[-77.461853,39.070379],[-77.537384,39.139647],[-77.474213,39.224807],[-77.572746,39.304284],[-77.723465,39.328986],[-77.777023,39.463234],[-77.861481,39.516225],[-77.840881,39.608862],[-77.956238,39.59299],[-78.166351,39.695564],[-78.270035,39.621557],[-78.338699,39.640066],[-78.466415,39.523641],[-78.662796,39.540058],[-78.798752,39.606217],[-78.9814,39.446799],[-79.06723,39.476486],[-79.485054,39.199536],[-79.485569,39.72158],[-75.788359,39.721811],[-75.690994,38.460579],[-75.049238,38.458159],[-75.049839,38.402218],[-75.081511,38.323208],[-75.097733,38.309066],[-75.186996,38.097551],[-75.23798,38.022402],[-75.61821,37.989669],[-75.863686,37.909534],[-76.234131,37.920368]]],"terms_url":"http://imap.maryland.gov/Pages/imagery-products.aspx","terms_text":"DoIT, MD iMap, MDP"},{"id":"geodata.md.gov-MD_ColorBasemap","name":"MD Transportation Basemap","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/MD_ColorBasemap/http://geodata.md.gov/imap/services/Transportation/MD_ColorBasemap/MapServer/WmsServer","description":"Maryland State Highway Administration road features and additional Maryland focused landmarks","polygon":[[[-76.234131,37.920368],[-76.598053,38.158317],[-76.940002,38.270532],[-77.038193,38.413786],[-77.23526,38.33627],[-77.312164,38.410558],[-77.262726,38.566422],[-77.042999,38.713376],[-77.049866,38.793697],[-76.92627,38.892503],[-77.040939,38.984499],[-77.12162,38.925229],[-77.150116,38.955137],[-77.252426,38.975425],[-77.259293,39.024252],[-77.34581,39.054918],[-77.461853,39.070379],[-77.537384,39.139647],[-77.474213,39.224807],[-77.572746,39.304284],[-77.723465,39.328986],[-77.777023,39.463234],[-77.861481,39.516225],[-77.840881,39.608862],[-77.956238,39.59299],[-78.166351,39.695564],[-78.270035,39.621557],[-78.338699,39.640066],[-78.466415,39.523641],[-78.662796,39.540058],[-78.798752,39.606217],[-78.9814,39.446799],[-79.06723,39.476486],[-79.485054,39.199536],[-79.485569,39.72158],[-75.788359,39.721811],[-75.690994,38.460579],[-75.049238,38.458159],[-75.049839,38.402218],[-75.081511,38.323208],[-75.097733,38.309066],[-75.186996,38.097551],[-75.23798,38.022402],[-75.61821,37.989669],[-75.863686,37.909534],[-76.234131,37.920368]]],"terms_url":"http://imap.maryland.gov/Pages/imagery-products.aspx","terms_text":"DoIT, MD iMap, MDP"},{"id":"New_and_Misaligned_TIGER_Roads-2013","name":"New & Misaligned TIGER Roads","type":"tms","template":"http://{switch:a,b,c}.tiles.mapbox.com/v4/enf.e0b8291e/{zoom}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJhNVlHd29ZIn0.ti6wATGDWOmCnCYen-Ip7Q","description":"At zoom level 16+, public domain map data from the US Census. At lower zooms, only changes since 2006 minus changes already incorporated into OpenStreetMap","scaleExtent":[0,22],"polygon":[[[-124.7617886,48.4130148],[-124.6059492,45.90245],[-124.9934269,40.0557614],[-122.5369737,36.8566086],[-119.9775867,33.0064099],[-117.675935,32.4630223],[-114.8612307,32.4799891],[-111.0089311,31.336015],[-108.1992687,31.3260016],[-108.1871123,31.7755116],[-106.5307225,31.7820947],[-106.4842052,31.7464455],[-106.429317,31.7520583],[-106.2868855,31.5613291],[-106.205248,31.446704],[-105.0205259,30.5360988],[-104.5881916,29.6997856],[-103.2518856,28.8908685],[-102.7173632,29.3920567],[-102.1513983,29.7475702],[-101.2552871,29.4810523],[-100.0062436,28.0082173],[-99.2351068,26.4475962],[-98.0109067,25.9928035],[-97.435024,25.8266009],[-96.9555259,25.9821589],[-96.8061741,27.7978168],[-95.5563349,28.5876066],[-93.7405308,29.4742093],[-90.9028456,28.8564513],[-88.0156706,28.9944338],[-88.0162494,30.0038862],[-86.0277506,30.0047454],[-84.0187909,28.9961781],[-81.9971976,25.9826768],[-81.9966618,25.0134917],[-84.0165592,25.0125783],[-84.0160068,24.0052745],[-80.0199985,24.007096],[-79.8901116,26.8550713],[-80.0245309,32.0161282],[-75.4147385,35.0531894],[-74.0211163,39.5727927],[-72.002019,40.9912464],[-69.8797398,40.9920457],[-69.8489304,43.2619916],[-66.9452845,44.7104937],[-67.7596632,47.0990024],[-69.2505131,47.5122328],[-70.4614886,46.2176574],[-71.412273,45.254878],[-72.0222508,45.0059846],[-75.0798841,44.9802854],[-76.9023061,43.8024568],[-78.7623935,43.6249578],[-79.15798,43.4462589],[-79.0060087,42.8005317],[-82.662475,41.6889458],[-82.1761642,43.588535],[-83.2813977,46.138853],[-87.5064535,48.0142702],[-88.3492194,48.2963271],[-89.4353148,47.9837822],[-93.9981078,49.0067142],[-95.1105379,49.412004],[-96.0131199,49.0060547],[-123.3228926,49.0042878],[-123.2275233,48.1849927],[-124.7617886,48.4130148]],[[-160.5787616,22.5062947],[-160.5782192,21.4984647],[-158.7470604,21.2439843],[-157.5083185,20.995803],[-155.9961942,18.7790194],[-154.6217803,18.7586966],[-154.6890176,19.8805722],[-156.2927622,21.2225888],[-157.5047384,21.9984962],[-159.0093692,22.5070181],[-160.5787616,22.5062947]],[[-167.1571546,68.721974],[-164.8553982,67.0255078],[-168.002195,66.0017503],[-169.0087448,66.001546],[-169.0075381,64.9987675],[-172.5143281,63.8767267],[-173.8197023,59.74014],[-162.5018149,58.0005815],[-160.0159024,58.0012389],[-160.0149725,57.000035],[-160.5054788,56.9999017],[-165.8092575,54.824847],[-178.000097,52.2446469],[-177.9992996,51.2554252],[-171.4689067,51.8215329],[-162.40251,53.956664],[-159.0075717,55.002502],[-158.0190709,55.0027849],[-151.9963213,55.9991902],[-151.500341,57.9987853],[-151.5012894,58.9919816],[-138.5159989,58.9953194],[-138.5150471,57.9986434],[-133.9948193,54.0031685],[-130.0044418,54.0043387],[-130.0070826,57.0000507],[-131.975877,56.9995156],[-135.1229873,59.756601],[-138.0071813,59.991805],[-139.1715881,60.4127229],[-140.9874011,61.0118551],[-140.9683975,69.9535069],[-156.176891,71.5633329],[-160.413634,70.7397728],[-163.0218273,69.9707435],[-164.9717003,68.994689],[-167.1571546,68.721974]]],"overlay":true},{"id":"geodata.state.nj.us-Infrared2015","name":"NJ 2015 Aerial Imagery (Infrared)","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/Infrared2015/http://geodata.state.nj.us/imagerywms/Infrared2015","description":"Digital orthophotography of New Jersey, Near Infrared, 1 foot resolution","scaleExtent":[0,20],"polygon":[[[-74.86599,40.085427],[-74.840927,40.107225],[-74.822903,40.130329],[-74.788055,40.124685],[-74.726086,40.149488],[-74.729176,40.16392],[-74.763336,40.191725],[-74.775524,40.214276],[-74.844017,40.247957],[-74.868393,40.291573],[-74.944611,40.33817],[-74.967098,40.395195],[-75.002632,40.406046],[-75.026836,40.402516],[-75.06134,40.416502],[-75.074215,40.455046],[-75.069065,40.536503],[-75.102367,40.567024],[-75.135927,40.573609],[-75.16777,40.559069],[-75.197639,40.573674],[-75.203733,40.618318],[-75.205064,40.691312],[-75.198326,40.753889],[-75.172405,40.780671],[-75.1367,40.777292],[-75.090179,40.822383],[-75.100994,40.839269],[-75.096874,40.850956],[-75.068464,40.850372],[-75.057049,40.867574],[-75.13773,40.973094],[-75.135155,40.994411],[-75.039024,41.03819],[-74.981518,41.112598],[-74.905472,41.170384],[-74.84024,41.278645],[-74.798012,41.322685],[-74.757156,41.347691],[-74.695702,41.360576],[-74.041054,41.059088],[-74.041051,41.059087],[-74.04105,41.059087],[-74.04105,41.059086],[-74.041049,41.059086],[-74.041049,41.059086],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-73.933408,40.882075],[-73.933408,40.882075],[-74.011459,40.75558],[-74.024543,40.709436],[-74.066048,40.651732],[-74.152222,40.638967],[-74.183121,40.644568],[-74.200459,40.631281],[-74.199257,40.598444],[-74.21505,40.558026],[-74.246807,40.548113],[-74.24715,40.519541],[-74.267578,40.489651],[-74.26054,40.469282],[-74.199257,40.445641],[-74.181061,40.460401],[-74.136429,40.459095],[-73.997555,40.413496],[-74.026566,40.47777],[-74.003906,40.484037],[-73.977814,40.452042],[-73.964767,40.33189],[-74.088364,39.756824],[-74.356842,39.383406],[-74.609528,39.215231],[-74.776382,38.998909],[-74.863586,38.931639],[-74.931221,38.920688],[-74.980316,38.930304],[-74.960747,39.00798],[-74.905472,39.100226],[-74.899979,39.164141],[-75.101166,39.201398],[-75.135498,39.171062],[-75.425949,39.378099],[-75.475044,39.43195],[-75.543365,39.457403],[-75.552292,39.482845],[-75.538902,39.541911],[-75.519676,39.56997],[-75.571175,39.608069],[-75.577698,39.625524],[-75.539932,39.656456],[-75.472984,39.747454],[-75.466253,39.750761],[-75.466252,39.750762],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466251,39.750764],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-75.466249,39.750769],[-75.466249,39.750769],[-75.465088,39.764478],[-75.415041,39.801786],[-75.324669,39.858891],[-75.246048,39.864689],[-75.143738,39.900255],[-75.142365,39.957912],[-75.07061,39.987117],[-75.056534,40.008683],[-74.935341,40.072555],[-74.86599,40.085427]]],"terms_url":"https://njgin.state.nj.us/NJ_NJGINExplorer/ShowMetadata.jsp?docId={E30775F2-6370-4525-8E68-C371ED29BBB3}","terms_text":"NJ Office of Information Technology (NJOIT), Office of Geographic Information Systems (OGIS)"},{"id":"geodata.state.nj.us-Natural2015","name":"NJ 2015 Aerial Imagery (Natural Color)","type":"tms","template":"http://whoots.mapwarper.net/tms/{zoom}/{x}/{y}/Natural2015/http://geodata.state.nj.us/imagerywms/Natural2015","description":"Digital orthophotography of New Jersey, Natural Color, 1 foot resolution","scaleExtent":[0,20],"polygon":[[[-74.86599,40.085427],[-74.840927,40.107225],[-74.822903,40.130329],[-74.788055,40.124685],[-74.726086,40.149488],[-74.729176,40.16392],[-74.763336,40.191725],[-74.775524,40.214276],[-74.844017,40.247957],[-74.868393,40.291573],[-74.944611,40.33817],[-74.967098,40.395195],[-75.002632,40.406046],[-75.026836,40.402516],[-75.06134,40.416502],[-75.074215,40.455046],[-75.069065,40.536503],[-75.102367,40.567024],[-75.135927,40.573609],[-75.16777,40.559069],[-75.197639,40.573674],[-75.203733,40.618318],[-75.205064,40.691312],[-75.198326,40.753889],[-75.172405,40.780671],[-75.1367,40.777292],[-75.090179,40.822383],[-75.100994,40.839269],[-75.096874,40.850956],[-75.068464,40.850372],[-75.057049,40.867574],[-75.13773,40.973094],[-75.135155,40.994411],[-75.039024,41.03819],[-74.981518,41.112598],[-74.905472,41.170384],[-74.84024,41.278645],[-74.798012,41.322685],[-74.757156,41.347691],[-74.695702,41.360576],[-74.041054,41.059088],[-74.041051,41.059087],[-74.04105,41.059087],[-74.04105,41.059086],[-74.041049,41.059086],[-74.041049,41.059086],[-73.890266,40.998039],[-73.933406,40.882078],[-73.933407,40.882077],[-73.933408,40.882076],[-73.933408,40.882075],[-73.933408,40.882075],[-74.011459,40.75558],[-74.024543,40.709436],[-74.066048,40.651732],[-74.152222,40.638967],[-74.183121,40.644568],[-74.200459,40.631281],[-74.199257,40.598444],[-74.21505,40.558026],[-74.246807,40.548113],[-74.24715,40.519541],[-74.267578,40.489651],[-74.26054,40.469282],[-74.199257,40.445641],[-74.181061,40.460401],[-74.136429,40.459095],[-73.997555,40.413496],[-74.026566,40.47777],[-74.003906,40.484037],[-73.977814,40.452042],[-73.964767,40.33189],[-74.088364,39.756824],[-74.356842,39.383406],[-74.609528,39.215231],[-74.776382,38.998909],[-74.863586,38.931639],[-74.931221,38.920688],[-74.980316,38.930304],[-74.960747,39.00798],[-74.905472,39.100226],[-74.899979,39.164141],[-75.101166,39.201398],[-75.135498,39.171062],[-75.425949,39.378099],[-75.475044,39.43195],[-75.543365,39.457403],[-75.552292,39.482845],[-75.538902,39.541911],[-75.519676,39.56997],[-75.571175,39.608069],[-75.577698,39.625524],[-75.539932,39.656456],[-75.472984,39.747454],[-75.466253,39.750761],[-75.466252,39.750762],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466252,39.750763],[-75.466251,39.750764],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.466251,39.750765],[-75.46625,39.750767],[-75.466249,39.750768],[-75.466249,39.750769],[-75.466249,39.750769],[-75.465088,39.764478],[-75.415041,39.801786],[-75.324669,39.858891],[-75.246048,39.864689],[-75.143738,39.900255],[-75.142365,39.957912],[-75.07061,39.987117],[-75.056534,40.008683],[-74.935341,40.072555],[-74.86599,40.085427]]],"terms_url":"https://njgin.state.nj.us/NJ_NJGINExplorer/ShowMetadata.jsp?docId={CDC67AB8-ADA1-4B4B-9087-67A82CB9151C}","terms_text":"NJ Office of Information Technology (NJOIT), Office of Geographic Information Systems (OGIS)"},{"id":"NLS-Bartholomew-hfinch-hist","name":"NLS - Bartholomew Half Inch, 1897-1907","type":"tms","template":"http://geo.nls.uk/mapdata2/bartholomew/great_britain/{zoom}/{x}/{-y}.png","scaleExtent":[0,15],"polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-7th_Series","name":"NLS - OS 1-inch 7th Series 1955-61","type":"tms","template":"http://geo.nls.uk/mapdata2/os/seventh/{zoom}/{x}/{-y}.png","scaleExtent":[5,16],"polygon":[[[-6.4585407,49.9044128],[-6.3872009,49.9841116],[-6.2296827,49.9896159],[-6.2171269,49.8680087],[-6.4551164,49.8591793],[-6.4585407,49.9044128]],[[-1.4495137,60.8634056],[-0.7167114,60.8545122],[-0.7349744,60.4359756],[-0.6938826,60.4168218],[-0.7258429,60.3942735],[-0.7395401,60.0484714],[-0.9267357,60.0461918],[-0.9381501,59.8266157],[-1.4586452,59.831205],[-1.4455187,60.0535999],[-1.463211,60.0535999],[-1.4643524,60.0630002],[-1.5716475,60.0638546],[-1.5693646,60.1790005],[-1.643558,60.1807033],[-1.643558,60.1892162],[-1.8216221,60.1894999],[-1.8204807,60.3615507],[-1.8415973,60.3697345],[-1.8216221,60.3832755],[-1.8179852,60.5934321],[-1.453168,60.5934321],[-1.4495137,60.8634056]],[[-4.9089213,54.4242078],[-4.282598,54.4429861],[-4.2535417,54.029769],[-4.8766366,54.0221831],[-4.9089213,54.4242078]],[[-5.8667408,59.1444603],[-5.7759966,59.1470945],[-5.7720016,59.1014052],[-5.8621751,59.0990605],[-5.8667408,59.1444603]],[[-1.7065887,59.5703599],[-1.5579165,59.5693481],[-1.5564897,59.4965695],[-1.7054472,59.4975834],[-1.7065887,59.5703599]],[[-7.6865827,58.2940975],[-7.5330594,58.3006957],[-7.5256401,58.2646905],[-7.6797341,58.2577853],[-7.6865827,58.2940975]],[[-4.5338281,59.0359871],[-4.481322,59.0371616],[-4.4796099,59.0186583],[-4.5332574,59.0180707],[-4.5338281,59.0359871]],[[-8.6710698,57.8769896],[-8.4673234,57.8897332],[-8.4467775,57.7907],[-8.6510947,57.7779213],[-8.6710698,57.8769896]],[[-5.2395519,50.3530581],[-5.7920073,50.3384899],[-5.760047,49.9317027],[-4.6551363,49.9581461],[-4.677965,50.2860073],[-4.244219,50.2801723],[-4.2487848,50.2042525],[-3.3812929,50.2042525],[-3.4223846,50.5188201],[-3.1164796,50.5246258],[-3.1210453,50.6579592],[-2.6736357,50.6619495],[-2.5953453,50.6394325],[-2.5905026,50.5728419],[-2.4791203,50.5733545],[-2.4758919,50.5066704],[-2.3967943,50.5056438],[-2.401637,50.5723293],[-1.0400296,50.5718167],[-1.0335726,50.7059289],[-0.549302,50.7038843],[-0.5460736,50.7886618],[-0.0924734,50.7856002],[-0.0876307,50.7181949],[0.4789659,50.7120623],[0.487037,50.8182467],[0.9761503,50.8049868],[0.9922927,51.0126311],[1.4491213,51.0004424],[1.4781775,51.4090372],[1.0229632,51.4271576],[1.035877,51.7640881],[1.6105448,51.7500992],[1.646058,52.1560003],[1.7267698,52.1540195],[1.749369,52.4481811],[1.7870672,52.4811624],[1.759102,52.522505],[1.7933451,52.9602749],[0.3798147,52.9958468],[0.3895238,53.2511239],[0.3478614,53.2511239],[0.3238912,53.282186],[0.3461492,53.6538501],[0.128487,53.6575466],[0.116582,53.6674703],[0.1350586,54.0655731],[-0.0609831,54.065908],[-0.0414249,54.4709448],[-0.5662701,54.4771794],[-0.5592078,54.6565127],[-1.1665638,54.6623485],[-1.1637389,54.842611],[-1.3316194,54.843909],[-1.3257065,55.2470842],[-1.529453,55.2487108],[-1.524178,55.6540122],[-1.7638798,55.6540122],[-1.7733693,55.9719116],[-2.1607858,55.9682981],[-2.1543289,56.0621387],[-2.4578051,56.0585337],[-2.4190635,56.641717],[-2.0962164,56.641717],[-2.0833025,57.0021322],[-1.9283359,57.0126802],[-1.9180966,57.3590895],[-1.7502161,57.3625721],[-1.7695869,57.7608634],[-3.6937554,57.7574187],[-3.7066693,57.9806386],[-3.5969013,57.9772149],[-3.6033582,58.1207277],[-3.0222335,58.1309566],[-3.0286905,58.5410788],[-2.8478961,58.530968],[-2.86081,58.8430508],[-2.679624,58.8414991],[-2.6841897,58.885175],[-2.6339665,58.9052239],[-2.679624,58.9335083],[-2.6887555,59.0229231],[-2.3668703,59.0229231],[-2.3702946,59.2652861],[-2.3429001,59.2821989],[-2.3714361,59.2996861],[-2.3737189,59.3707083],[-2.3429001,59.385825],[-2.3725775,59.400354],[-2.3714361,59.4259098],[-3.0734196,59.4230067],[-3.0711368,59.3433649],[-3.103097,59.3311405],[-3.0745611,59.3136695],[-3.0722782,59.232603],[-3.3850319,59.1484167],[-3.3747589,58.9352753],[-3.5653789,58.9323303],[-3.554829,58.69759],[-5.2808579,58.6667732],[-5.2534159,58.3514125],[-5.5068508,58.3437887],[-5.4761804,58.0323557],[-5.8974958,58.0212436],[-5.8522972,57.6171758],[-6.1396311,57.6137174],[-6.1541592,57.7423183],[-6.2913692,57.7380102],[-6.3365678,58.1398784],[-6.1121891,58.1466944],[-6.1473778,58.5106285],[-6.2934817,58.5416182],[-6.8413713,58.2977321],[-7.0057382,58.2929331],[-7.1016189,58.2064403],[-7.2573132,58.1793148],[-7.2531092,58.1004928],[-7.4070698,58.0905566],[-7.391347,57.7911354],[-7.790991,57.7733151],[-7.7624215,57.5444165],[-7.698501,57.1453194],[-7.7943817,57.1304547],[-7.716764,56.7368628],[-7.0122067,56.7654359],[-6.979922,56.5453858],[-7.0638622,56.5453858],[-7.0444914,56.3562587],[-6.500676,56.3812917],[-6.4491433,55.9793649],[-6.563287,55.9691456],[-6.5393742,55.7030135],[-6.5595521,55.6907321],[-6.5345315,55.6761713],[-6.5216176,55.5704434],[-5.8912587,55.5923416],[-5.8560127,55.2320733],[-5.2293639,55.2515958],[-5.1837064,54.6254139],[-3.6655956,54.6518373],[-3.6496155,54.4320023],[-3.5400375,54.4306744],[-3.530906,54.0290181],[-3.0697656,54.030359],[-3.0675737,53.8221388],[-3.0804876,53.7739911],[-3.0619239,53.7477488],[-3.0611168,53.6737049],[-3.2144691,53.6708361],[-3.2057699,53.4226163],[-3.2799632,53.355224],[-3.2896655,53.3608441],[-3.3327547,53.364931],[-3.3761293,53.3540318],[-4.0888976,53.3433102],[-4.0945474,53.4612036],[-4.697412,53.4448624],[-4.6882805,53.3318598],[-4.7202407,53.2895771],[-4.6837148,53.2486184],[-4.6768661,53.1542644],[-4.8480816,53.1446807],[-4.8178336,52.7440299],[-4.2545751,52.7558939],[-4.228876,52.254876],[-4.2607571,52.2536408],[-4.2724603,52.2432637],[-4.8136263,52.230095],[-4.8079191,52.1138892],[-5.3889104,52.0991668],[-5.3717888,51.9129667],[-5.4208706,51.9101502],[-5.414022,51.8453218],[-5.3683645,51.8474373],[-5.3466772,51.5595332],[-4.773676,51.5758518],[-4.7656859,51.4885146],[-4.1915432,51.4970427],[-4.1869775,51.4344663],[-3.6151177,51.4444274],[-3.6105519,51.3746543],[-3.1494115,51.3789292],[-3.1494115,51.2919281],[-4.3038735,51.2745907],[-4.2861169,51.0508721],[-4.8543277,51.0366633],[-4.8372201,50.7212787],[-5.2618345,50.7082694],[-5.2395519,50.3530581]],[[-2.1502671,60.171318],[-2.0030218,60.1696146],[-2.0013096,60.0997023],[-2.148555,60.1011247],[-2.1502671,60.171318]],[[-6.2086011,59.1163488],[-6.1229934,59.1166418],[-6.121852,59.0714985],[-6.2097426,59.0714985],[-6.2086011,59.1163488]],[[-4.4159559,59.0889036],[-4.4212022,59.0770848],[-4.3971904,59.0779143],[-4.3913388,59.0897328],[-4.4159559,59.0889036]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-1st_Series","name":"NLS - OS 1:25k 1st Series 1937-61","type":"tms","template":"http://geo.nls.uk/mapdata2/os/25000/{zoom}/{x}/{-y}.png","scaleExtent":[5,16],"polygon":[[[-4.7157244,54.6796556],[-4.6850662,54.6800268],[-4.6835779,54.6623245],[-4.7148782,54.6615818],[-4.7157244,54.6796556]],[[-3.7085748,58.3371151],[-3.5405937,58.3380684],[-3.5315137,58.1608002],[-3.3608086,58.1622372],[-3.3653486,58.252173],[-3.1610473,58.2536063],[-3.1610473,58.3261509],[-3.0275704,58.3271045],[-3.0366505,58.6139001],[-3.0021463,58.614373],[-3.0030543,58.7036341],[-3.4180129,58.7003322],[-3.4171049,58.6290293],[-3.7240109,58.6266658],[-3.7231029,58.606806],[-4.2361262,58.5992374],[-4.2334022,58.5092347],[-3.88836,58.5144516],[-3.8829119,58.4261327],[-3.7158389,58.4270836],[-3.7085748,58.3371151]],[[-6.46676,49.9943621],[-6.1889102,50.004868],[-6.1789222,49.8967815],[-6.3169391,49.8915171],[-6.312399,49.8200979],[-6.4504159,49.8159968],[-6.46676,49.9943621]],[[-5.6453263,50.2029809],[-5.7801329,50.2014076],[-5.7637888,50.0197267],[-5.3479221,50.0290604],[-5.3388421,49.9414854],[-5.024672,49.9473287],[-5.0355681,50.0383923],[-5.0010639,50.0453901],[-4.9974319,50.1304478],[-4.855783,50.13394],[-4.861231,50.206057],[-4.6546085,50.2140172],[-4.6558926,50.3018616],[-4.5184924,50.3026818],[-4.51464,50.325642],[-4.2488284,50.3264618],[-4.2488284,50.3100631],[-4.10886,50.3141633],[-4.1062917,50.2411267],[-3.9648088,50.2432047],[-3.9640778,50.2254158],[-3.8522287,50.2273626],[-3.8503757,50.1552563],[-3.6921809,50.1572487],[-3.5414602,50.1602198],[-3.5465781,50.3226814],[-3.4068012,50.3241013],[-3.4165761,50.5892711],[-3.2746691,50.5962721],[-3.2749172,50.6106323],[-2.9971742,50.613972],[-2.9896008,50.688537],[-2.7120266,50.690565],[-2.710908,50.6195964],[-2.5695473,50.6157538],[-2.5651019,50.5134083],[-2.4014463,50.513379],[-2.3940583,50.6160348],[-2.2894123,50.6147436],[-2.2876184,50.6008549],[-2.1477855,50.6048506],[-2.1451013,50.5325437],[-1.9335117,50.5347477],[-1.9362139,50.6170445],[-1.8573025,50.6228094],[-1.8554865,50.709139],[-1.6066929,50.709139],[-1.6085089,50.6239615],[-1.4450678,50.6228094],[-1.4432518,50.5317039],[-1.1545059,50.5293951],[-1.1472419,50.6170485],[-1.011041,50.6205051],[-1.011041,50.7056889],[-0.704135,50.7045388],[-0.700503,50.7769401],[-0.5860943,50.7723465],[-0.5879103,50.7907181],[-0.0149586,50.7798108],[-0.0185906,50.7625836],[0.0967261,50.7620093],[0.0921861,50.6913106],[0.3046595,50.6890096],[0.3101075,50.7757917],[0.5511831,50.7726336],[0.5529991,50.8432096],[0.695556,50.8403428],[0.696464,50.8592608],[0.9852099,50.8523824],[0.9906579,50.9417226],[1.0160821,50.9411504],[1.0215301,51.0303204],[1.2812198,51.0240383],[1.2848518,51.0948044],[1.4277848,51.0948044],[1.4386809,51.2882859],[1.4713691,51.2871502],[1.4804492,51.3994534],[1.1590151,51.4073836],[1.1590151,51.3869889],[1.0191822,51.3903886],[1.0228142,51.4798247],[0.8793493,51.4843484],[0.8829813,51.5566675],[1.0264462,51.5544092],[1.0373423,51.7493319],[1.2607117,51.7482076],[1.2661598,51.8279642],[1.3351682,51.8335756],[1.3478803,51.9199021],[1.4840812,51.9199021],[1.4986093,52.0038271],[1.6438902,52.0027092],[1.6656823,52.270221],[1.7310588,52.270221],[1.7528509,52.4465637],[1.8254914,52.4476705],[1.8345714,52.624408],[1.7690346,52.6291402],[1.7741711,52.717904],[1.6996925,52.721793],[1.706113,52.8103687],[1.559724,52.8165777],[1.5648605,52.9034116],[1.4184715,52.9103818],[1.4223238,52.9281894],[1.3439928,52.9289635],[1.3491293,53.0001194],[0.4515789,53.022589],[0.4497629,52.9351139],[0.3789384,52.9351139],[0.3716744,52.846365],[0.2227614,52.8496552],[0.2336575,52.9329248],[0.3062979,52.9351139],[0.308114,53.022589],[0.3807544,53.0236813],[0.3993708,53.2933729],[0.3248922,53.2987454],[0.3274604,53.3853782],[0.2504136,53.38691],[0.2581183,53.4748924],[0.1862079,53.4779494],[0.1913443,53.6548777],[0.1502527,53.6594436],[0.1528209,53.7666003],[0.0012954,53.7734308],[0.0025796,53.8424326],[-0.0282392,53.841675],[-0.0226575,53.9311501],[-0.1406983,53.9322193],[-0.1416063,54.0219323],[-0.1706625,54.0235326],[-0.1679384,54.0949482],[-0.0126694,54.0912206],[-0.0099454,54.1811226],[-0.1615824,54.1837795],[-0.1606744,54.2029038],[-0.2405789,54.2034349],[-0.2378549,54.2936234],[-0.3894919,54.2941533],[-0.3857497,54.3837321],[-0.461638,54.3856364],[-0.4571122,54.4939066],[-0.6105651,54.4965434],[-0.6096571,54.5676704],[-0.7667421,54.569776],[-0.7640181,54.5887213],[-0.9192871,54.5908258],[-0.9148116,54.6608348],[-1.1485204,54.6634343],[-1.1472363,54.7528316],[-1.2268514,54.7532021],[-1.2265398,54.8429879],[-1.2991803,54.8435107],[-1.2991803,54.9333391],[-1.3454886,54.9354258],[-1.3436726,55.0234878],[-1.3772688,55.0255698],[-1.3754528,55.1310877],[-1.4997441,55.1315727],[-1.4969272,55.2928323],[-1.5296721,55.2942946],[-1.5258198,55.6523803],[-1.7659492,55.6545537],[-1.7620968,55.7435626],[-1.9688392,55.7435626],[-1.9698023,55.8334505],[-2.0019051,55.8336308],[-2.0015841,55.9235526],[-2.1604851,55.9240613],[-2.1613931,55.9413549],[-2.3202942,55.9408463],[-2.3212022,56.0145126],[-2.5627317,56.0124824],[-2.5645477,56.1022207],[-2.9658863,56.0991822],[-2.9667943,56.1710304],[-2.4828272,56.1755797],[-2.4882752,56.2856078],[-2.5645477,56.2835918],[-2.5681798,56.3742075],[-2.7261728,56.3732019],[-2.7316208,56.4425301],[-2.6190281,56.4425301],[-2.6153961,56.5317671],[-2.453771,56.5347715],[-2.4534686,56.6420248],[-2.4062523,56.6440218],[-2.3953562,56.7297964],[-2.2936596,56.7337811],[-2.2972916,56.807423],[-2.1629067,56.8113995],[-2.1592747,56.9958425],[-1.9922016,57.0017771],[-2.0067297,57.2737477],[-1.9195612,57.2757112],[-1.9304572,57.3482876],[-1.8106005,57.3443682],[-1.7997044,57.4402728],[-1.6616875,57.4285429],[-1.6689516,57.5398256],[-1.7452241,57.5398256],[-1.7524881,57.6313302],[-1.8287606,57.6332746],[-1.8287606,57.7187255],[-3.1768526,57.7171219],[-3.1794208,57.734264],[-3.5134082,57.7292105],[-3.5129542,57.7112683],[-3.7635638,57.7076303],[-3.7598539,57.635713],[-3.8420372,57.6343382],[-3.8458895,57.6178365],[-3.9794374,57.6157733],[-3.9794374,57.686544],[-3.8150708,57.689976],[-3.817639,57.7968899],[-3.6853753,57.7989429],[-3.6892276,57.8891567],[-3.9383458,57.8877915],[-3.9421981,57.9750592],[-3.6943641,57.9784638],[-3.6969323,58.0695865],[-4.0372226,58.0641528],[-4.0346543,57.9730163],[-4.2003051,57.9702923],[-4.1832772,57.7012869],[-4.518752,57.6951111],[-4.5122925,57.6050682],[-4.6789116,57.6016628],[-4.666022,57.4218334],[-3.6677696,57.4394729],[-3.671282,57.5295384],[-3.3384979,57.5331943],[-3.3330498,57.4438859],[-2.8336466,57.4485275],[-2.8236396,56.9992706],[-2.3305398,57.0006693],[-2.3298977,56.9113932],[-2.6579889,56.9092901],[-2.6559637,56.8198406],[-2.8216747,56.8188467],[-2.8184967,56.7295397],[-3.1449248,56.7265508],[-3.1435628,56.6362749],[-3.4679089,56.6350265],[-3.474265,56.7238108],[-3.8011471,56.7188284],[-3.785711,56.4493026],[-3.946428,56.4457896],[-3.9428873,56.2659777],[-4.423146,56.2588459],[-4.4141572,56.0815506],[-4.8944159,56.0708008],[-4.8791072,55.8896994],[-5.1994158,55.8821374],[-5.1852906,55.7023791],[-5.0273445,55.7067203],[-5.0222081,55.6879046],[-4.897649,55.6907999],[-4.8880181,55.6002822],[-4.7339244,55.6046348],[-4.7275038,55.5342082],[-4.773732,55.5334815],[-4.7685955,55.4447227],[-4.8494947,55.4418092],[-4.8405059,55.3506535],[-4.8700405,55.3513836],[-4.8649041,55.2629462],[-4.9920314,55.2592875],[-4.9907473,55.1691779],[-5.0600894,55.1655105],[-5.0575212,55.0751884],[-5.2141831,55.0722477],[-5.1991766,54.8020337],[-5.0466316,54.8062205],[-5.0502636,54.7244996],[-4.9703591,54.7203043],[-4.9776232,54.6215905],[-4.796022,54.6342056],[-4.796022,54.7307917],[-4.8977186,54.7265971],[-4.9086147,54.8145928],[-4.8069181,54.8166856],[-4.8105501,54.7915648],[-4.6943253,54.7978465],[-4.6761652,54.7244996],[-4.5744686,54.7244996],[-4.5599405,54.6426135],[-4.3093309,54.6384098],[-4.3333262,54.8229889],[-4.2626999,54.8274274],[-4.2549952,54.7348587],[-3.8338058,54.7400481],[-3.836374,54.8141105],[-3.7118149,54.8133706],[-3.7143831,54.8318654],[-3.5346072,54.8355633],[-3.5271039,54.9066228],[-3.4808758,54.9084684],[-3.4776655,54.7457328],[-3.5874573,54.744621],[-3.5836049,54.6546166],[-3.7107322,54.6531308],[-3.6991752,54.4550407],[-3.5746161,54.4572801],[-3.5759002,54.3863042],[-3.539945,54.3855564],[-3.5386609,54.297224],[-3.46033,54.2957252],[-3.4590458,54.2079507],[-3.3807149,54.2102037],[-3.381999,54.1169788],[-3.302878,54.1160656],[-3.300154,54.0276224],[-3.1013007,54.0292224],[-3.093596,53.6062158],[-3.2065981,53.6016441],[-3.2091663,53.4917753],[-3.2451215,53.4887193],[-3.2348486,53.4045934],[-3.5276266,53.3999999],[-3.5343966,53.328481],[-3.6488053,53.3252272],[-3.6527308,53.3057716],[-3.7271873,53.3046865],[-3.7315003,53.3945257],[-3.9108315,53.3912769],[-3.9071995,53.3023804],[-3.9521457,53.3015665],[-3.9566724,53.3912183],[-4.1081979,53.3889209],[-4.1081979,53.4072967],[-4.2622916,53.4065312],[-4.2635757,53.4753707],[-4.638537,53.4677274],[-4.6346847,53.3812621],[-4.7091633,53.3774321],[-4.7001745,53.1954965],[-4.5499332,53.1962658],[-4.5435126,53.1092488],[-4.3919871,53.1100196],[-4.3855666,53.0236002],[-4.6115707,53.0205105],[-4.603866,52.9284932],[-4.7566756,52.9261709],[-4.7476868,52.8370555],[-4.8208813,52.8331768],[-4.8208813,52.7446476],[-4.3701572,52.7539749],[-4.3765778,52.8401583],[-4.2314728,52.8455875],[-4.2237682,52.7586379],[-4.1056297,52.7570836],[-4.1015192,52.6714874],[-4.1487355,52.6703862],[-4.1305754,52.4008596],[-4.1995838,52.3986435],[-4.2050319,52.3110195],[-4.3466808,52.303247],[-4.3484968,52.2365693],[-4.4901457,52.2332328],[-4.4883297,52.2098702],[-4.6572188,52.2098702],[-4.6590348,52.1385939],[-4.7788916,52.13525],[-4.7807076,52.1162967],[-4.9259885,52.1140663],[-4.9187245,52.0392855],[-5.2365265,52.0314653],[-5.2347105,51.9442339],[-5.3473032,51.9408755],[-5.3473032,51.9195995],[-5.4925842,51.9162392],[-5.4853201,51.8265386],[-5.1983903,51.8321501],[-5.1893102,51.7625177],[-5.335825,51.7589528],[-5.3281204,51.6686495],[-5.1836575,51.6730296],[-5.1836575,51.6539134],[-5.0674452,51.6578966],[-5.0603825,51.5677905],[-4.5974594,51.5809588],[-4.60388,51.6726314],[-4.345773,51.6726314],[-4.3355001,51.4962964],[-3.9528341,51.5106841],[-3.9425611,51.5905333],[-3.8809237,51.5953198],[-3.8706508,51.5074872],[-3.7679216,51.4978952],[-3.7550805,51.4242895],[-3.5855774,51.41468],[-3.5778727,51.3329177],[-3.0796364,51.3329177],[-3.0770682,51.2494018],[-3.7216935,51.2381477],[-3.7216935,51.2558315],[-3.8706508,51.2558315],[-3.8680825,51.2365398],[-4.2944084,51.2252825],[-4.289272,51.0496352],[-4.5692089,51.0431767],[-4.5624122,50.9497388],[-4.5905604,50.9520269],[-4.5896524,50.8627065],[-4.6296046,50.8592677],[-4.6226411,50.7691513],[-4.6952816,50.7680028],[-4.6934655,50.6967379],[-4.8342064,50.6938621],[-4.8296664,50.6046231],[-4.9676833,50.6000126],[-4.9685913,50.5821427],[-5.1084242,50.5786832],[-5.1029762,50.4892254],[-5.1311244,50.48807],[-5.1274923,50.4163798],[-5.2664172,50.4117509],[-5.2609692,50.3034214],[-5.5124868,50.2976214],[-5.5061308,50.2256428],[-5.6468717,50.2209953],[-5.6453263,50.2029809]],[[-5.1336607,55.2630226],[-5.1021999,55.2639372],[-5.0999527,55.2458239],[-5.1322161,55.2446343],[-5.1336607,55.2630226]],[[-5.6431878,55.5095745],[-5.4861028,55.5126594],[-5.4715747,55.3348829],[-5.6277517,55.3302345],[-5.6431878,55.5095745]],[[-4.7213517,51.2180246],[-4.5804201,51.2212417],[-4.5746416,51.1306736],[-4.7174993,51.1280545],[-4.7213517,51.2180246]],[[-5.1608796,55.4153626],[-5.0045387,55.4190069],[-5.0184798,55.6153521],[-5.1755648,55.6138137],[-5.1608796,55.4153626]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-25inch-hist","name":"NLS - OS 25-inch (Scotland), 1892-1905","type":"tms","template":"http://geo.nls.uk/mapdata2/os/25_inch/scotland_1/{zoom}/{x}/{y}.png","scaleExtent":[0,18],"polygon":[[[-9.25,54.43],[-9.25,61.12],[0.22,61.12],[0.22,54.43],[-9.25,54.43]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-6inch-County-Series-hist","name":"NLS - OS 6-inch County Series, 1888-1913","type":"tms","template":"http://geo.nls.uk/mapdata3/os/6_inch_gb_1900/{zoom}/{x}/{y}.png","scaleExtent":[0,17],"polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLS-OS-6inch-Scotland-hist","name":"NLS - OS 6-inch Scotland 1842-82","type":"tms","template":"http://geo.nls.uk/maps/os/six_inch/{zoom}/{x}/{-y}.png","scaleExtent":[5,16],"polygon":[[[-5.2112173,54.8018593],[-5.0642752,54.8026508],[-5.0560354,54.6305176],[-4.3158316,54.6297227],[-4.3117117,54.7448258],[-3.8530325,54.7464112],[-3.8530325,54.8034424],[-3.5522818,54.8034424],[-3.5522818,54.8374644],[-3.468511,54.8406277],[-3.4657644,54.8983158],[-3.3847403,54.8991055],[-3.3888601,54.9559214],[-3.0920786,54.9539468],[-3.0392359,54.9923274],[-3.0212713,55.0493881],[-2.9591232,55.0463283],[-2.9202807,55.0666294],[-2.7857081,55.068652],[-2.7852225,55.0914426],[-2.7337562,55.0922761],[-2.737616,55.151204],[-2.7648395,55.1510672],[-2.7013114,55.1722505],[-2.6635459,55.2192808],[-2.6460364,55.2188891],[-2.629042,55.2233933],[-2.6317886,55.2287781],[-2.6235488,55.2446345],[-2.6197723,55.2454663],[-2.6099017,55.2454174],[-2.6099876,55.2486466],[-2.6408121,55.2590039],[-2.6247896,55.2615631],[-2.6045186,55.2823081],[-2.5693176,55.296132],[-2.5479542,55.3121617],[-2.5091116,55.3234891],[-2.4780376,55.3494471],[-2.4421083,55.3533118],[-2.4052079,55.3439256],[-2.3726772,55.3447539],[-2.3221819,55.3687665],[-2.3241241,55.3999337],[-2.2576062,55.425015],[-2.1985547,55.4273529],[-2.1484296,55.4717466],[-2.1944348,55.484199],[-2.2040479,55.529306],[-2.2960584,55.6379722],[-2.2177808,55.6379722],[-2.1059266,55.7452498],[-1.9716874,55.7462161],[-1.9697453,55.9190951],[-2.1201694,55.9207115],[-2.1242893,55.9776133],[-2.3440159,55.9783817],[-2.3440159,56.0390349],[-2.5046909,56.0413363],[-2.500571,56.1003588],[-2.8823459,56.0957629],[-2.8823459,56.1722898],[-2.4126804,56.1692316],[-2.4181736,56.2334017],[-2.5857151,56.2303484],[-2.5719822,56.3416356],[-2.7257908,56.3462022],[-2.7312839,56.4343808],[-2.6928318,56.4343808],[-2.6928318,56.4859769],[-2.5307834,56.4935587],[-2.5307834,56.570806],[-2.5302878,56.6047947],[-2.3732428,56.6044452],[-2.3684363,56.7398824],[-2.3292975,56.7398824],[-2.3292975,56.7888065],[-2.3145346,56.7891826],[-2.3148779,56.7967036],[-2.171369,56.7967036],[-2.1703979,56.9710595],[-2.0101725,56.9694716],[-2.0101725,57.0846832],[-2.0817687,57.085349],[-2.0488097,57.1259963],[-2.0409133,57.126369],[-2.0383434,57.2411129],[-1.878118,57.2421638],[-1.8771469,57.2978175],[-1.9868771,57.2983422],[-1.9082209,57.3560063],[-1.8752048,57.3560063],[-1.8761758,57.3769527],[-1.8120857,57.4120111],[-1.7120661,57.4120111],[-1.7034646,57.6441388],[-1.8666032,57.6451781],[-1.8646611,57.7033351],[-3.1204292,57.7064705],[-3.1218025,57.7504652],[-3.4445259,57.7526635],[-3.4472724,57.7138067],[-3.5145637,57.7094052],[-3.5118171,57.6939956],[-3.7645027,57.6917938],[-3.7672492,57.6344975],[-3.842378,57.6288312],[-3.8438346,57.5965825],[-3.9414265,57.5916386],[-3.9404554,57.6537782],[-3.8894746,57.6529989],[-3.8826772,57.7676408],[-3.7224517,57.766087],[-3.7195385,57.8819201],[-3.9146888,57.8853352],[-3.916062,57.9546243],[-3.745774,57.9538956],[-3.7471473,58.0688409],[-3.5837256,58.0695672],[-3.5837256,58.1116689],[-3.4560096,58.1138452],[-3.4544646,58.228503],[-3.4379851,58.2283222],[-3.4243233,58.2427725],[-3.412307,58.2438567],[-3.3735115,58.2695057],[-3.3063919,58.2862038],[-3.1229154,58.2859395],[-3.123602,58.3443661],[-2.9574338,58.3447264],[-2.951254,58.6422011],[-2.8812162,58.6429157],[-2.8851004,58.8112825],[-2.7180775,58.8142997],[-2.7161354,58.8715749],[-2.556881,58.8775984],[-2.5544533,58.9923453],[-2.5567617,59.0483775],[-2.391893,59.0485996],[-2.3918002,59.1106996],[-2.4733695,59.1106996],[-2.5591563,59.1783028],[-2.5630406,59.2210646],[-2.3921334,59.224046],[-2.3911409,59.2740075],[-2.3639512,59.2745036],[-2.3658933,59.285417],[-2.3911409,59.284921],[-2.3911409,59.3379505],[-2.2221759,59.3381981],[-2.2233897,59.395965],[-2.3758467,59.396583],[-2.3899271,59.4026383],[-2.4008516,59.3962122],[-2.5637882,59.3952604],[-2.5637882,59.3385811],[-2.7320164,59.3375306],[-2.7333896,59.3952604],[-3.0726511,59.3931174],[-3.0703404,59.3354759],[-3.0753186,59.3355634],[-3.0749753,59.3292593],[-3.0698254,59.3289091],[-3.069801,59.2196159],[-3.2363384,59.2166341],[-3.2336751,59.1606496],[-3.4032766,59.1588895],[-3.394086,58.9279316],[-3.5664497,58.9259268],[-3.5611089,58.8679885],[-3.392508,58.8699339],[-3.3894734,58.8698711],[-3.3891093,58.8684905],[-3.3912942,58.868616],[-3.3884161,58.7543084],[-3.2238208,58.7555677],[-3.2189655,58.691289],[-3.4634113,58.6905753],[-3.4551716,58.6341518],[-3.787508,58.6341518],[-3.7861347,58.5769211],[-3.9028645,58.5733411],[-3.9028645,58.6477304],[-4.0690327,58.6491594],[-4.0690327,58.5912376],[-4.7364521,58.5933845],[-4.7364521,58.6505884],[-5.0715351,58.6520173],[-5.0654779,58.5325854],[-5.2332047,58.5316087],[-5.2283494,58.4719947],[-5.2424298,58.4719947],[-5.2366034,58.4089731],[-5.2283494,58.4094818],[-5.2210664,58.3005859],[-5.5657939,58.2959933],[-5.5580254,58.2372573],[-5.4146722,58.2401326],[-5.4141866,58.2267768],[-5.3885749,58.2272242],[-5.382714,58.1198615],[-5.51043,58.1191362],[-5.5114011,58.006214],[-5.6745397,58.0041559],[-5.6716266,57.9449366],[-5.6716266,57.8887166],[-5.8347652,57.8856193],[-5.8277052,57.5988958],[-6.0384259,57.5986357],[-6.0389115,57.6459559],[-6.1981658,57.6456961],[-6.2076123,57.7600132],[-6.537067,57.7544033],[-6.5312406,57.6402392],[-6.7002056,57.6360809],[-6.6807844,57.5236293],[-6.8516915,57.5152857],[-6.8361545,57.3385811],[-6.6730158,57.3438213],[-6.674958,57.2850883],[-6.5098772,57.2850883],[-6.4982244,57.1757637],[-6.3506228,57.1820797],[-6.3312015,57.1251969],[-6.1797156,57.1230884],[-6.1719471,57.0682265],[-6.4593819,57.059779],[-6.4564687,57.1093806],[-6.6671895,57.1062165],[-6.6730158,57.002708],[-6.5021087,57.0048233],[-6.4836097,56.8917522],[-6.3266104,56.8894062],[-6.3156645,56.7799312],[-6.2146739,56.775675],[-6.2146739,56.7234965],[-6.6866107,56.7224309],[-6.6769001,56.6114413],[-6.8419809,56.607166],[-6.8400387,56.5483307],[-7.1546633,56.5461895],[-7.1488369,56.4872592],[-6.9915246,56.490476],[-6.9876404,56.4325329],[-6.6827265,56.4314591],[-6.6769001,56.5472601],[-6.5292985,56.5504717],[-6.5234721,56.4379018],[-6.3661598,56.4368281],[-6.3642177,56.3766524],[-6.5273563,56.3712749],[-6.5171745,56.2428427],[-6.4869621,56.247421],[-6.4869621,56.1893882],[-6.3001945,56.1985572],[-6.3029411,56.2581017],[-5.9019401,56.256576],[-5.8964469,56.0960466],[-6.0282829,56.0883855],[-6.0392692,56.1557502],[-6.3853385,56.1542205],[-6.3606193,55.96099],[-6.2123039,55.9640647],[-6.2047508,55.9202269],[-6.5185478,55.9129158],[-6.5061881,55.7501763],[-6.6764762,55.7409005],[-6.6599967,55.6263176],[-6.3551261,55.6232161],[-6.3578727,55.5689002],[-6.0392692,55.5720059],[-6.0310294,55.6247669],[-5.7398917,55.6309694],[-5.7371452,55.4569279],[-5.8964469,55.4600426],[-5.8964469,55.2789864],[-5.4350211,55.2821151],[-5.4405143,55.4506979],[-5.2867057,55.4569279],[-5.3086784,55.4070602],[-4.9735954,55.4008223],[-4.9845817,55.2038242],[-5.1493766,55.2038242],[-5.1411369,55.037337],[-5.2152946,55.0341891],[-5.2112173,54.8018593]],[[-2.1646559,60.1622059],[-1.9930299,60.1609801],[-1.9946862,60.1035151],[-2.1663122,60.104743],[-2.1646559,60.1622059]],[[-1.5360658,59.8570831],[-1.3653566,59.8559841],[-1.366847,59.7975565],[-1.190628,59.7964199],[-1.1862046,59.9695391],[-1.0078652,59.9683948],[-1.0041233,60.114145],[-0.8360832,60.1130715],[-0.834574,60.1716772],[-1.0074262,60.1727795],[-1.0052165,60.2583924],[-0.8299659,60.2572778],[-0.826979,60.3726551],[-0.6507514,60.3715381],[-0.6477198,60.4882292],[-0.9984896,60.4904445],[-0.9970279,60.546555],[-0.6425288,60.5443201],[-0.6394896,60.6606792],[-0.8148133,60.6617806],[-0.8132987,60.7196112],[-0.6383298,60.7185141],[-0.635467,60.8275393],[-0.797568,60.8285523],[-0.9941426,60.8297807],[-0.9954966,60.7782667],[-1.1670282,60.7793403],[-1.1700357,60.6646181],[-1.5222599,60.6668304],[-1.5237866,60.6084426],[-1.6975673,60.609536],[-1.7021271,60.4345249],[-1.5260578,60.4334111],[-1.5275203,60.3770719],[-1.8751127,60.3792746],[-1.8781372,60.2624647],[-1.7019645,60.2613443],[-1.7049134,60.1470532],[-1.528659,60.1459283],[-1.5360658,59.8570831]],[[-0.9847667,60.8943762],[-0.9860347,60.8361105],[-0.8078362,60.8351904],[-0.8065683,60.8934578],[-0.9847667,60.8943762]],[[-7.7696901,56.8788231],[-7.7614504,56.7608274],[-7.6009049,56.7641903],[-7.5972473,56.819332],[-7.4479894,56.8203948],[-7.4489319,56.8794098],[-7.2841369,56.8794098],[-7.2813904,57.0471152],[-7.1303283,57.0515969],[-7.1330749,57.511801],[-6.96828,57.5147514],[-6.9765198,57.6854668],[-6.8062317,57.6913392],[-6.8089782,57.8041985],[-6.6496765,57.8071252],[-6.6441833,57.8612267],[-6.3200866,57.8626878],[-6.3200866,58.1551617],[-6.1607849,58.1522633],[-6.1552917,58.20874],[-5.9850036,58.2101869],[-5.9904968,58.2680163],[-6.1497986,58.2665717],[-6.1415588,58.5557514],[-6.3173401,58.5557514],[-6.3091003,58.4983923],[-6.4876282,58.4955218],[-6.4876282,58.4423768],[-6.6606628,58.4395018],[-6.6469299,58.3819525],[-6.8117248,58.3805125],[-6.8117248,58.3286357],[-6.9792663,58.3286357],[-6.9710266,58.2694608],[-7.1413147,58.2680163],[-7.1403816,58.0358742],[-7.3020636,58.0351031],[-7.3030347,57.9774797],[-7.1379539,57.9777372],[-7.1413526,57.9202792],[-7.1398961,57.8640206],[-7.3020636,57.862471],[-7.298484,57.7442293],[-7.4509193,57.7456951],[-7.4550392,57.6899522],[-7.6186131,57.6906048],[-7.6198341,57.7456951],[-7.7901222,57.7442293],[-7.7873756,57.6855477],[-7.6222332,57.6853817],[-7.6173779,57.5712602],[-7.788285,57.5709998],[-7.7892561,57.512109],[-7.7038025,57.5115874],[-7.6999183,57.4546902],[-7.5367796,57.4552126],[-7.5348375,57.5126306],[-7.4581235,57.5131521],[-7.4552103,57.2824165],[-7.6115515,57.2845158],[-7.6144647,57.2272651],[-7.451326,57.2256881],[-7.451326,57.1103873],[-7.6164068,57.1088053],[-7.603783,56.8792358],[-7.7696901,56.8788231]],[[-1.7106618,59.5626284],[-1.5417509,59.562215],[-1.5423082,59.5037224],[-1.7112191,59.5041365],[-1.7106618,59.5626284]]],"terms_url":"http://geo.nls.uk/maps/","terms_text":"National Library of Scotland Historic Maps"},{"id":"NLSC-EMAP5","name":"NLSC General Map with Contour line","type":"tms","template":"http://maps.nlsc.gov.tw/S_Maps/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=EMAP5_OPENDATA&STYLE=_null&TILEMATRIXSET=EPSG:3857&TILEMATRIX=EPSG:3857:{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image/png","description":"The emap from Taiwan National Land Surveying and Mapping Center","scaleExtent":[0,15],"polygon":[[[120.4570579,26.3970586],[120.44256,26.3708009],[120.44713,26.3531513],[120.4673009,26.3405831],[120.4978723,26.3340866],[120.5141036,26.3401594],[120.5341168,26.3641649],[120.5297045,26.3842128],[120.4956661,26.4015754],[120.4570579,26.3970586]],[[119.9007221,25.9858609],[119.8960071,25.9648902],[119.9131301,25.9470399],[119.9503542,25.9278478],[119.9905563,25.9260623],[120.0198392,25.9363284],[120.0277804,25.9557423],[120.0275322,25.9845224],[119.9989937,26.0010288],[119.9404278,26.0028131],[119.9007221,25.9858609]],[[122.089,24.5485],[121.709,23.4541],[121.717,22.698],[121.818,21.95],[121.803,21.8735],[121.759,21.8087],[121.694,21.7653],[120.861,21.5631],[120.815,21.5576],[120.739,21.5728],[120.661,21.6296],[120.202,22.1809],[119.27,23.0542],[119.153,23.2049],[119.128,23.2485],[119.103,23.4],[119.118,23.4765],[119.137,23.512],[119.361,23.8885],[119.406,23.9407],[120.968,25.2284],[121.408,25.4687],[121.989,25.8147],[122.065,25.8299],[122.141,25.8147],[122.216,25.7663],[122.26,25.7015],[122.297,25.48],[122.196,24.9696],[122.089,24.5485]],[[116.6855033,20.8547596],[116.6309071,20.8149565],[116.5941695,20.7600846],[116.5797214,20.6967501],[116.5893056,20.6325865],[116.621766,20.5753367],[116.6731874,20.5319171],[116.7373678,20.5075783],[116.8065659,20.5052653],[116.8724354,20.5252581],[116.9270316,20.5651373],[116.9637692,20.6200797],[116.9782173,20.6834462],[116.9686331,20.7475883],[116.9361727,20.8047732],[116.8847512,20.8481147],[116.8205709,20.872399],[116.7513728,20.8747063],[116.6855033,20.8547596]],[[118.2261504,24.4563345],[118.2936439,24.4538527],[118.2851467,24.4751026],[118.3097372,24.4916821],[118.3767709,24.4729348],[118.4100947,24.5332285],[118.4479031,24.5284069],[118.4746394,24.4599272],[118.512992,24.4315479],[118.5065839,24.4202318],[118.4811625,24.4332439],[118.4610567,24.4089192],[118.426145,24.3970385],[118.3970055,24.4284184],[118.3765564,24.4258395],[118.3397565,24.3814628],[118.3031926,24.3705764],[118.2574234,24.4139213],[118.1381276,24.3724838],[118.1617342,24.4022433],[118.2094226,24.4139604],[118.1895784,24.4352201],[118.2176338,24.430205],[118.2261504,24.4563345]],[[120.2234496,26.30045],[120.2550843,26.3100412],[120.269888,26.3368716],[120.2591889,26.3652192],[120.2292544,26.3784823],[120.1976197,26.3688968],[120.182816,26.3420738],[120.1935151,26.3137205],[120.2234496,26.30045]],[[119.4374461,25.0047541],[119.4342024,24.9886249],[119.4541901,24.9722553],[119.4827444,24.9718376],[119.4898402,24.9937882],[119.4715877,25.0069239],[119.4374461,25.0047541]],[[119.8869914,26.180381],[119.893227,26.1203128],[119.9285109,26.1080224],[119.9779388,26.1223611],[120.0366775,26.151728],[120.1098054,26.2134921],[120.119269,26.2713663],[120.0629175,26.3172592],[119.9923706,26.3164881],[119.9467732,26.2898799],[119.9020362,26.2439761],[119.8869914,26.180381]]],"terms_url":"http://maps.nlsc.gov.tw/","terms_text":"NLSC EMAP 2015"},{"id":"MAPNIK","name":"OpenStreetMap (Standard)","type":"tms","template":"https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png","description":"The default OpenStreetMap layer.","scaleExtent":[0,19],"terms_url":"https://openstreetmap.org/","terms_text":"© OpenStreetMap contributors, CC-BY-SA","default":true},{"id":"osm-gps","name":"OpenStreetMap GPS traces","type":"tms","template":"http://{switch:a,b,c}.gps-tile.openstreetmap.org/lines/{zoom}/{x}/{y}.png","description":"Public GPS traces uploaded to OpenStreetMap.","scaleExtent":[0,20],"terms_url":"http://www.openstreetmap.org/copyright","terms_text":"© OpenStreetMap contributors","terms_html":"<span style='display: inline-block; padding: 0 8px; background-color: rgba(0,0,0,0.5);'><span style='color: #eee;'>GPS Direction:</span> <span style='font-size: 15px; padding-left: 2px; font-weight: bold;'> <span style='color: #0ee;'>←</span> <span style='color: #96f;'>↓</span> <span style='color: #6e0;'>↑</span> <span style='color: #f63;'>→</span> </span></span> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap contributors</a>.","overlay":true},{"id":"OS-historic-25k-OSM_Limited","name":"OS 1:25k historic (OSM)","type":"tms","template":"http://ooc.openstreetmap.org/os1/{zoom}/{x}/{y}.jpg","scaleExtent":[6,17],"polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]]},{"id":"OS-New_Popular_Edition-historic","name":"OS New Popular Edition historic","type":"tms","template":"http://ooc.openstreetmap.org/npe/{zoom}/{x}/{y}.png","polygon":[[[-5.8,49.8],[-5.8,55.8],[1.9,55.8],[1.9,49.8],[-5.8,49.8]]]},{"id":"OS-OpenData_Locator","name":"OS OpenData Locator","type":"tms","template":"http://tiles.itoworld.com/os_locator/{zoom}/{x}/{y}.png","polygon":[[[-9,49.8],[-9,61.1],[1.9,61.1],[1.9,49.8],[-9,49.8]]],"overlay":true},{"id":"OS-OpenData_StreetView","name":"OS OpenData StreetView","type":"tms","template":"http://os.openstreetmap.org/sv/{zoom}/{x}/{y}.png","scaleExtent":[1,18],"polygon":[[[-5.8292886,50.0229734],[-5.8292886,50.254819],[-5.373356,50.254819],[-5.373356,50.3530588],[-5.1756021,50.3530588],[-5.1756021,50.5925406],[-4.9970743,50.5925406],[-4.9970743,50.6935617],[-4.7965738,50.6935617],[-4.7965738,50.7822112],[-4.6949503,50.7822112],[-4.6949503,50.9607371],[-4.6043131,50.9607371],[-4.6043131,51.0692066],[-4.3792215,51.0692066],[-4.3792215,51.2521782],[-3.9039346,51.2521782],[-3.9039346,51.2916998],[-3.7171671,51.2916998],[-3.7171671,51.2453014],[-3.1486246,51.2453014],[-3.1486246,51.362067],[-3.7446329,51.362067],[-3.7446329,51.4340386],[-3.8297769,51.4340386],[-3.8297769,51.5298246],[-4.0852091,51.5298246],[-4.0852091,51.4939284],[-4.3792215,51.4939284],[-4.3792215,51.5427168],[-5.1444195,51.5427168],[-5.1444195,51.6296003],[-5.7387103,51.6296003],[-5.7387103,51.774037],[-5.5095393,51.774037],[-5.5095393,51.9802596],[-5.198799,51.9802596],[-5.198799,52.0973358],[-4.8880588,52.0973358],[-4.8880588,52.1831557],[-4.4957492,52.1831557],[-4.4957492,52.2925739],[-4.3015365,52.2925739],[-4.3015365,52.3685318],[-4.1811246,52.3685318],[-4.1811246,52.7933685],[-4.4413696,52.7933685],[-4.4413696,52.7369614],[-4.8569847,52.7369614],[-4.8569847,52.9317255],[-4.7288044,52.9317255],[-4.7288044,53.5038599],[-4.1578191,53.5038599],[-4.1578191,53.4113498],[-3.3110518,53.4113498],[-3.3110518,53.5038599],[-3.2333667,53.5038599],[-3.2333667,54.0159169],[-3.3926211,54.0159169],[-3.3926211,54.1980953],[-3.559644,54.1980953],[-3.559644,54.433732],[-3.7188984,54.433732],[-3.7188984,54.721897],[-4.3015365,54.721897],[-4.3015365,54.6140739],[-5.0473132,54.6140739],[-5.0473132,54.7532915],[-5.2298731,54.7532915],[-5.2298731,55.2190799],[-5.6532567,55.2190799],[-5.6532567,55.250088],[-5.8979647,55.250088],[-5.8979647,55.4822462],[-6.5933212,55.4822462],[-6.5933212,56.3013441],[-7.1727691,56.3013441],[-7.1727691,56.5601822],[-6.8171722,56.5601822],[-6.8171722,56.6991713],[-6.5315276,56.6991713],[-6.5315276,56.9066964],[-6.811679,56.9066964],[-6.811679,57.3716613],[-6.8721038,57.3716613],[-6.8721038,57.5518893],[-7.0973235,57.5518893],[-7.0973235,57.2411085],[-7.1742278,57.2411085],[-7.1742278,56.9066964],[-7.3719817,56.9066964],[-7.3719817,56.8075885],[-7.5202972,56.8075885],[-7.5202972,56.7142479],[-7.8306806,56.7142479],[-7.8306806,56.8994605],[-7.6494061,56.8994605],[-7.6494061,57.4739617],[-7.8306806,57.4739617],[-7.8306806,57.7915584],[-7.4736249,57.7915584],[-7.4736249,58.086063],[-7.1879804,58.086063],[-7.1879804,58.367197],[-6.8034589,58.367197],[-6.8034589,58.4155786],[-6.638664,58.4155786],[-6.638664,58.4673277],[-6.5178143,58.4673277],[-6.5178143,58.5625632],[-6.0536224,58.5625632],[-6.0536224,58.1568843],[-6.1470062,58.1568843],[-6.1470062,58.1105865],[-6.2799798,58.1105865],[-6.2799798,57.7122664],[-6.1591302,57.7122664],[-6.1591302,57.6667563],[-5.9339104,57.6667563],[-5.9339104,57.8892524],[-5.80643,57.8892524],[-5.80643,57.9621767],[-5.6141692,57.9621767],[-5.6141692,58.0911236],[-5.490819,58.0911236],[-5.490819,58.3733281],[-5.3199118,58.3733281],[-5.3199118,58.75015],[-3.5719977,58.75015],[-3.5719977,59.2091788],[-3.1944501,59.2091788],[-3.1944501,59.4759216],[-2.243583,59.4759216],[-2.243583,59.1388749],[-2.4611012,59.1388749],[-2.4611012,58.8185938],[-2.7407675,58.8185938],[-2.7407675,58.5804743],[-2.9116746,58.5804743],[-2.9116746,58.1157523],[-3.4865441,58.1157523],[-3.4865441,57.740386],[-1.7153245,57.740386],[-1.7153245,57.2225558],[-1.9794538,57.2225558],[-1.9794538,56.8760742],[-2.1658979,56.8760742],[-2.1658979,56.6333186],[-2.3601106,56.6333186],[-2.3601106,56.0477521],[-1.9794538,56.0477521],[-1.9794538,55.8650949],[-1.4745008,55.8650949],[-1.4745008,55.2499926],[-1.3221997,55.2499926],[-1.3221997,54.8221737],[-1.0550014,54.8221737],[-1.0550014,54.6746628],[-0.6618765,54.6746628],[-0.6618765,54.5527463],[-0.3247617,54.5527463],[-0.3247617,54.2865195],[0.0092841,54.2865195],[0.0092841,53.7938518],[0.2081962,53.7938518],[0.2081962,53.5217726],[0.4163548,53.5217726],[0.4163548,53.0298851],[1.4273388,53.0298851],[1.4273388,52.92021],[1.8333912,52.92021],[1.8333912,52.042488],[1.5235504,52.042488],[1.5235504,51.8261335],[1.2697049,51.8261335],[1.2697049,51.6967453],[1.116651,51.6967453],[1.116651,51.440346],[1.5235504,51.440346],[1.5235504,51.3331831],[1.4507565,51.3331831],[1.4507565,51.0207553],[1.0699883,51.0207553],[1.0699883,50.9008416],[0.7788126,50.9008416],[0.7788126,50.729843],[-0.7255952,50.729843],[-0.7255952,50.7038437],[-1.0074383,50.7038437],[-1.0074383,50.5736307],[-2.3625252,50.5736307],[-2.3625252,50.4846421],[-2.4987805,50.4846421],[-2.4987805,50.5736307],[-3.4096378,50.5736307],[-3.4096378,50.2057837],[-3.6922446,50.2057837],[-3.6922446,50.1347737],[-5.005468,50.1347737],[-5.005468,49.9474456],[-5.2839506,49.9474456],[-5.2839506,50.0229734],[-5.8292886,50.0229734]],[[-6.4580707,49.8673563],[-6.4580707,49.9499935],[-6.3978807,49.9499935],[-6.3978807,50.0053797],[-6.1799606,50.0053797],[-6.1799606,49.9168614],[-6.2540201,49.9168614],[-6.2540201,49.8673563],[-6.4580707,49.8673563]],[[-5.8343165,49.932156],[-5.8343165,49.9754641],[-5.7683254,49.9754641],[-5.7683254,49.932156],[-5.8343165,49.932156]],[[-1.9483797,60.6885737],[-1.9483797,60.3058841],[-1.7543149,60.3058841],[-1.7543149,60.1284428],[-1.5754914,60.1284428],[-1.5754914,59.797917],[-1.0316959,59.797917],[-1.0316959,60.0354518],[-0.6626918,60.0354518],[-0.6626918,60.9103862],[-1.1034395,60.9103862],[-1.1034395,60.8040022],[-1.3506319,60.8040022],[-1.3506319,60.6885737],[-1.9483797,60.6885737]],[[-2.203381,60.1968568],[-2.203381,60.0929443],[-1.9864011,60.0929443],[-1.9864011,60.1968568],[-2.203381,60.1968568]],[[-1.7543149,59.5698289],[-1.7543149,59.4639383],[-1.5373349,59.4639383],[-1.5373349,59.5698289],[-1.7543149,59.5698289]],[[-4.5585981,59.1370518],[-4.5585981,58.9569099],[-4.2867004,58.9569099],[-4.2867004,59.1370518],[-4.5585981,59.1370518]],[[-6.2787732,59.2025744],[-6.2787732,59.0227769],[-5.6650612,59.0227769],[-5.6650612,59.2025744],[-6.2787732,59.2025744]],[[-8.7163482,57.9440556],[-8.7163482,57.7305936],[-8.3592926,57.7305936],[-8.3592926,57.9440556],[-8.7163482,57.9440556]],[[-7.6077005,50.4021026],[-7.6077005,50.2688657],[-7.3907205,50.2688657],[-7.3907205,50.4021026],[-7.6077005,50.4021026]],[[-7.7304303,58.3579902],[-7.7304303,58.248313],[-7.5134503,58.248313],[-7.5134503,58.3579902],[-7.7304303,58.3579902]]]},{"id":"OS-Scottish_Popular-historic","name":"OS Scottish Popular historic","type":"tms","template":"http://ooc.openstreetmap.org/npescotland/tiles/{zoom}/{x}/{y}.jpg","scaleExtent":[6,15],"polygon":[[[-7.8,54.5],[-7.8,61.1],[-1.1,61.1],[-1.1,54.5],[-7.8,54.5]]]},{"id":"Pangasinan_Bulacan_HiRes","name":"Pangasinán/Bulacan (Phillipines HiRes)","type":"tms","template":"http://gravitystorm.dev.openstreetmap.org/imagery/philippines/{zoom}/{x}/{y}.png","scaleExtent":[12,19],"polygon":[[[120.336593,15.985768],[120.445995,15.984],[120.446134,15.974459],[120.476464,15.974592],[120.594247,15.946832],[120.598064,16.090795],[120.596537,16.197999],[120.368537,16.218527],[120.347576,16.042308],[120.336593,15.985768]],[[120.8268,15.3658],[121.2684,15.2602],[121.2699,14.7025],[120.695,14.8423],[120.8268,15.3658]]]},{"id":"PNOA-Spain-TMS","name":"PNOA Spain","type":"tms","template":"http://www.ign.es/wmts/pnoa-ma?request=GetTile&service=WMTS&VERSION=1.0.0&Layer=OI.OrthoimageCoverage&Style=default&Format=image/png&TileMatrixSet=GoogleMapsCompatible&TileMatrix={zoom}&TileRow={y}&TileCol={x}","polygon":[[[-17.8846298,28.4460601],[-17.8939535,28.5225529],[-18.0212548,28.7481927],[-18.0224091,28.8038375],[-17.9424017,28.8726124],[-17.8911792,28.8737099],[-17.8903302,28.8515102],[-17.7675902,28.8537764],[-17.7669837,28.8312183],[-17.7412714,28.8319975],[-17.7394926,28.7642235],[-17.7139824,28.7649677],[-17.7129312,28.7303731],[-17.7574427,28.6931782],[-17.7570788,28.6741254],[-17.7457913,28.6743524],[-17.7457266,28.6165627],[-17.7519687,28.5833675],[-17.7622536,28.5591958],[-17.7833086,28.541667],[-17.7831575,28.4936643],[-17.808611,28.4925024],[-17.8060072,28.4468974],[-17.8846298,28.4460601]],[[-18.1661033,27.7851643],[-18.163494,27.6949247],[-18.0889827,27.6963366],[-18.0873398,27.6738724],[-18.0364092,27.6753701],[-18.0350079,27.6302571],[-17.9589987,27.6323976],[-17.8603269,27.7926025],[-17.8630328,27.8368793],[-17.8884015,27.8364947],[-17.8891263,27.8590536],[-17.9906491,27.8567467],[-18.0386803,27.7655831],[-18.1146412,27.7637873],[-18.1154627,27.7863613],[-18.1661033,27.7851643]],[[-17.36038,28.0639801],[-17.3629657,28.1757247],[-17.3375583,28.1763688],[-17.3384577,28.2213012],[-17.1857883,28.2238767],[-17.0820788,28.1351849],[-17.0808422,28.0679977],[-17.1315446,28.0668073],[-17.1563337,28.0214628],[-17.2321063,28.0203711],[-17.2319938,27.9980388],[-17.2576823,27.9978403],[-17.257851,28.0199741],[-17.3086658,28.0192298],[-17.36038,28.0639801]],[[-16.9278171,28.3275779],[-16.9286591,28.3721879],[-16.8776666,28.3729288],[-16.8780707,28.3954191],[-16.5214259,28.4226146],[-16.4457117,28.491135],[-16.4462506,28.535972],[-16.4205859,28.5362679],[-16.4209227,28.5588419],[-16.3443329,28.5597589],[-16.3446023,28.5822095],[-16.1912541,28.5837179],[-16.1916246,28.6068435],[-16.1279344,28.6078193],[-16.1277997,28.5921762],[-16.0995079,28.5925015],[-16.0993395,28.5163822],[-16.1648148,28.5161158],[-16.1647474,28.4938583],[-16.2385755,28.4484704],[-16.2653516,28.4476116],[-16.2658569,28.4030038],[-16.3167484,28.4017594],[-16.3163105,28.380189],[-16.3420763,28.3795075],[-16.3408301,28.2892963],[-16.415837,28.1976134],[-16.415096,28.1311312],[-16.5153297,28.0164796],[-16.6168433,28.01532],[-16.6168096,27.9930469],[-16.7184243,27.9919168],[-16.7190979,28.0371426],[-16.7446952,28.0367859],[-16.7453351,28.0818146],[-16.7706967,28.0816065],[-16.8223966,28.1259036],[-16.8231712,28.1708652],[-16.8487012,28.1707464],[-16.8502842,28.260791],[-16.8756457,28.2605537],[-16.8760836,28.2832162],[-16.9015125,28.2827713],[-16.9023882,28.3279337],[-16.9278171,28.3275779]],[[-15.8537427,27.9008901],[-15.8542032,27.9901812],[-15.828953,27.9906555],[-15.8291065,28.035578],[-15.7782992,28.0363232],[-15.7532793,28.0814298],[-15.7278756,28.0815652],[-15.7282593,28.1718567],[-15.4989741,28.1728039],[-15.4987438,28.1504075],[-15.4497785,28.1507459],[-15.4501622,28.1961425],[-15.3972827,28.1961425],[-15.3964385,28.0383554],[-15.3710348,28.0380167],[-15.3706511,28.0153212],[-15.3457847,28.0153212],[-15.3454777,27.9254406],[-15.3708046,27.9252372],[-15.3705743,27.8352137],[-15.395978,27.8347387],[-15.4209979,27.7879673],[-15.4718052,27.7893932],[-15.471882,27.7666454],[-15.522766,27.7667813],[-15.5477092,27.7216112],[-15.6236132,27.7213395],[-15.6241504,27.741991],[-15.7007451,27.7433495],[-15.801669,27.8110501],[-15.8537427,27.9008901]],[[-14.5215621,28.0467778],[-14.5224358,28.1184131],[-14.4157526,28.1156076],[-14.2168794,28.2278805],[-14.2153651,28.33903],[-14.1641672,28.4528287],[-14.1115132,28.4747955],[-14.0335806,28.7226671],[-13.9565217,28.7449351],[-13.9561722,28.7665857],[-13.8290221,28.7664325],[-13.8289639,28.7879765],[-13.8000741,28.7879255],[-13.8012972,28.7189894],[-13.827566,28.719347],[-13.8278572,28.6517968],[-13.8025786,28.651899],[-13.8033941,28.5384172],[-13.8288474,28.5384684],[-13.8315061,28.3970177],[-13.9158189,28.2241438],[-13.9856445,28.2235696],[-14.0369588,28.1795787],[-14.1387139,28.1799894],[-14.1386556,28.1579103],[-14.2153651,28.1578076],[-14.2147244,28.1118888],[-14.2913173,28.0452356],[-14.3319673,28.0368713],[-14.4457846,28.0469834],[-14.4466583,28.0657961],[-14.4962835,28.0682631],[-14.495934,28.0458525],[-14.5215621,28.0467778]],[[-13.800662,28.8456579],[-13.8009273,28.8231121],[-13.775688,28.8230539],[-13.69729,28.8898184],[-13.69729,28.9127744],[-13.6072498,28.9117991],[-13.4388551,29.0002417],[-13.4374559,29.1351289],[-13.4117005,29.1349931],[-13.4105556,29.2229789],[-13.4592801,29.255586],[-13.4597392,29.2942023],[-13.5091254,29.2945638],[-13.5100581,29.3163453],[-13.5635382,29.3172941],[-13.5640564,29.2713764],[-13.5389228,29.2711956],[-13.5389747,29.2500375],[-13.5661293,29.2501279],[-13.5665956,29.2030039],[-13.5156549,29.2022349],[-13.5156549,29.1820579],[-13.5398038,29.1827819],[-13.5408921,29.137528],[-13.65782,29.1368528],[-13.713222,29.0935079],[-13.7663353,29.0934533],[-13.8502463,29.0165937],[-13.8518224,28.983425],[-13.8524443,28.914861],[-13.9013122,28.89245],[-13.9024005,28.8469779],[-13.800662,28.8456579]],[[1.6479916,38.9990693],[1.7321668,38.9993635],[1.7314703,39.0441733],[1.6489512,39.0431944],[1.6481552,39.1276358],[1.3948608,39.1265691],[1.3954412,39.0864199],[1.2281145,39.0852615],[1.2291095,39.0028958],[1.1448657,39.0018003],[1.1452803,38.8319988],[1.3113632,38.8331615],[1.3121924,38.7906483],[1.3946949,38.7916178],[1.3951924,38.7529597],[1.3112803,38.7519251],[1.3125919,38.6238804],[1.6489036,38.6251112],[1.6480745,38.7111504],[1.58456,38.7101152],[1.5811604,38.7005387],[1.5491544,38.7002798],[1.5197188,38.7092094],[1.50355,38.7253185],[1.4813282,38.9155064],[1.5518906,38.9254411],[1.5667328,38.9566554],[1.6487378,38.9583318],[1.6479916,38.9990693]],[[2.5450749,39.4166673],[2.43933,39.4161122],[2.438714,39.4846853],[2.439022,39.4993424],[2.3122308,39.4993424],[2.3119228,39.5417911],[2.2290722,39.5409994],[2.2283536,39.6260571],[2.3460076,39.6270851],[2.9270445,39.9601558],[3.1456647,39.9600498],[3.1460753,40.0019797],[3.2313899,40.0019797],[3.2312872,39.8329231],[3.1482313,39.8331596],[3.1484366,39.7935717],[3.4814817,39.7931773],[3.4803472,39.5959027],[3.3150618,39.4784606],[3.3146179,39.3785504],[3.0830178,39.2499355],[2.9798608,39.2501482],[2.9790395,39.3334971],[2.7287424,39.3334177],[2.7288451,39.4581361],[2.6456865,39.4577397],[2.6453785,39.4996593],[2.5452802,39.4994216],[2.5450749,39.4166673]],[[3.8120402,40.0434431],[3.729082,40.0437979],[3.7286185,39.9584155],[3.8126633,39.9576011],[3.8122771,39.9164393],[3.9608975,39.9159813],[4.1938142,39.791308],[4.3150279,39.7905799],[4.3159934,39.8329294],[4.3987393,39.8320396],[4.3973664,39.9185834],[4.3158003,39.9193274],[4.3161865,40.0433985],[4.2318959,40.0443594],[4.2324752,40.0847793],[4.1491501,40.086109],[4.1490623,40.1255157],[4.0627981,40.1272166],[4.0624217,40.0849941],[3.8128687,40.085294],[3.8120402,40.0434431]],[[-8.8910646,41.8228891],[-9.1092038,42.5751065],[-9.0365469,42.730656],[-9.0883419,42.7269569],[-9.1466113,42.7750272],[-9.2185488,42.9016271],[-9.2760988,42.8605106],[-9.3099094,42.9311297],[-9.2789763,42.9821991],[-9.3099094,43.0600377],[-9.2523594,43.1041725],[-9.2314975,43.1703151],[-9.1473307,43.210176],[-9.06748,43.1991644],[-9.0336694,43.2426748],[-8.99842,43.2447709],[-8.9998588,43.2955793],[-8.9372732,43.3055265],[-8.92936,43.326986],[-8.8638969,43.3290792],[-8.8761263,43.3740655],[-8.8221732,43.3735426],[-8.785485,43.3191358],[-8.7063538,43.305003],[-8.6099575,43.3296025],[-8.5509688,43.3233227],[-8.5243519,43.3364048],[-8.5250713,43.3646525],[-8.45745,43.3918416],[-8.3610538,43.4111803],[-8.3603344,43.4634161],[-8.3344369,43.5797394],[-8.2776063,43.5708796],[-8.0646713,43.7239184],[-7.9992081,43.7233986],[-7.9171994,43.7826357],[-7.8560525,43.7914643],[-7.83591,43.7374337],[-7.6628443,43.809819],[-7.3188932,43.6782695],[-7.1997467,43.5830817],[-6.2488228,43.6075032],[-6.1229322,43.5790105],[-5.8520425,43.6798953],[-5.6036334,43.5708672],[-5.2855347,43.5619084],[-5.1787525,43.4991591],[-4.9089869,43.4836655],[-4.6156167,43.4192021],[-4.1839917,43.4249168],[-3.8029478,43.5195394],[-3.7400025,43.4869277],[-3.5612827,43.5423572],[-3.1083013,43.3816347],[-2.9385737,43.4624573],[-2.7452417,43.4755094],[-2.3046245,43.3170625],[-1.9854018,43.3563045],[-1.8552841,43.3972545],[-1.769802,43.3964383],[-1.7700492,43.3760501],[-1.7100474,43.3756908],[-1.7113451,43.3312527],[-1.7225915,43.3131806],[-1.6890375,43.3129108],[-1.6881106,43.3341294],[-1.6446695,43.3337248],[-1.6449785,43.3133155],[-1.6029903,43.3129528],[-1.6034352,43.2926624],[-1.5635905,43.2921227],[-1.5630468,43.3133844],[-1.4779905,43.3128355],[-1.3667723,43.2761368],[-1.3568809,43.2381533],[-1.3703692,43.1712972],[-1.4423067,43.0833554],[-1.4198262,43.0603647],[-1.3730668,43.051166],[-1.3640746,43.1115893],[-1.3020285,43.135217],[-1.2354864,43.1332484],[-1.2795481,43.0774443],[-1.1923239,43.0649635],[-1.0061856,43.0077821],[-0.942341,42.9748951],[-0.7562028,42.9821318],[-0.7148387,42.9610774],[-0.6968543,42.9031405],[-0.5511809,42.8220693],[-0.5044215,42.8484456],[-0.4288871,42.8200906],[-0.3164848,42.8655842],[-0.1456332,42.810856],[-0.0314324,42.7124874],[0.1861785,42.7540985],[0.3021777,42.7177729],[0.3642238,42.7428729],[0.4487504,42.7144695],[0.6276949,42.7223973],[0.6411832,42.8576747],[0.7149192,42.882718],[0.9675996,42.8181119],[1.108777,42.7989808],[1.1753192,42.7342872],[1.3632559,42.7415521],[1.4113736,42.7093914],[1.4806054,42.7103407],[1.4813006,42.5010664],[1.6443591,42.5020345],[1.6432777,42.5424539],[1.730407,42.5434214],[1.7316429,42.5011803],[2.0638621,42.5016359],[2.0645572,42.4590247],[2.3969309,42.4599364],[2.3976786,42.4178363],[2.4804823,42.4179732],[2.4809767,42.3759441],[2.6447922,42.3762636],[2.6444832,42.4592447],[2.8113266,42.4596094],[2.8112648,42.5010358],[3.063878,42.5008535],[3.063878,42.4591535],[3.2307832,42.4593359],[3.2304935,42.3764363],[3.3141469,42.3760369],[3.3141243,42.3339864],[3.397855,42.3340435],[3.3973912,42.290094],[3.3138923,42.2908368],[3.3139695,42.2070151],[3.1475896,42.2073012],[3.1475896,42.1260612],[3.2305478,42.1260039],[3.2466753,41.9529359],[3.1945206,41.8558943],[3.060537,41.7647419],[2.7835777,41.6371796],[2.26293,41.4271601],[2.1649151,41.2989297],[1.86008,41.2232228],[1.3763003,41.116273],[1.1793714,41.0464585],[1.0858526,41.048493],[0.758537,40.8195599],[0.9114042,40.733761],[0.8781331,40.6751363],[0.6650182,40.5358666],[0.5580112,40.5502166],[0.433919,40.3757589],[0.2675635,40.1919192],[0.1641534,40.0647234],[0.0751307,40.0144671],[0.010387,39.8952188],[-0.0939224,39.8116904],[-0.1847435,39.6311716],[-0.2908513,39.5036254],[-0.2863552,39.333431],[-0.1856427,39.1774612],[-0.2135185,39.1558487],[-0.1110076,38.9722246],[0.0094878,38.8826835],[0.1218901,38.872183],[0.2342925,38.798636],[0.2558737,38.7264162],[0.0958128,38.6133825],[-0.0022021,38.6070586],[-0.0570544,38.5269073],[-0.2719677,38.4762395],[-0.379874,38.3931234],[-0.3834708,38.3381297],[-0.4509122,38.3310763],[-0.5048654,38.2830943],[-0.4823849,38.1948095],[-0.429331,38.1658287],[-0.4545091,38.148859],[-0.5839966,38.1721913],[-0.6136708,38.1198599],[-0.6370505,37.9612228],[-0.6811123,37.9456238],[-0.7323677,37.8810656],[-0.7215771,37.7830562],[-0.688306,37.7340026],[-0.6641461,37.6231485],[-0.7193941,37.5878413],[-0.9196258,37.5375806],[-1.1107098,37.5164093],[-1.3383246,37.5286671],[-1.4408917,37.3903714],[-1.6766966,37.2765189],[-1.8540816,36.9122889],[-2.0683486,36.6929117],[-2.2158766,36.6619233],[-2.3721861,36.7801753],[-2.6812926,36.6591056],[-2.9201476,36.6675585],[-3.09402,36.712625],[-3.4610839,36.6548788],[-3.7280395,36.6929117],[-4.3743529,36.6633322],[-4.6571151,36.4404171],[-4.9188018,36.4531321],[-5.1699508,36.3513541],[-5.2841094,36.1970201],[-5.2680911,36.1241812],[-5.3524784,36.1224654],[-5.3516094,36.0401413],[-5.4365759,36.0388921],[-5.4353207,36.0034384],[-5.6888562,36.0036518],[-5.6899635,36.0405317],[-5.85506,36.0385595],[-5.8566821,36.1242077],[-5.9384817,36.1221487],[-5.9400265,36.1655625],[-5.9983445,36.1645024],[-6.0357297,36.1780957],[-6.0775178,36.2224132],[-6.1506113,36.2864561],[-6.231541,36.3770075],[-6.3358504,36.5310643],[-6.3214629,36.5816265],[-6.404191,36.6234958],[-6.4743301,36.7489673],[-6.4158808,36.7993866],[-6.490516,36.9173818],[-6.6298949,37.0194012],[-6.8744824,37.1083766],[-7.0426363,37.1850699],[-7.2647434,37.1843535],[-7.3753473,37.1535419],[-7.408316,37.1682196],[-7.4202886,37.2118318],[-7.4249231,37.2350505],[-7.4380543,37.2451969],[-7.4459717,37.3326142],[-7.4480958,37.3909382],[-7.4696271,37.4075829],[-7.4647029,37.4530494],[-7.5019723,37.516411],[-7.5191587,37.5229203],[-7.5219588,37.5723727],[-7.4501271,37.6695835],[-7.4249019,37.7599222],[-7.316662,37.839974],[-7.268329,37.988952],[-7.1536786,38.0155235],[-7.1177098,38.0553626],[-7.0142997,38.0243785],[-6.9963153,38.1075633],[-6.9614706,38.201254],[-7.080617,38.1570753],[-7.3402665,38.4402363],[-7.2638329,38.7380741],[-7.0435243,38.8729667],[-7.0615086,38.907962],[-6.9693387,39.0198308],[-7.0008114,39.0887867],[-7.1536786,39.0957658],[-7.1525545,39.1602899],[-7.2447245,39.1968854],[-7.2559647,39.2813308],[-7.3368944,39.3535074],[-7.3279022,39.4559917],[-7.5144901,39.5886496],[-7.5527069,39.6795427],[-7.0502684,39.6752171],[-6.9951913,39.8195433],[-6.9221297,39.8790868],[-6.886161,40.0229854],[-7.0412762,40.1347927],[-7.0176717,40.266146],[-6.8086034,40.3450071],[-6.8681766,40.4451649],[-6.8535643,40.6066433],[-6.837828,40.8757589],[-6.9536024,41.0370445],[-6.8018592,41.0395879],[-6.7681385,41.138706],[-6.6411239,41.2655616],[-6.5624422,41.2630269],[-6.217367,41.5791017],[-6.3162811,41.644652],[-6.5152332,41.6412921],[-6.5871707,41.6883151],[-6.5478299,41.8559743],[-6.6298836,41.9112057],[-7.1334461,41.9404756],[-7.1682909,41.8718791],[-7.4256922,41.7847727],[-7.9539833,41.8459271],[-8.130455,41.7805819],[-8.2518495,41.9078597],[-8.1293309,42.0348842],[-8.2484774,42.1008034],[-8.3676239,42.0557521],[-8.6070409,42.0340493],[-8.8910646,41.8228891]]],"terms_text":"PNOA","best":true},{"id":"Slovakia-Historic-Maps","name":"Slovakia Historic Maps","type":"tms","template":"http://tms.freemap.sk/historicke/{zoom}/{x}/{y}.png","scaleExtent":[0,12],"polygon":[[[16.8196949,47.4927236],[16.8196949,49.5030322],[22.8388318,49.5030322],[22.8388318,47.4927236],[16.8196949,47.4927236]]]},{"id":"South_Africa-CD_NGI-Aerial","name":"South Africa CD:NGI Aerial","type":"tms","template":"http://{switch:a,b,c}.aerial.openstreetmap.org.za/ngi-aerial/{zoom}/{x}/{y}.jpg","scaleExtent":[1,22],"polygon":[[[17.8396817,-32.7983384],[17.8893509,-32.6972835],[18.00364,-32.6982187],[18.0991679,-32.7485251],[18.2898747,-32.5526645],[18.2930182,-32.0487089],[18.105455,-31.6454966],[17.8529257,-31.3443951],[17.5480046,-30.902171],[17.4044506,-30.6374731],[17.2493704,-30.3991663],[16.9936977,-29.6543552],[16.7987996,-29.19437],[16.5494139,-28.8415949],[16.4498691,-28.691876],[16.4491046,-28.5515766],[16.6002551,-28.4825663],[16.7514057,-28.4486958],[16.7462192,-28.2458973],[16.8855148,-28.04729],[16.9929502,-28.0244005],[17.0529659,-28.0257086],[17.1007562,-28.0338839],[17.2011527,-28.0930546],[17.2026346,-28.2328424],[17.2474611,-28.2338215],[17.2507953,-28.198892],[17.3511919,-28.1975861],[17.3515624,-28.2442655],[17.4015754,-28.2452446],[17.4149122,-28.3489751],[17.4008345,-28.547997],[17.4526999,-28.5489733],[17.4512071,-28.6495106],[17.4983599,-28.6872054],[17.6028204,-28.6830048],[17.6499732,-28.6967928],[17.6525928,-28.7381457],[17.801386,-28.7381457],[17.9994276,-28.7560602],[18.0002748,-28.7956172],[18.1574507,-28.8718055],[18.5063811,-28.8718055],[18.6153564,-28.8295875],[18.9087513,-28.8277516],[19.1046973,-28.9488548],[19.1969071,-28.9378513],[19.243012,-28.8516164],[19.2314858,-28.802963],[19.2587296,-28.7009928],[19.4431493,-28.6973163],[19.5500289,-28.4958332],[19.6967264,-28.4939914],[19.698822,-28.4479358],[19.8507587,-28.4433291],[19.8497109,-28.4027818],[19.9953605,-28.399095],[19.9893671,-24.7497859],[20.2916682,-24.9192346],[20.4724562,-25.1501701],[20.6532441,-25.4529449],[20.733265,-25.6801957],[20.8281046,-25.8963498],[20.8429232,-26.215851],[20.6502804,-26.4840868],[20.6532441,-26.8204869],[21.0889134,-26.846933],[21.6727695,-26.8389998],[21.7765003,-26.6696268],[21.9721069,-26.6431395],[22.2803355,-26.3274702],[22.5707817,-26.1333967],[22.7752795,-25.6775246],[23.0005235,-25.2761948],[23.4658301,-25.2735148],[23.883717,-25.597366],[24.2364017,-25.613402],[24.603905,-25.7896563],[25.110704,-25.7389432],[25.5078447,-25.6855376],[25.6441766,-25.4823781],[25.8419267,-24.7805437],[25.846641,-24.7538456],[26.3928487,-24.6332894],[26.4739066,-24.5653312],[26.5089966,-24.4842437],[26.5861946,-24.4075775],[26.7300635,-24.3014458],[26.8567384,-24.2499463],[26.8574402,-24.1026901],[26.9215471,-23.8990957],[26.931831,-23.8461891],[26.9714827,-23.6994344],[27.0006074,-23.6367644],[27.0578041,-23.6052574],[27.1360547,-23.5203437],[27.3339623,-23.3973792],[27.5144057,-23.3593929],[27.5958145,-23.2085465],[27.8098634,-23.0994957],[27.8828506,-23.0620496],[27.9382928,-22.9496487],[28.0407556,-22.8255118],[28.2056786,-22.6552861],[28.3397223,-22.5639374],[28.4906093,-22.560697],[28.6108769,-22.5400248],[28.828175,-22.4550173],[28.9285324,-22.4232328],[28.9594116,-22.3090081],[29.0162574,-22.208335],[29.2324117,-22.1693453],[29.3531213,-22.1842926],[29.6548952,-22.1186426],[29.7777102,-22.1361956],[29.9292989,-22.1849425],[30.1166795,-22.2830348],[30.2563377,-22.2914767],[30.3033582,-22.3395204],[30.5061784,-22.3057617],[30.8374279,-22.284983],[31.0058599,-22.3077095],[31.1834152,-22.3232913],[31.2930586,-22.3674647],[31.5680579,-23.1903385],[31.5568311,-23.4430809],[31.6931122,-23.6175209],[31.7119696,-23.741136],[31.7774743,-23.8800628],[31.8886337,-23.9481098],[31.9144386,-24.1746736],[31.9948307,-24.3040878],[32.0166656,-24.4405988],[32.0077331,-24.6536578],[32.019643,-24.9140701],[32.035523,-25.0849767],[32.019643,-25.3821442],[31.9928457,-25.4493771],[31.9997931,-25.5165725],[32.0057481,-25.6078978],[32.0057481,-25.6624806],[31.9362735,-25.8403721],[31.9809357,-25.9546537],[31.8687838,-26.0037251],[31.4162062,-25.7277683],[31.3229117,-25.7438611],[31.2504595,-25.8296526],[31.1393001,-25.9162746],[31.1164727,-25.9912361],[30.9656135,-26.2665756],[30.8921689,-26.3279703],[30.8534616,-26.4035568],[30.8226943,-26.4488849],[30.8022583,-26.5240694],[30.8038369,-26.8082089],[30.9020939,-26.7807451],[30.9100338,-26.8489495],[30.9824859,-26.9082627],[30.976531,-27.0029222],[31.0034434,-27.0441587],[31.1543322,-27.1980416],[31.5015607,-27.311117],[31.9700183,-27.311117],[31.9700183,-27.120472],[31.9769658,-27.050664],[32.0002464,-26.7983892],[32.1069826,-26.7984645],[32.3114546,-26.8479493],[32.899986,-26.8516059],[32.886091,-26.9816971],[32.709427,-27.4785436],[32.6240724,-27.7775144],[32.5813951,-28.07479],[32.5387178,-28.2288046],[32.4275584,-28.5021568],[32.3640388,-28.5945699],[32.0702603,-28.8469827],[31.9878832,-28.9069497],[31.7764818,-28.969487],[31.4638459,-29.2859343],[31.359634,-29.3854348],[31.1680825,-29.6307408],[31.064863,-29.7893535],[31.0534493,-29.8470469],[31.0669933,-29.8640319],[31.0455459,-29.9502017],[30.9518556,-30.0033946],[30.8651833,-30.1024093],[30.7244725,-30.392502],[30.3556256,-30.9308873],[30.0972364,-31.2458274],[29.8673136,-31.4304296],[29.7409393,-31.5014699],[29.481312,-31.6978686],[28.8943171,-32.2898903],[28.5497137,-32.5894641],[28.1436499,-32.8320732],[28.0748735,-32.941689],[27.8450942,-33.082869],[27.3757956,-33.3860685],[26.8805407,-33.6458951],[26.5916871,-33.7480756],[26.4527308,-33.7935795],[26.206754,-33.7548943],[26.0077897,-33.7223961],[25.8055494,-33.7524272],[25.7511073,-33.8006512],[25.6529079,-33.8543597],[25.6529079,-33.9469768],[25.7195789,-34.0040115],[25.7202807,-34.0511235],[25.5508915,-34.063151],[25.3504571,-34.0502627],[25.2810609,-34.0020322],[25.0476316,-33.9994588],[24.954724,-34.0043594],[24.9496586,-34.1010363],[24.8770358,-34.1506456],[24.8762914,-34.2005281],[24.8532574,-34.2189562],[24.7645287,-34.2017946],[24.5001356,-34.2003254],[24.3486733,-34.1163824],[24.1988819,-34.1019039],[23.9963377,-34.0514443],[23.8017509,-34.0524332],[23.7493589,-34.0111855],[23.4973536,-34.009014],[23.4155191,-34.0434586],[23.4154284,-34.1140433],[22.9000853,-34.0993009],[22.8412418,-34.0547911],[22.6470321,-34.0502627],[22.6459843,-34.0072768],[22.570016,-34.0064081],[22.5050499,-34.0645866],[22.2519968,-34.0645866],[22.2221334,-34.1014701],[22.1621197,-34.1057019],[22.1712431,-34.1521766],[22.1576913,-34.2180897],[22.0015632,-34.2172232],[21.9496952,-34.3220009],[21.8611528,-34.4007145],[21.5614708,-34.4020114],[21.5468011,-34.3661242],[21.501744,-34.3669892],[21.5006961,-34.4020114],[21.4194886,-34.4465247],[21.1978706,-34.4478208],[21.0988193,-34.3991325],[21.0033746,-34.3753872],[20.893192,-34.3997115],[20.8976647,-34.4854003],[20.7446802,-34.4828092],[20.5042011,-34.486264],[20.2527197,-34.701477],[20.0803502,-34.8361855],[19.9923317,-34.8379056],[19.899074,-34.8275845],[19.8938348,-34.7936018],[19.5972963,-34.7961833],[19.3929677,-34.642015],[19.2877095,-34.6404784],[19.2861377,-34.5986563],[19.3474363,-34.5244458],[19.3285256,-34.4534372],[19.098001,-34.449981],[19.0725583,-34.3802371],[19.0023531,-34.3525593],[18.9520568,-34.3949373],[18.7975006,-34.3936403],[18.7984174,-34.1016376],[18.501748,-34.1015292],[18.4999545,-34.3616945],[18.4477325,-34.3620007],[18.4479944,-34.3522691],[18.3974362,-34.3514041],[18.3971742,-34.3022959],[18.3565705,-34.3005647],[18.3479258,-34.2020436],[18.2972095,-34.1950274],[18.2951139,-33.9937138],[18.3374474,-33.9914079],[18.3476638,-33.8492427],[18.3479258,-33.781555],[18.4124718,-33.7448849],[18.3615477,-33.6501624],[18.2992013,-33.585591],[18.2166839,-33.448872],[18.1389858,-33.3974083],[17.9473472,-33.1602647],[17.8855247,-33.0575732],[17.8485884,-32.9668505],[17.8396817,-32.8507302],[17.8396817,-32.7983384]]],"best":true},{"id":"South-Tyrol-Orthofoto2011","name":"South Tyrol Orthofoto 2011","type":"tms","template":"http://geoservices.buergernetz.bz.it/geoserver/gwc/service/wmts/?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=P_BZ_OF_2011_EPSG3857&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","description":"Orthophoto of South Tyrol from 2011","scaleExtent":[0,18],"polygon":[[[10.38615,46.68821],[10.39201,46.69016],[10.40215,46.70624],[10.41274,46.70821],[10.41622,46.71479],[10.4168,46.71847],[10.39934,46.73435],[10.43464,46.75356],[10.44107,46.75413],[10.44011,46.77149],[10.42123,46.78861],[10.42845,46.79755],[10.43851,46.79869],[10.44925,46.80462],[10.45602,46.81635],[10.45438,46.82221],[10.4583,46.82478],[10.45513,46.83059],[10.45906,46.83548],[10.46483,46.83624],[10.46229,46.8413],[10.46987,46.84933],[10.46819,46.8553],[10.47838,46.86013],[10.48372,46.85543],[10.49628,46.85305],[10.49931,46.84857],[10.52124,46.84653],[10.5527,46.8511],[10.55795,46.84695],[10.55264,46.8408],[10.55536,46.84087],[10.58883,46.85125],[10.59502,46.85829],[10.60936,46.8597],[10.62441,46.86558],[10.64858,46.86655],[10.66787,46.87651],[10.67297,46.87138],[10.69112,46.86861],[10.69786,46.86339],[10.69508,46.85308],[10.70594,46.84786],[10.71763,46.84795],[10.72333,46.83892],[10.75621,46.83383],[10.76481,46.82409],[10.76387,46.81971],[10.75239,46.81387],[10.74506,46.80223],[10.7276,46.79709],[10.73122,46.78925],[10.75722,46.78624],[10.77744,46.79149],[10.78678,46.79735],[10.81439,46.77662],[10.82479,46.77472],[10.83129,46.78138],[10.84112,46.78282],[10.85354,46.77506],[10.86845,46.77313],[10.86993,46.7669],[10.88294,46.76393],[10.88962,46.76529],[10.8951,46.77092],[10.90527,46.76911],[10.92299,46.7764],[10.92821,46.77408],[10.94388,46.77648],[10.97522,46.77361],[10.97932,46.77014],[10.99475,46.76804],[11.01397,46.77317],[11.02328,46.76715],[11.0346,46.79428],[11.04234,46.801],[11.03792,46.80562],[11.05633,46.80928],[11.07279,46.82092],[11.08171,46.82252],[11.0762,46.83384],[11.06887,46.83793],[11.07303,46.84345],[11.06988,46.85348],[11.08742,46.87927],[11.09961,46.88922],[11.09538,46.89178],[11.09795,46.89844],[11.0946,46.91247],[11.10792,46.91706],[11.10804,46.92632],[11.11418,46.93234],[11.13851,46.92865],[11.16322,46.94091],[11.16642,46.94479],[11.16114,46.94979],[11.1637,46.96677],[11.17598,46.96367],[11.18658,46.97062],[11.19527,46.97152],[11.20418,46.96877],[11.20688,46.96403],[11.22047,46.97025],[11.24139,46.9708],[11.24865,46.97517],[11.25582,46.97535],[11.26272,46.98169],[11.27662,46.98168],[11.28762,46.98699],[11.30709,46.98525],[11.3205,46.99345],[11.33765,46.98606],[11.34516,46.99169],[11.35932,46.99154],[11.37697,46.98025],[11.38324,46.97168],[11.40465,46.96609],[11.43929,46.97601],[11.45134,46.99294],[11.46803,46.99582],[11.46859,47.003],[11.47831,47.01201],[11.50238,47.01073],[11.50313,47.00808],[11.51366,47.00595],[11.51679,47.00091],[11.53381,46.99233],[11.53846,46.98519],[11.55297,46.99149],[11.57663,46.99657],[11.58,47.00277],[11.58879,47.00641],[11.59901,47.00657],[11.60944,47.01207],[11.62697,47.01437],[11.63629,47.00383],[11.66542,46.99304],[11.6885,46.99658],[11.71226,46.99416],[11.72897,46.97322],[11.74698,46.97013],[11.76411,46.97412],[11.78106,46.99342],[11.81526,46.991],[11.83564,46.99417],[11.84396,47.0025],[11.85192,47.0014],[11.86722,47.01252],[11.87393,47.01136],[11.8794,47.01714],[11.89137,47.01728],[11.91627,47.03422],[11.9329,47.03864],[11.94688,47.03464],[11.95457,47.04374],[11.96773,47.04158],[11.97912,47.0511],[11.98587,47.04815],[11.99534,47.05064],[12.02037,47.04821],[12.02968,47.05127],[12.03353,47.0583],[12.04276,47.06228],[12.07543,47.0605],[12.08035,47.06951],[12.09308,47.07791],[12.10329,47.07931],[12.11867,47.07445],[12.13561,47.08171],[12.15125,47.08049],[12.15997,47.08267],[12.18589,47.09322],[12.2278,47.08302],[12.24228,47.06892],[12.23786,47.0644],[12.21821,47.05795],[12.2182,47.04483],[12.20552,47.02595],[12.18048,47.02414],[12.16423,47.01782],[12.14786,47.02357],[12.12723,47.01218],[12.12285,47.00662],[12.1322,46.99339],[12.12974,46.98593],[12.13977,46.982],[12.13808,46.96514],[12.13328,46.96292],[12.13882,46.95764],[12.15927,46.95133],[12.1702,46.93758],[12.15414,46.91654],[12.14675,46.91413],[12.16205,46.908],[12.16959,46.91121],[12.19154,46.90682],[12.20106,46.8965],[12.2022,46.88806],[12.21663,46.87517],[12.22147,46.88084],[12.23125,46.88146],[12.2345,46.88919],[12.24162,46.89192],[12.27486,46.88512],[12.27979,46.87921],[12.27736,46.87319],[12.29326,46.86566],[12.2912,46.85704],[12.29733,46.84455],[12.30833,46.84137],[12.30726,46.83271],[12.285,46.81503],[12.29383,46.8027],[12.28905,46.79948],[12.28889,46.79427],[12.28232,46.79153],[12.28539,46.7839],[12.30943,46.78603],[12.35837,46.77583],[12.37036,46.74163],[12.38475,46.71745],[12.40283,46.70811],[12.41103,46.70701],[12.41522,46.70163],[12.42862,46.6997],[12.42943,46.69567],[12.44268,46.68979],[12.47501,46.68756],[12.4795,46.67969],[12.43473,46.66714],[12.40648,46.64167],[12.38115,46.64183],[12.37944,46.63733],[12.3915,46.62765],[12.38577,46.62154],[12.35939,46.61829],[12.34465,46.62376],[12.34034,46.63022],[12.33578,46.62732],[12.3172,46.62876],[12.31785,46.62355],[12.30802,46.61811],[12.28413,46.61623],[12.26982,46.62003],[12.25931,46.62809],[12.24502,46.62326],[12.24198,46.61586],[12.21241,46.60918],[12.20444,46.59836],[12.19228,46.59321],[12.19261,46.62059],[12.1818,46.6192],[12.17117,46.63275],[12.16062,46.63574],[12.1511,46.63215],[12.1436,46.6327],[12.13739,46.64122],[12.12342,46.64475],[12.10949,46.65204],[12.10609,46.65783],[12.09345,46.66123],[12.08826,46.66638],[12.07985,46.66686],[12.07038,46.67386],[12.07173,46.66064],[12.06686,46.65364],[12.07479,46.64329],[12.06837,46.63997],[12.06495,46.62121],[12.05448,46.61778],[12.05318,46.60989],[12.04613,46.60716],[12.05043,46.60016],[12.04763,46.58357],[12.03665,46.57668],[12.0266,46.55871],[12.02189,46.55791],[11.99941,46.53208],[11.99411,46.53345],[11.98704,46.54417],[11.96633,46.54363],[11.95094,46.53869],[11.94719,46.52879],[11.94147,46.52689],[11.93294,46.52631],[11.9121,46.532],[11.8904,46.52175],[11.85192,46.51682],[11.82849,46.50783],[11.82334,46.51315],[11.82391,46.52141],[11.81086,46.53146],[11.79385,46.52023],[11.79189,46.51322],[11.76157,46.50503],[11.74317,46.50391],[11.73202,46.50877],[11.71935,46.50916],[11.71524,46.51245],[11.69889,46.50218],[11.6672,46.49647],[11.64515,46.49743],[11.63849,46.50051],[11.63495,46.49486],[11.64297,46.49346],[11.65174,46.48271],[11.64536,46.47189],[11.64179,46.47439],[11.62679,46.4708],[11.62987,46.46377],[11.61882,46.44325],[11.62143,46.42539],[11.60161,46.39731],[11.60307,46.38924],[11.5932,46.38265],[11.56489,46.38018],[11.55878,46.35076],[11.55249,46.34418],[11.54423,46.34483],[11.53837,46.35015],[11.52445,46.35502],[11.47969,46.36277],[11.48052,46.3551],[11.46322,46.34922],[11.45556,46.33396],[11.42105,46.32441],[11.40517,46.32387],[11.39865,46.31426],[11.39994,46.30709],[11.39569,46.3083],[11.38188,46.30052],[11.36088,46.29906],[11.36078,46.29682],[11.38256,46.29177],[11.3871,46.28143],[11.39609,46.27423],[11.39862,46.264],[11.38756,46.26029],[11.37347,46.2629],[11.36836,46.26135],[11.35783,46.26481],[11.35495,46.27564],[11.33912,46.28306],[11.33379,46.29049],[11.33471,46.2962],[11.3129,46.28256],[11.31737,46.27303],[11.30645,46.25786],[11.29124,46.2604],[11.24743,46.22933],[11.20622,46.2187],[11.18267,46.22496],[11.17077,46.23806],[11.17994,46.24434],[11.18351,46.25269],[11.18935,46.25354],[11.19448,46.2461],[11.20029,46.25566],[11.16604,46.26129],[11.14885,46.27904],[11.13725,46.28336],[11.14293,46.28934],[11.15847,46.29059],[11.16439,46.2986],[11.1761,46.30346],[11.1847,46.32104],[11.18894,46.32151],[11.18696,46.32673],[11.1942,46.33016],[11.20204,46.34212],[11.19001,46.35984],[11.19263,46.36578],[11.20393,46.36765],[11.19792,46.37232],[11.21275,46.39804],[11.21345,46.40675],[11.20565,46.4166],[11.21026,46.4206],[11.20347,46.42682],[11.21416,46.43556],[11.21634,46.44255],[11.20903,46.45293],[11.21419,46.45807],[11.21736,46.45731],[11.21886,46.46199],[11.21626,46.47277],[11.20939,46.481],[11.20876,46.49346],[11.19608,46.50241],[11.1924,46.501],[11.18686,46.50734],[11.18002,46.49823],[11.17014,46.49635],[11.16095,46.4878],[11.12934,46.48058],[11.1103,46.49643],[11.10449,46.4948],[11.08812,46.50128],[11.08173,46.53021],[11.05915,46.51508],[11.03795,46.51357],[11.05006,46.50784],[11.05773,46.49235],[11.06278,46.4894],[11.06894,46.46619],[11.07625,46.45487],[11.0778,46.44569],[11.07301,46.44042],[11.05394,46.44849],[11.0414,46.44569],[11.02817,46.46116],[11.00952,46.46917],[11.00462,46.47607],[10.98695,46.48289],[10.96543,46.48103],[10.95791,46.46983],[10.93819,46.46578],[10.9325,46.45831],[10.93332,46.4528],[10.91305,46.44284],[10.89161,46.44366],[10.88324,46.44995],[10.88093,46.44579],[10.87162,46.4438],[10.86174,46.43509],[10.85113,46.43817],[10.80034,46.44185],[10.78906,46.45164],[10.77835,46.47112],[10.76934,46.47609],[10.76463,46.4848],[10.75906,46.48547],[10.74422,46.48333],[10.71753,46.46022],[10.69667,46.4573],[10.68293,46.44846],[10.66821,46.45122],[10.63303,46.44309],[10.61439,46.45098],[10.60128,46.46139],[10.59995,46.46766],[10.57672,46.47237],[10.55875,46.48187],[10.54986,46.49123],[10.53685,46.49062],[10.52657,46.49425],[10.49366,46.49719],[10.48141,46.49337],[10.45714,46.5096],[10.45124,46.53083],[10.45814,46.54215],[10.47056,46.54377],[10.46954,46.54856],[10.47617,46.55749],[10.47321,46.56701],[10.48305,46.5777],[10.48575,46.58921],[10.48221,46.59199],[10.48576,46.59805],[10.48291,46.60512],[10.49055,46.61394],[10.44632,46.63989],[10.40935,46.63389],[10.40011,46.63648],[10.39873,46.6455],[10.38946,46.65862],[10.39057,46.67089],[10.3803,46.68399],[10.38615,46.68821]]],"terms_url":"http://geoservices.buergernetz.bz.it/geokatalog/","terms_text":"© Autonomen Provinz Bozen/Provincia Autonoma di Bolzano CC-BY 3.0"},{"id":"South-Tyrol-Orthofoto2014","name":"South Tyrol Orthofoto 2014","type":"tms","template":"http://geoservices.buergernetz.bz.it/geoserver/gwc/service/wmts/?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=P_BZ_OF_2014_EPSG3857&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","description":"Orthophoto of South Tyrol from 2011","scaleExtent":[0,18],"polygon":[[[12.23442,46.84254],[12.24913,46.82785],[12.24913,46.81945],[12.25753,46.81735],[12.26173,46.80686],[12.26594,46.80686],[12.26804,46.79637],[12.26173,46.79427],[12.27014,46.78587],[12.27224,46.76908],[12.28485,46.76698],[12.29745,46.7439],[12.30166,46.7439],[12.30166,46.7376],[12.28695,46.7376],[12.23652,46.72081],[12.18819,46.71451],[12.16298,46.70192],[12.10835,46.69353],[12.08944,46.68303],[12.05792,46.68093],[12.04531,46.67464],[12.03481,46.67464],[12.03061,46.68303],[12.0096,46.68303],[11.98438,46.66834],[11.94866,46.66414],[11.93816,46.65575],[11.90874,46.64525],[11.89193,46.64525],[11.8457,46.62846],[11.82049,46.62636],[11.80998,46.60748],[11.79528,46.60328],[11.78897,46.59069],[11.78057,46.58859],[11.76586,46.55501],[11.75325,46.54871],[11.73855,46.52982],[11.73224,46.52982],[11.72384,46.51513],[11.71543,46.51513],[11.71333,46.50254],[11.70913,46.50254],[11.70913,46.49624],[11.69652,46.48575],[11.69442,46.47735],[11.66711,46.47525],[11.66711,46.44587],[11.6608,46.44587],[11.64399,46.45846],[11.63769,46.45846],[11.63349,46.44587],[11.62508,46.44797],[11.62508,46.43957],[11.61878,46.43957],[11.61458,46.42278],[11.61037,46.42278],[11.61037,46.41649],[11.62508,46.41229],[11.62508,46.3934],[11.61458,46.38291],[11.60617,46.38291],[11.60407,46.37241],[11.58306,46.37241],[11.58306,46.34932],[11.55995,46.32414],[11.53894,46.32834],[11.53894,46.34513],[11.52423,46.34723],[11.50111,46.34723],[11.49901,46.32834],[11.48851,46.33044],[11.49271,46.32204],[11.41917,46.32414],[11.41707,46.25278],[11.35613,46.24858],[11.34773,46.25698],[11.34563,46.26747],[11.34143,46.26747],[11.33722,46.25068],[11.31201,46.24858],[11.30991,46.25278],[11.3015,46.25278],[11.2889,46.24019],[11.2889,46.2234],[11.25108,46.2234],[11.24898,46.2129],[11.16283,46.215],[11.16283,46.24858],[11.12711,46.24858],[11.13131,46.25278],[11.12291,46.25488],[11.12501,46.29895],[11.16283,46.29895],[11.16283,46.36821],[11.16703,46.36821],[11.16703,46.38081],[11.17543,46.3871],[11.17754,46.3997],[11.20485,46.3997],[11.20695,46.42068],[11.19014,46.42068],[11.19014,46.42698],[11.19435,46.42698],[11.19855,46.44167],[11.20485,46.44587],[11.20695,46.47315],[11.19014,46.47525],[11.18804,46.48365],[11.15232,46.47525],[11.08298,46.47525],[11.08088,46.43537],[11.04096,46.42068],[11.01154,46.42068],[10.99894,46.44587],[10.98843,46.44587],[10.98423,46.45217],[10.96952,46.45217],[10.96112,46.48365],[10.95691,46.48365],[10.95481,46.49414],[10.94851,46.49624],[10.94431,46.50673],[10.91069,46.49624],[10.90018,46.49624],[10.89808,46.51093],[10.85606,46.50254],[10.84135,46.54241],[10.86446,46.54661],[10.86236,46.55081],[10.76571,46.54031],[10.72158,46.55081],[10.59762,46.55291],[10.5619,46.54871],[10.53668,46.55291],[10.50096,46.54871],[10.48415,46.55501],[10.46314,46.55501],[10.47155,46.5676],[10.47365,46.59069],[10.47785,46.59069],[10.47785,46.61797],[10.46944,46.62636],[10.44843,46.63476],[10.42532,46.62846],[10.3938,46.63056],[10.3896,46.64525],[10.3812,46.64735],[10.3833,46.66414],[10.3791,46.66834],[10.3791,46.69353],[10.3854,46.72081],[10.3896,46.72081],[10.3938,46.7376],[10.41692,46.75229],[10.41692,46.78587],[10.42112,46.79847],[10.42532,46.79847],[10.42532,46.80686],[10.43373,46.81106],[10.43793,46.79007],[10.44423,46.78377],[10.44843,46.7439],[10.45264,46.7439],[10.45684,46.72711],[10.46104,46.72711],[10.46524,46.71032],[10.46944,46.71032],[10.47365,46.67254],[10.47995,46.67044],[10.48415,46.65575],[10.48836,46.65575],[10.48415,46.62846],[10.48836,46.62846],[10.48836,46.62217],[10.49886,46.62007],[10.52828,46.62427],[10.49886,46.63056],[10.49886,46.64525],[10.50516,46.64316],[10.49886,46.66204],[10.51777,46.65785],[10.58921,46.66204],[10.63123,46.65365],[10.79302,46.65575],[10.79723,46.65155],[10.88127,46.65155],[10.89178,46.65785],[10.9275,46.66414],[10.94431,46.67464],[10.98003,46.67464],[11.00104,46.68303],[11.02415,46.68303],[11.05147,46.69772],[11.12711,46.70822],[11.13971,46.71242],[11.14392,46.71871],[11.17543,46.72081],[11.19855,46.7334],[11.24898,46.7355],[11.25318,46.72291],[11.2952,46.72921],[11.30571,46.70822],[11.31831,46.70822],[11.33722,46.71871],[11.38555,46.72081],[11.43178,46.7376],[11.50952,46.7439],[11.54734,46.75649],[11.56835,46.75649],[11.58306,46.76698],[11.60617,46.76908],[11.61037,46.77538],[11.69862,46.79427],[11.71753,46.79427],[11.72174,46.79007],[11.73855,46.75859],[11.74905,46.75019],[11.76166,46.70192],[11.76586,46.70192],[11.78687,46.71661],[11.8331,46.72291],[11.86041,46.7376],[11.90874,46.7439],[11.92135,46.75229],[11.95286,46.75859],[11.95917,46.76488],[11.99489,46.77538],[12.00749,46.77538],[12.0096,46.77958],[12.03061,46.78168],[12.05792,46.79427],[12.09995,46.79847],[12.13566,46.81316],[12.15878,46.81316],[12.18609,46.82785],[12.21551,46.83205],[12.23442,46.84254]],[[11.97388,46.96637],[11.99489,46.96007],[11.99489,46.95587],[12.0096,46.95797],[12.0117,46.94748],[12.0159,46.94748],[12.0117,46.94118],[12.018,46.93908],[12.02851,46.92229],[12.00749,46.9118],[11.97388,46.9055],[11.95707,46.89501],[11.91714,46.88871],[11.85831,46.86982],[11.8394,46.86982],[11.80158,46.85303],[11.76166,46.84464],[11.74905,46.83415],[11.68181,46.81945],[11.67971,46.81526],[11.6545,46.81106],[11.64399,46.80476],[11.63769,46.80686],[11.63139,46.82155],[11.62508,46.82155],[11.62298,46.83205],[11.61037,46.84464],[11.61668,46.84884],[11.61458,46.85723],[11.61037,46.85723],[11.61668,46.86563],[11.64609,46.86563],[11.68602,46.88242],[11.69022,46.88871],[11.74905,46.89711],[11.75325,46.90341],[11.78057,46.9076],[11.80158,46.9202],[11.8457,46.92649],[11.87722,46.94118],[11.89613,46.94328],[11.92135,46.95797],[11.96757,46.96217],[11.97388,46.96637]]],"terms_url":"http://geoservices.buergernetz.bz.it/geokatalog/","terms_text":"© Autonomen Provinz Bozen/Provincia Autonoma di Bolzano CC-BY 3.0","best":true},{"id":"South-Tyrol-Topomap","name":"South Tyrol Topomap","type":"tms","template":"http://geoservices.buergernetz.bz.it/geoserver/gwc/service/wmts/?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=P_BZ_BASEMAP_TOPO&STYLE=default&TILEMATRIXSET=GoogleMapsCompatible&TILEMATRIX=GoogleMapsCompatible%3A{zoom}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg","description":"Topographical basemap of South Tyrol","scaleExtent":[0,20],"polygon":[[[10.38615,46.68821],[10.39201,46.69016],[10.40215,46.70624],[10.41274,46.70821],[10.41622,46.71479],[10.4168,46.71847],[10.39934,46.73435],[10.43464,46.75356],[10.44107,46.75413],[10.44011,46.77149],[10.42123,46.78861],[10.42845,46.79755],[10.43851,46.79869],[10.44925,46.80462],[10.45602,46.81635],[10.45438,46.82221],[10.4583,46.82478],[10.45513,46.83059],[10.45906,46.83548],[10.46483,46.83624],[10.46229,46.8413],[10.46987,46.84933],[10.46819,46.8553],[10.47838,46.86013],[10.48372,46.85543],[10.49628,46.85305],[10.49931,46.84857],[10.52124,46.84653],[10.5527,46.8511],[10.55795,46.84695],[10.55264,46.8408],[10.55536,46.84087],[10.58883,46.85125],[10.59502,46.85829],[10.60936,46.8597],[10.62441,46.86558],[10.64858,46.86655],[10.66787,46.87651],[10.67297,46.87138],[10.69112,46.86861],[10.69786,46.86339],[10.69508,46.85308],[10.70594,46.84786],[10.71763,46.84795],[10.72333,46.83892],[10.75621,46.83383],[10.76481,46.82409],[10.76387,46.81971],[10.75239,46.81387],[10.74506,46.80223],[10.7276,46.79709],[10.73122,46.78925],[10.75722,46.78624],[10.77744,46.79149],[10.78678,46.79735],[10.81439,46.77662],[10.82479,46.77472],[10.83129,46.78138],[10.84112,46.78282],[10.85354,46.77506],[10.86845,46.77313],[10.86993,46.7669],[10.88294,46.76393],[10.88962,46.76529],[10.8951,46.77092],[10.90527,46.76911],[10.92299,46.7764],[10.92821,46.77408],[10.94388,46.77648],[10.97522,46.77361],[10.97932,46.77014],[10.99475,46.76804],[11.01397,46.77317],[11.02328,46.76715],[11.0346,46.79428],[11.04234,46.801],[11.03792,46.80562],[11.05633,46.80928],[11.07279,46.82092],[11.08171,46.82252],[11.0762,46.83384],[11.06887,46.83793],[11.07303,46.84345],[11.06988,46.85348],[11.08742,46.87927],[11.09961,46.88922],[11.09538,46.89178],[11.09795,46.89844],[11.0946,46.91247],[11.10792,46.91706],[11.10804,46.92632],[11.11418,46.93234],[11.13851,46.92865],[11.16322,46.94091],[11.16642,46.94479],[11.16114,46.94979],[11.1637,46.96677],[11.17598,46.96367],[11.18658,46.97062],[11.19527,46.97152],[11.20418,46.96877],[11.20688,46.96403],[11.22047,46.97025],[11.24139,46.9708],[11.24865,46.97517],[11.25582,46.97535],[11.26272,46.98169],[11.27662,46.98168],[11.28762,46.98699],[11.30709,46.98525],[11.3205,46.99345],[11.33765,46.98606],[11.34516,46.99169],[11.35932,46.99154],[11.37697,46.98025],[11.38324,46.97168],[11.40465,46.96609],[11.43929,46.97601],[11.45134,46.99294],[11.46803,46.99582],[11.46859,47.003],[11.47831,47.01201],[11.50238,47.01073],[11.50313,47.00808],[11.51366,47.00595],[11.51679,47.00091],[11.53381,46.99233],[11.53846,46.98519],[11.55297,46.99149],[11.57663,46.99657],[11.58,47.00277],[11.58879,47.00641],[11.59901,47.00657],[11.60944,47.01207],[11.62697,47.01437],[11.63629,47.00383],[11.66542,46.99304],[11.6885,46.99658],[11.71226,46.99416],[11.72897,46.97322],[11.74698,46.97013],[11.76411,46.97412],[11.78106,46.99342],[11.81526,46.991],[11.83564,46.99417],[11.84396,47.0025],[11.85192,47.0014],[11.86722,47.01252],[11.87393,47.01136],[11.8794,47.01714],[11.89137,47.01728],[11.91627,47.03422],[11.9329,47.03864],[11.94688,47.03464],[11.95457,47.04374],[11.96773,47.04158],[11.97912,47.0511],[11.98587,47.04815],[11.99534,47.05064],[12.02037,47.04821],[12.02968,47.05127],[12.03353,47.0583],[12.04276,47.06228],[12.07543,47.0605],[12.08035,47.06951],[12.09308,47.07791],[12.10329,47.07931],[12.11867,47.07445],[12.13561,47.08171],[12.15125,47.08049],[12.15997,47.08267],[12.18589,47.09322],[12.2278,47.08302],[12.24228,47.06892],[12.23786,47.0644],[12.21821,47.05795],[12.2182,47.04483],[12.20552,47.02595],[12.18048,47.02414],[12.16423,47.01782],[12.14786,47.02357],[12.12723,47.01218],[12.12285,47.00662],[12.1322,46.99339],[12.12974,46.98593],[12.13977,46.982],[12.13808,46.96514],[12.13328,46.96292],[12.13882,46.95764],[12.15927,46.95133],[12.1702,46.93758],[12.15414,46.91654],[12.14675,46.91413],[12.16205,46.908],[12.16959,46.91121],[12.19154,46.90682],[12.20106,46.8965],[12.2022,46.88806],[12.21663,46.87517],[12.22147,46.88084],[12.23125,46.88146],[12.2345,46.88919],[12.24162,46.89192],[12.27486,46.88512],[12.27979,46.87921],[12.27736,46.87319],[12.29326,46.86566],[12.2912,46.85704],[12.29733,46.84455],[12.30833,46.84137],[12.30726,46.83271],[12.285,46.81503],[12.29383,46.8027],[12.28905,46.79948],[12.28889,46.79427],[12.28232,46.79153],[12.28539,46.7839],[12.30943,46.78603],[12.35837,46.77583],[12.37036,46.74163],[12.38475,46.71745],[12.40283,46.70811],[12.41103,46.70701],[12.41522,46.70163],[12.42862,46.6997],[12.42943,46.69567],[12.44268,46.68979],[12.47501,46.68756],[12.4795,46.67969],[12.43473,46.66714],[12.40648,46.64167],[12.38115,46.64183],[12.37944,46.63733],[12.3915,46.62765],[12.38577,46.62154],[12.35939,46.61829],[12.34465,46.62376],[12.34034,46.63022],[12.33578,46.62732],[12.3172,46.62876],[12.31785,46.62355],[12.30802,46.61811],[12.28413,46.61623],[12.26982,46.62003],[12.25931,46.62809],[12.24502,46.62326],[12.24198,46.61586],[12.21241,46.60918],[12.20444,46.59836],[12.19228,46.59321],[12.19261,46.62059],[12.1818,46.6192],[12.17117,46.63275],[12.16062,46.63574],[12.1511,46.63215],[12.1436,46.6327],[12.13739,46.64122],[12.12342,46.64475],[12.10949,46.65204],[12.10609,46.65783],[12.09345,46.66123],[12.08826,46.66638],[12.07985,46.66686],[12.07038,46.67386],[12.07173,46.66064],[12.06686,46.65364],[12.07479,46.64329],[12.06837,46.63997],[12.06495,46.62121],[12.05448,46.61778],[12.05318,46.60989],[12.04613,46.60716],[12.05043,46.60016],[12.04763,46.58357],[12.03665,46.57668],[12.0266,46.55871],[12.02189,46.55791],[11.99941,46.53208],[11.99411,46.53345],[11.98704,46.54417],[11.96633,46.54363],[11.95094,46.53869],[11.94719,46.52879],[11.94147,46.52689],[11.93294,46.52631],[11.9121,46.532],[11.8904,46.52175],[11.85192,46.51682],[11.82849,46.50783],[11.82334,46.51315],[11.82391,46.52141],[11.81086,46.53146],[11.79385,46.52023],[11.79189,46.51322],[11.76157,46.50503],[11.74317,46.50391],[11.73202,46.50877],[11.71935,46.50916],[11.71524,46.51245],[11.69889,46.50218],[11.6672,46.49647],[11.64515,46.49743],[11.63849,46.50051],[11.63495,46.49486],[11.64297,46.49346],[11.65174,46.48271],[11.64536,46.47189],[11.64179,46.47439],[11.62679,46.4708],[11.62987,46.46377],[11.61882,46.44325],[11.62143,46.42539],[11.60161,46.39731],[11.60307,46.38924],[11.5932,46.38265],[11.56489,46.38018],[11.55878,46.35076],[11.55249,46.34418],[11.54423,46.34483],[11.53837,46.35015],[11.52445,46.35502],[11.47969,46.36277],[11.48052,46.3551],[11.46322,46.34922],[11.45556,46.33396],[11.42105,46.32441],[11.40517,46.32387],[11.39865,46.31426],[11.39994,46.30709],[11.39569,46.3083],[11.38188,46.30052],[11.36088,46.29906],[11.36078,46.29682],[11.38256,46.29177],[11.3871,46.28143],[11.39609,46.27423],[11.39862,46.264],[11.38756,46.26029],[11.37347,46.2629],[11.36836,46.26135],[11.35783,46.26481],[11.35495,46.27564],[11.33912,46.28306],[11.33379,46.29049],[11.33471,46.2962],[11.3129,46.28256],[11.31737,46.27303],[11.30645,46.25786],[11.29124,46.2604],[11.24743,46.22933],[11.20622,46.2187],[11.18267,46.22496],[11.17077,46.23806],[11.17994,46.24434],[11.18351,46.25269],[11.18935,46.25354],[11.19448,46.2461],[11.20029,46.25566],[11.16604,46.26129],[11.14885,46.27904],[11.13725,46.28336],[11.14293,46.28934],[11.15847,46.29059],[11.16439,46.2986],[11.1761,46.30346],[11.1847,46.32104],[11.18894,46.32151],[11.18696,46.32673],[11.1942,46.33016],[11.20204,46.34212],[11.19001,46.35984],[11.19263,46.36578],[11.20393,46.36765],[11.19792,46.37232],[11.21275,46.39804],[11.21345,46.40675],[11.20565,46.4166],[11.21026,46.4206],[11.20347,46.42682],[11.21416,46.43556],[11.21634,46.44255],[11.20903,46.45293],[11.21419,46.45807],[11.21736,46.45731],[11.21886,46.46199],[11.21626,46.47277],[11.20939,46.481],[11.20876,46.49346],[11.19608,46.50241],[11.1924,46.501],[11.18686,46.50734],[11.18002,46.49823],[11.17014,46.49635],[11.16095,46.4878],[11.12934,46.48058],[11.1103,46.49643],[11.10449,46.4948],[11.08812,46.50128],[11.08173,46.53021],[11.05915,46.51508],[11.03795,46.51357],[11.05006,46.50784],[11.05773,46.49235],[11.06278,46.4894],[11.06894,46.46619],[11.07625,46.45487],[11.0778,46.44569],[11.07301,46.44042],[11.05394,46.44849],[11.0414,46.44569],[11.02817,46.46116],[11.00952,46.46917],[11.00462,46.47607],[10.98695,46.48289],[10.96543,46.48103],[10.95791,46.46983],[10.93819,46.46578],[10.9325,46.45831],[10.93332,46.4528],[10.91305,46.44284],[10.89161,46.44366],[10.88324,46.44995],[10.88093,46.44579],[10.87162,46.4438],[10.86174,46.43509],[10.85113,46.43817],[10.80034,46.44185],[10.78906,46.45164],[10.77835,46.47112],[10.76934,46.47609],[10.76463,46.4848],[10.75906,46.48547],[10.74422,46.48333],[10.71753,46.46022],[10.69667,46.4573],[10.68293,46.44846],[10.66821,46.45122],[10.63303,46.44309],[10.61439,46.45098],[10.60128,46.46139],[10.59995,46.46766],[10.57672,46.47237],[10.55875,46.48187],[10.54986,46.49123],[10.53685,46.49062],[10.52657,46.49425],[10.49366,46.49719],[10.48141,46.49337],[10.45714,46.5096],[10.45124,46.53083],[10.45814,46.54215],[10.47056,46.54377],[10.46954,46.54856],[10.47617,46.55749],[10.47321,46.56701],[10.48305,46.5777],[10.48575,46.58921],[10.48221,46.59199],[10.48576,46.59805],[10.48291,46.60512],[10.49055,46.61394],[10.44632,46.63989],[10.40935,46.63389],[10.40011,46.63648],[10.39873,46.6455],[10.38946,46.65862],[10.39057,46.67089],[10.3803,46.68399],[10.38615,46.68821]]],"terms_url":"http://geoservices.buergernetz.bz.it/geokatalog/","terms_text":"© Autonomen Provinz Bozen/Provincia Autonoma di Bolzano"},{"id":"Bern-bern2016-tms","name":"Stadt Bern 10cm (2016)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/bern2016/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[7.2943145,46.9237564],[7.2982665,46.9274715],[7.3061586,46.9309487],[7.3043338,46.9362344],[7.3068603,46.9403709],[7.3246431,46.9432765],[7.3284525,46.946409],[7.3414051,46.9460797],[7.3438454,46.9473713],[7.3434554,46.9487937],[7.3513567,46.9485481],[7.3505628,46.950213],[7.3530901,46.9519266],[7.3582028,46.9511773],[7.3685031,46.9566244],[7.3715097,46.9607339],[7.37503,46.959835],[7.3785111,46.9614686],[7.3806232,46.9654741],[7.3832097,46.9663014],[7.3937998,46.9669268],[7.4000528,46.9691779],[7.4082922,46.9686857],[7.4281713,46.9738041],[7.4327053,46.972689],[7.4353602,46.9684345],[7.4378522,46.9684302],[7.4412474,46.9767865],[7.4456893,46.9747939],[7.4483835,46.9756393],[7.4477006,46.9790125],[7.4440468,46.9780682],[7.4412738,46.9798224],[7.4506732,46.9901527],[7.4522112,46.9896803],[7.454649,46.9778182],[7.4680382,46.9758258],[7.4707923,46.969998],[7.4701907,46.9674116],[7.4781618,46.9711823],[7.4845237,46.9701571],[7.4861275,46.9679018],[7.4857945,46.9646828],[7.4784708,46.9629043],[7.4802865,46.9606768],[7.4789304,46.9587841],[7.4797786,46.9566019],[7.4770135,46.9544586],[7.4840504,46.9499938],[7.4833925,46.9451977],[7.4955563,46.9396169],[7.4935119,46.9376594],[7.4908036,46.9387617],[7.4894997,46.9368667],[7.4766667,46.9369496],[7.4781093,46.9362489],[7.4746986,46.9339187],[7.4753537,46.9329898],[7.4691047,46.9292427],[7.4707683,46.9255044],[7.4585674,46.934836],[7.4476373,46.9304297],[7.435418,46.9349668],[7.4338022,46.9331237],[7.4376403,46.9307415],[7.4146941,46.9368183],[7.413844,46.9315682],[7.4070798,46.9303824],[7.408065,46.9256296],[7.4021268,46.9241992],[7.4014835,46.9211927],[7.3875736,46.9304506],[7.3823129,46.927282],[7.3800187,46.9298929],[7.3808694,46.9324085],[7.3748669,46.9314306],[7.3748901,46.9327104],[7.368066,46.9323929],[7.3683058,46.930426],[7.3604074,46.9285884],[7.3605592,46.9272018],[7.338783,46.9245357],[7.3393683,46.9196675],[7.3274574,46.9190326],[7.3269178,46.9235974],[7.324374,46.9251891],[7.3082264,46.9222857],[7.2943145,46.9237564]]],"terms_text":"Orthophoto 2016, Vermessungsamt Stadt Bern ","best":true},{"id":"Uster-2008","name":"Stadt Uster Orthophoto 2008 10cm","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/uster/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","polygon":[[[8.6,47.31],[8.6,47.39],[8.77,47.39],[8.77,47.31],[8.6,47.31]]],"terms_text":"Stadt Uster Vermessung Orthophoto 2008"},{"id":"Zuerich-zh_luftbild2011-tms","name":"Stadt Zürich Luftbild 2011","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/zh_luftbild2011/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","polygon":[[[8.4441,47.3141],[8.4441,47.4411],[8.6284,47.4411],[8.6284,47.3141],[8.4441,47.3141]]],"terms_text":"Stadt Zürich Luftbild 2011"},{"id":"Zuerich-city_map","name":"Stadtplan Zürich","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/zh_stadtplan/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","polygon":[[[8.4482,47.321],[8.4482,47.4339],[8.6248,47.4339],[8.6248,47.321],[8.4482,47.321]]],"terms_text":"Stadt Zürich Open Government Data"},{"id":"stamen-terrain-background","name":"Stamen Terrain","type":"tms","template":"http://{switch:a,b,c,d}.tile.stamen.com/terrain-background/{zoom}/{x}/{y}.jpg","scaleExtent":[4,18],"terms_url":"http://maps.stamen.com/#terrain","terms_text":"Map tiles by Stamen Design, under CC BY 3.0"},{"id":"Stevns_Denmark","name":"Stevns (Denmark)","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.dk/stevns/2009/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[12.0913942,55.3491574],[12.0943104,55.3842256],[12.1573875,55.3833103],[12.1587287,55.4013326],[12.1903468,55.400558],[12.1931411,55.4364665],[12.2564251,55.4347995],[12.2547073,55.4168882],[12.3822489,55.4134349],[12.3795942,55.3954143],[12.4109213,55.3946958],[12.409403,55.3766417],[12.4407807,55.375779],[12.4394142,55.3578314],[12.4707413,55.3569971],[12.4629475,55.2672214],[12.4315633,55.2681491],[12.430045,55.2502103],[12.3672011,55.2519673],[12.3656858,55.2340267],[12.2714604,55.2366031],[12.2744467,55.272476],[12.2115654,55.2741475],[12.2130078,55.2920322],[12.1815665,55.2928638],[12.183141,55.3107091],[12.2144897,55.3100981],[12.2159927,55.3279764],[12.1214458,55.3303379],[12.1229489,55.3483291],[12.0913942,55.3491574]]],"terms_text":"Stevns Kommune"},{"id":"Surrey-Air_Survey","name":"Surrey Air Survey","type":"tms","template":"http://gravitystorm.dev.openstreetmap.org/surrey/{zoom}/{x}/{y}.png","scaleExtent":[8,19],"polygon":[[[-0.752478,51.0821941],[-0.7595183,51.0856254],[-0.8014342,51.1457917],[-0.8398864,51.1440686],[-0.8357665,51.1802397],[-0.8529549,51.2011266],[-0.8522683,51.2096231],[-0.8495217,51.217903],[-0.8266907,51.2403696],[-0.8120995,51.2469248],[-0.7736474,51.2459577],[-0.7544213,51.2381127],[-0.754078,51.233921],[-0.7446366,51.2333836],[-0.7430693,51.2847178],[-0.751503,51.3069524],[-0.7664376,51.3121032],[-0.7820588,51.3270157],[-0.7815438,51.3388135],[-0.7374268,51.3720456],[-0.7192307,51.3769748],[-0.6795769,51.3847961],[-0.6807786,51.3901523],[-0.6531411,51.3917591],[-0.6301385,51.3905808],[-0.6291085,51.3970074],[-0.6234437,51.3977572],[-0.613144,51.4295552],[-0.6002471,51.4459121],[-0.5867081,51.4445365],[-0.5762368,51.453202],[-0.5626755,51.4523462],[-0.547741,51.4469972],[-0.5372697,51.4448575],[-0.537098,51.4526671],[-0.5439644,51.4545926],[-0.5405312,51.4698865],[-0.5309182,51.4760881],[-0.5091172,51.4744843],[-0.5086022,51.4695657],[-0.4900628,51.4682825],[-0.4526406,51.4606894],[-0.4486924,51.4429316],[-0.4414826,51.4418616],[-0.4418259,51.4369394],[-0.4112702,51.4380095],[-0.4014855,51.4279498],[-0.3807145,51.4262372],[-0.3805428,51.4161749],[-0.3491288,51.4138195],[-0.3274994,51.4037544],[-0.3039818,51.3990424],[-0.3019219,51.3754747],[-0.309475,51.369688],[-0.3111916,51.3529669],[-0.2955704,51.3541462],[-0.2923089,51.3673303],[-0.2850991,51.3680805],[-0.2787476,51.3771891],[-0.2655297,51.3837247],[-0.2411538,51.3847961],[-0.2123147,51.3628288],[-0.2107697,51.3498578],[-0.190857,51.3502867],[-0.1542931,51.3338802],[-0.1496583,51.3057719],[-0.1074296,51.2966491],[-0.0887185,51.3099571],[-0.0878602,51.3220811],[-0.0652009,51.3215448],[-0.0641709,51.3264793],[-0.0519829,51.3263721],[-0.0528412,51.334631],[-0.0330779,51.3430876],[0.0019187,51.3376339],[0.0118751,51.3281956],[0.013935,51.2994398],[0.0202865,51.2994398],[0.0240631,51.3072743],[0.0331611,51.3086694],[0.0455207,51.30545],[0.0523872,51.2877392],[0.0616569,51.2577764],[0.0640602,51.2415518],[0.0462074,51.2126342],[0.0407142,51.2109136],[0.0448341,51.1989753],[0.0494689,51.1997283],[0.0558204,51.1944573],[0.0611419,51.1790713],[0.0623435,51.1542061],[0.0577087,51.1417146],[0.0204582,51.1365447],[-0.0446015,51.1336364],[-0.1566964,51.1352522],[-0.1572114,51.1290043],[-0.2287942,51.1183379],[-0.2473336,51.1183379],[-0.2500802,51.1211394],[-0.299347,51.1137042],[-0.3221779,51.1119799],[-0.3223496,51.1058367],[-0.3596001,51.1019563],[-0.3589135,51.1113333],[-0.3863793,51.1117644],[-0.3869014,51.1062516],[-0.4281001,51.0947174],[-0.4856784,51.0951554],[-0.487135,51.0872266],[-0.5297404,51.0865404],[-0.5302259,51.0789914],[-0.61046,51.076551],[-0.6099745,51.080669],[-0.6577994,51.0792202],[-0.6582849,51.0743394],[-0.6836539,51.0707547],[-0.6997979,51.070831],[-0.7296581,51.0744919],[-0.752478,51.0821941]]]},{"id":"Szeged_2011","name":"Szeged ortophoto 2011","type":"tms","template":"http://e.tile.openstreetmap.hu/szeged-2011-10cm/{zoom}/{x}/{y}.png","scaleExtent":[10,22],"polygon":[[[20.1459914,46.2281144],[20.1332261,46.2290431],[20.1258373,46.2298686],[20.122329,46.2309893],[20.1208484,46.2317537],[20.1189709,46.2335126],[20.1131237,46.2413638],[20.1120293,46.2433005],[20.1115733,46.2449996],[20.1111871,46.247092],[20.1112944,46.2487725],[20.1115948,46.2509686],[20.1122171,46.2528047],[20.1129949,46.2542681],[20.1135421,46.2553549],[20.1147705,46.2567977],[20.1352251,46.2768529],[20.1366386,46.2775055],[20.1378939,46.2780301],[20.1393932,46.2783508],[20.1408818,46.2784583],[20.1611494,46.278159],[20.1621093,46.2781579],[20.1635894,46.277702],[20.1661777,46.2761484],[20.1687795,46.2738569],[20.1696108,46.2714413],[20.1695895,46.2704465],[20.1700871,46.2704418],[20.1739897,46.2643295],[20.1766182,46.2582878],[20.1947983,46.25492],[20.1858719,46.2448077],[20.1846595,46.2453122],[20.1780371,46.2383112],[20.1781766,46.2377101],[20.1795258,46.2370961],[20.1725666,46.2300241],[20.1698349,46.2350404],[20.1687701,46.2362946],[20.1670262,46.2378475],[20.1659431,46.2387342],[20.1654408,46.2389988],[20.1654837,46.2389988],[20.1635177,46.2401383],[20.1602051,46.2412003],[20.1592684,46.241531],[20.1592684,46.2415751],[20.1583504,46.2418505],[20.1549473,46.2422869],[20.1510796,46.2351538],[20.1493804,46.232459],[20.1459914,46.2281144]]],"terms_url":"http://www.geo.u-szeged.hu/","terms_text":"SZTE TFGT - University of Szeged"},{"id":"tnris.org","name":"Texas Orthophoto","type":"tms","template":"https://txgi.tnris.org/login/path/ecology-fiona-poem-romeo/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=texas&STYLE=&FORMAT=image/png&tileMatrixSet=0to20&tileMatrix=0to20:{zoom}&tileRow={y}&tileCol={x}","scaleExtent":[0,20],"polygon":[[[-99.9985439,34.5601834],[-95.55654502453,33.99257450647],[-93.89679027134,33.61039304449],[-93.98468089634,32.04103124103],[-93.41613841587,31.02505269211],[-93.74531484297,29.57268254375],[-96.50492070332,28.23158511753],[-97.36942054453,26.95467452634],[-97.04866958924,25.80530249434],[-99.0734177889,26.32559221139],[-100.76599193149,29.02531904433],[-102.3315436893,29.8433892263],[-103.13354564242,28.88112103669],[-104.2887874222,29.28831477845],[-104.7269783935,29.94815782859],[-104.72696778796,30.23535241761],[-106.53450082091,31.78456647831],[-106.75767043939,31.78457253947],[-106.75766067978,32.04385536686],[-106.61848436611,32.04385159755],[-103.11949492759,32.04375683439],[-103.09544343487,36.50045758762],[-103.05798056071,36.54268645422],[-100.00042146824,36.54222227302],[-99.9985439,34.5601834]]],"terms_url":"https://tnris.org/maps-and-data/online-mapping-services/"},{"id":"tf-landscape","name":"Thunderforest Landscape","type":"tms","template":"https://{switch:a,b,c}.tile.thunderforest.com/landscape/{zoom}/{x}/{y}.png","scaleExtent":[0,22],"terms_url":"http://www.thunderforest.com/terms/","terms_text":"Maps © Thunderforest, Data © OpenStreetMap contributors"},{"id":"Toulouse-Orthophotoplan-2007","name":"Toulouse - Orthophotoplan 2007","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_ortho2007/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1919978,43.6328791],[1.2015377,43.6329729],[1.2011107,43.6554932],[1.2227985,43.6557029],[1.2226231,43.6653353],[1.2275341,43.6653849],[1.2275417,43.6656387],[1.2337568,43.6656883],[1.2337644,43.6650153],[1.2351218,43.6650319],[1.2350913,43.6670729],[1.2443566,43.6671556],[1.2441584,43.6743925],[1.2493973,43.6744256],[1.2493973,43.6746628],[1.2555666,43.6747234],[1.2555742,43.6744532],[1.2569545,43.6744697],[1.2568782,43.678529],[1.2874873,43.6788257],[1.2870803,43.7013229],[1.3088219,43.7014632],[1.3086493,43.7127673],[1.3303262,43.7129544],[1.3300242,43.7305221],[1.3367106,43.7305845],[1.3367322,43.7312235],[1.3734338,43.7310456],[1.3735848,43.7245772],[1.4604504,43.7252947],[1.4607783,43.7028034],[1.4824875,43.7029516],[1.4829828,43.6692071],[1.5046832,43.6693616],[1.5048383,43.6581174],[1.5265475,43.6582656],[1.5266945,43.6470298],[1.548368,43.6471633],[1.5485357,43.6359385],[1.5702172,43.636082],[1.5705123,43.6135777],[1.5488166,43.6134276],[1.549097,43.5909479],[1.5707695,43.5910694],[1.5709373,43.5798341],[1.5793714,43.5798894],[1.5794782,43.5737682],[1.5809119,43.5737792],[1.5810859,43.5573794],[1.5712334,43.5573131],[1.5716504,43.5235497],[1.3984804,43.5222618],[1.3986509,43.5110113],[1.3120959,43.5102543],[1.3118968,43.5215192],[1.2902569,43.5213126],[1.2898637,43.5438168],[1.311517,43.5440133],[1.3113271,43.5552596],[1.3036924,43.5551924],[1.3036117,43.5595099],[1.2955449,43.5594317],[1.2955449,43.5595489],[1.2895595,43.5594473],[1.2892899,43.5775366],[1.2675698,43.5773647],[1.2673973,43.5886141],[1.25355,43.5885047],[1.2533774,43.5956282],[1.2518029,43.5956282],[1.2518029,43.5949409],[1.2350437,43.5947847],[1.2350437,43.5945972],[1.2239572,43.5945972],[1.2239357,43.5994708],[1.2139708,43.599299],[1.2138845,43.6046408],[1.2020647,43.6044846],[1.2019464,43.61048],[1.1924294,43.6103695],[1.1919978,43.6328791]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Toulouse-Orthophotoplan-2011","name":"Toulouse - Orthophotoplan 2011","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_ortho2011/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1135067,43.6867566],[1.1351836,43.6870842],[1.1348907,43.6983471],[1.1782867,43.6990338],[1.1779903,43.7102786],[1.1996591,43.7106144],[1.1993387,43.7218722],[1.2427356,43.7225269],[1.2424336,43.7337491],[1.2641536,43.734092],[1.2638301,43.7453588],[1.2855285,43.7456548],[1.2852481,43.756935],[1.306925,43.757231],[1.3066446,43.7684779],[1.3283431,43.7687894],[1.3280842,43.780034],[1.4367275,43.7815757],[1.4373098,43.7591004],[1.4590083,43.7593653],[1.4593318,43.7481479],[1.4810303,43.7483972],[1.4813322,43.7371777],[1.5030307,43.7374115],[1.5035915,43.7149664],[1.5253115,43.7151846],[1.5256135,43.7040057],[1.5472688,43.7042552],[1.5475708,43.6930431],[1.5692045,43.6932926],[1.5695712,43.6820316],[1.5912049,43.6822656],[1.5917441,43.6597998],[1.613421,43.6600339],[1.613723,43.6488291],[1.6353783,43.6490788],[1.6384146,43.5140731],[1.2921649,43.5094658],[1.2918629,43.5206966],[1.2702076,43.5203994],[1.2698841,43.5316437],[1.2482288,43.531331],[1.2476048,43.5537788],[1.2259628,43.5534914],[1.2256819,43.564716],[1.2039835,43.564419],[1.2033148,43.5869049],[1.1816164,43.5865611],[1.1810237,43.6090368],[1.1592821,43.6086932],[1.1589585,43.6199523],[1.1372601,43.6196244],[1.1365933,43.642094],[1.1149055,43.6417629],[1.1135067,43.6867566]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Toulouse-Orthophotoplan-2013","name":"Toulouse - Orthophotoplan 2013","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_2013/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1135067,43.6867566],[1.1351836,43.6870842],[1.1348907,43.6983471],[1.1782867,43.6990338],[1.1779903,43.7102786],[1.1996591,43.7106144],[1.1993387,43.7218722],[1.2427356,43.7225269],[1.2424336,43.7337491],[1.2641536,43.734092],[1.2638301,43.7453588],[1.2855285,43.7456548],[1.2852481,43.756935],[1.306925,43.757231],[1.3066446,43.7684779],[1.3283431,43.7687894],[1.3280842,43.780034],[1.4367275,43.7815757],[1.4373098,43.7591004],[1.4590083,43.7593653],[1.4593318,43.7481479],[1.4810303,43.7483972],[1.4813322,43.7371777],[1.5030307,43.7374115],[1.5035915,43.7149664],[1.5253115,43.7151846],[1.5256135,43.7040057],[1.5472688,43.7042552],[1.5475708,43.6930431],[1.5692045,43.6932926],[1.5695712,43.6820316],[1.5912049,43.6822656],[1.5917441,43.6597998],[1.613421,43.6600339],[1.613723,43.6488291],[1.6353783,43.6490788],[1.6384146,43.5140731],[1.2921649,43.5094658],[1.2918629,43.5206966],[1.2702076,43.5203994],[1.2698841,43.5316437],[1.2482288,43.531331],[1.2476048,43.5537788],[1.2259628,43.5534914],[1.2256819,43.564716],[1.2039835,43.564419],[1.2033148,43.5869049],[1.1816164,43.5865611],[1.1810237,43.6090368],[1.1592821,43.6086932],[1.1589585,43.6199523],[1.1372601,43.6196244],[1.1365933,43.642094],[1.1149055,43.6417629],[1.1135067,43.6867566]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Toulouse-Orthophotoplan-2015","name":"Toulouse - Orthophotoplan 2015","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/toulouse_2015/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[1.1135067,43.6867566],[1.1351836,43.6870842],[1.1348907,43.6983471],[1.1782867,43.6990338],[1.1779903,43.7102786],[1.1996591,43.7106144],[1.1993387,43.7218722],[1.2427356,43.7225269],[1.2424336,43.7337491],[1.2641536,43.734092],[1.2638301,43.7453588],[1.2855285,43.7456548],[1.2852481,43.756935],[1.306925,43.757231],[1.3066446,43.7684779],[1.3283431,43.7687894],[1.3280842,43.780034],[1.4367275,43.7815757],[1.4373098,43.7591004],[1.4590083,43.7593653],[1.4593318,43.7481479],[1.4810303,43.7483972],[1.4813322,43.7371777],[1.5030307,43.7374115],[1.5035915,43.7149664],[1.5253115,43.7151846],[1.5256135,43.7040057],[1.5472688,43.7042552],[1.5475708,43.6930431],[1.5692045,43.6932926],[1.5695712,43.6820316],[1.5912049,43.6822656],[1.5917441,43.6597998],[1.613421,43.6600339],[1.613723,43.6488291],[1.6353783,43.6490788],[1.6384146,43.5140731],[1.2921649,43.5094658],[1.2918629,43.5206966],[1.2702076,43.5203994],[1.2698841,43.5316437],[1.2482288,43.531331],[1.2476048,43.5537788],[1.2259628,43.5534914],[1.2256819,43.564716],[1.2039835,43.564419],[1.2033148,43.5869049],[1.1816164,43.5865611],[1.1810237,43.6090368],[1.1592821,43.6086932],[1.1589585,43.6199523],[1.1372601,43.6196244],[1.1365933,43.642094],[1.1149055,43.6417629],[1.1135067,43.6867566]]],"terms_url":"https://wiki.openstreetmap.org/wiki/Toulouse/ToulouseMetropoleData","terms_text":"ToulouseMetropole"},{"id":"Tours-Orthophoto-2008_2010","name":"Tours - Orthophotos 2008-2010","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/tours/{zoom}/{x}/{y}","scaleExtent":[0,20],"polygon":[[[0.5457462,47.465264],[0.54585,47.4608163],[0.5392188,47.4606983],[0.5393484,47.456243],[0.5327959,47.4561003],[0.5329011,47.451565],[0.52619,47.4514013],[0.5265854,47.4424884],[0.5000941,47.4420739],[0.5002357,47.4375835],[0.4936014,47.4374324],[0.4937,47.4329285],[0.4606141,47.4324593],[0.4607248,47.4279827],[0.4541016,47.4278125],[0.454932,47.4053921],[0.4615431,47.4054476],[0.4619097,47.3964924],[0.4684346,47.3966005],[0.4691319,47.3786415],[0.4757125,47.3787609],[0.4762116,47.3652018],[0.4828297,47.3653499],[0.4829611,47.3608321],[0.4763543,47.360743],[0.476654,47.3517263],[0.4700497,47.3516186],[0.4701971,47.3471313],[0.4637503,47.3470104],[0.4571425,47.3424146],[0.4572922,47.3379061],[0.4506741,47.3378081],[0.4508379,47.3333051],[0.4442212,47.3332032],[0.4443809,47.328711],[0.4311392,47.3284977],[0.4316262,47.3150004],[0.4382432,47.3151136],[0.4383815,47.3106174],[0.4714487,47.3111374],[0.4713096,47.3156565],[0.477888,47.3157542],[0.4780733,47.3112802],[0.4846826,47.3113639],[0.4848576,47.3068686],[0.4914359,47.3069803],[0.491745,47.2979733],[0.4851578,47.2978722],[0.4854269,47.2888744],[0.4788485,47.2887697],[0.4791574,47.2797818],[0.4857769,47.2799005],[0.4859107,47.2753885],[0.492539,47.2755029],[0.4926669,47.2710127],[0.4992986,47.2711066],[0.4994296,47.2666116],[0.5192658,47.2669245],[0.5194225,47.2624231],[0.5260186,47.2625205],[0.5258735,47.2670183],[0.5456972,47.2673383],[0.5455537,47.2718283],[0.5587737,47.2720366],[0.5586259,47.2765185],[0.5652252,47.2766278],[0.5650848,47.2811206],[0.5716753,47.2812285],[0.5715223,47.2857217],[0.5781436,47.2858299],[0.5779914,47.2903294],[0.5846023,47.2904263],[0.5843076,47.2994231],[0.597499,47.2996094],[0.5976637,47.2951375],[0.6571596,47.2960036],[0.6572988,47.2915091],[0.6705019,47.2917186],[0.6703475,47.2962082],[0.6836175,47.2963688],[0.6834322,47.3008929],[0.690062,47.3009558],[0.6899241,47.3054703],[0.7362019,47.3061157],[0.7360848,47.3106063],[0.7559022,47.3108935],[0.7557718,47.315392],[0.7623755,47.3154716],[0.7622314,47.3199941],[0.7754911,47.3201546],[0.77497,47.3388218],[0.7745786,47.351628],[0.7680363,47.3515901],[0.767589,47.3605298],[0.7742443,47.3606238],[0.7733465,47.3921266],[0.7667434,47.3920195],[0.7664411,47.4010837],[0.7730647,47.4011115],[0.7728868,47.4101297],[0.7661849,47.4100226],[0.7660267,47.4145044],[0.7527613,47.4143038],[0.7529788,47.4098086],[0.7462373,47.4097016],[0.7459424,47.4232208],[0.7392324,47.4231451],[0.738869,47.4366116],[0.7323267,47.4365171],[0.7321869,47.4410556],[0.7255048,47.44098],[0.7254209,47.4453479],[0.7318793,47.4454803],[0.7318514,47.4501126],[0.7384496,47.450226],[0.7383098,47.454631],[0.7449359,47.4547444],[0.7443209,47.4771985],[0.7310685,47.4769717],[0.7309008,47.4815445],[0.7176205,47.4812611],[0.7177883,47.4768394],[0.69777,47.4764993],[0.6980496,47.4719827],[0.6914514,47.4718882],[0.6917309,47.4630241],[0.6851048,47.4629295],[0.684937,47.4673524],[0.678255,47.4673335],[0.6779754,47.4762158],[0.6714051,47.4761592],[0.6710417,47.4881952],[0.6577334,47.4879685],[0.6578173,47.48504],[0.6511911,47.4848322],[0.6514707,47.4758568],[0.6448166,47.4757245],[0.6449284,47.4712646],[0.6117976,47.4707543],[0.6118815,47.4663129],[0.6052833,47.4661239],[0.6054231,47.4616631],[0.5988808,47.4615497],[0.5990206,47.4570886],[0.572488,47.4566916],[0.5721805,47.4656513],[0.5457462,47.465264]]],"terms_url":"http://wiki.openstreetmap.org/wiki/Tours/Orthophoto","terms_text":"Orthophoto Tour(s) Plus 2008"},{"id":"Tours-Orthophoto-2013","name":"Tours - Orthophotos 2013","type":"tms","template":"http://wms.openstreetmap.fr/tms/1.0.0/tours_2013/{zoom}/{x}/{y}","scaleExtent":[0,22],"polygon":[[[0.427093505859375,47.26199018174824],[0.427093505859375,47.50096732311069],[0.814361572265625,47.50096732311069],[0.814361572265625,47.26199018174824],[0.427093505859375,47.26199018174824]]],"terms_url":"http://wiki.openstreetmap.org/wiki/Tours/Orthophoto","terms_text":"Orthophoto Tour(s)plus 2013"},{"id":"US_Forest_Service_roads","name":"U.S. Forest Service roads","type":"tms","template":"http://osm.cycle.travel/forest/{zoom}/{x}/{y}.png","scaleExtent":[0,19],"polygon":[[[-124.7617886,48.4130148],[-124.6059492,45.90245],[-124.9934269,40.0557614],[-122.5369737,36.8566086],[-119.9775867,33.0064099],[-117.675935,32.4630223],[-114.8612307,32.4799891],[-111.0089311,31.336015],[-108.1992687,31.3260016],[-108.1871123,31.7755116],[-106.5307225,31.7820947],[-106.4842052,31.7464455],[-106.429317,31.7520583],[-106.2868855,31.5613291],[-106.205248,31.446704],[-105.0205259,30.5360988],[-104.5881916,29.6997856],[-103.2518856,28.8908685],[-102.7173632,29.3920567],[-102.1513983,29.7475702],[-101.2552871,29.4810523],[-100.0062436,28.0082173],[-99.2351068,26.4475962],[-98.0109067,25.9928035],[-97.435024,25.8266009],[-96.9555259,25.9821589],[-96.8061741,27.7978168],[-95.5563349,28.5876066],[-93.7405308,29.4742093],[-90.9028456,28.8564513],[-88.0156706,28.9944338],[-88.0162494,30.0038862],[-86.0277506,30.0047454],[-84.0187909,28.9961781],[-81.9971976,25.9826768],[-81.9966618,25.0134917],[-84.0165592,25.0125783],[-84.0160068,24.0052745],[-80.0199985,24.007096],[-79.8901116,26.8550713],[-80.0245309,32.0161282],[-75.4147385,35.0531894],[-74.0211163,39.5727927],[-72.002019,40.9912464],[-69.8797398,40.9920457],[-69.8489304,43.2619916],[-66.9452845,44.7104937],[-67.7596632,47.0990024],[-69.2505131,47.5122328],[-70.4614886,46.2176574],[-71.412273,45.254878],[-72.0222508,45.0059846],[-75.0798841,44.9802854],[-76.9023061,43.8024568],[-78.7623935,43.6249578],[-79.15798,43.4462589],[-79.0060087,42.8005317],[-82.662475,41.6889458],[-82.1761642,43.588535],[-83.2813977,46.138853],[-87.5064535,48.0142702],[-88.3492194,48.2963271],[-89.4353148,47.9837822],[-93.9981078,49.0067142],[-95.1105379,49.412004],[-96.0131199,49.0060547],[-123.3228926,49.0042878],[-123.2275233,48.1849927],[-124.7617886,48.4130148]],[[-160.5787616,22.5062947],[-160.5782192,21.4984647],[-158.7470604,21.2439843],[-157.5083185,20.995803],[-155.9961942,18.7790194],[-154.6217803,18.7586966],[-154.6890176,19.8805722],[-156.2927622,21.2225888],[-157.5047384,21.9984962],[-159.0093692,22.5070181],[-160.5787616,22.5062947]],[[-167.1571546,68.721974],[-164.8553982,67.0255078],[-168.002195,66.0017503],[-169.0087448,66.001546],[-169.0075381,64.9987675],[-172.5143281,63.8767267],[-173.8197023,59.74014],[-162.5018149,58.0005815],[-160.0159024,58.0012389],[-160.0149725,57.000035],[-160.5054788,56.9999017],[-165.8092575,54.824847],[-178.000097,52.2446469],[-177.9992996,51.2554252],[-171.4689067,51.8215329],[-162.40251,53.956664],[-159.0075717,55.002502],[-158.0190709,55.0027849],[-151.9963213,55.9991902],[-151.500341,57.9987853],[-151.5012894,58.9919816],[-138.5159989,58.9953194],[-138.5150471,57.9986434],[-133.9948193,54.0031685],[-130.0044418,54.0043387],[-130.0070826,57.0000507],[-131.975877,56.9995156],[-135.1229873,59.756601],[-138.0071813,59.991805],[-139.1715881,60.4127229],[-140.9874011,61.0118551],[-140.9683975,69.9535069],[-156.176891,71.5633329],[-160.413634,70.7397728],[-163.0218273,69.9707435],[-164.9717003,68.994689],[-167.1571546,68.721974]]]},{"id":"Zuerich-zh_uebersichtsplan-tms","name":"Übersichtsplan Zürich","type":"tms","template":"http://mapproxy.sosm.ch:8080/tiles/zh_uebersichtsplan/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[0,21],"polygon":[[[8.4482,47.321],[8.4482,47.4339],[8.6248,47.4339],[8.6248,47.321],[8.4482,47.321]]],"terms_text":"Stadt Zürich Open Government Data"},{"id":"USGS-Large_Scale","name":"USGS Large Scale Imagery","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.us/usgs_large_scale/{zoom}/{x}/{y}.jpg","scaleExtent":[12,20],"polygon":[[[-123.2549305,48.7529029],[-123.2549305,48.5592263],[-123.192224,48.5592263],[-123.192224,48.4348366],[-122.9419646,48.4348366],[-122.9419646,48.3720812],[-122.8806229,48.3720812],[-122.8806229,48.3094763],[-122.8167566,48.3094763],[-122.8167566,48.1904587],[-123.0041133,48.1904587],[-123.0041133,48.1275918],[-123.058416,48.1275918],[-123.058416,48.190514],[-123.254113,48.190514],[-123.254113,48.1274982],[-123.3706593,48.1274982],[-123.3706593,48.1908403],[-124.0582632,48.1908403],[-124.0582632,48.253442],[-124.1815163,48.253442],[-124.1815163,48.3164666],[-124.4319117,48.3164666],[-124.4319117,48.3782613],[-124.5564618,48.3782613],[-124.5564618,48.4408305],[-124.7555107,48.4408305],[-124.7555107,48.1914986],[-124.8185282,48.1914986],[-124.8185282,48.1228381],[-124.7552951,48.1228381],[-124.7552951,47.5535253],[-124.3812108,47.5535253],[-124.3812108,47.1218696],[-124.1928897,47.1218696],[-124.1928897,43.7569431],[-124.4443382,43.7569431],[-124.4443382,43.1425556],[-124.6398855,43.1425556],[-124.6398855,42.6194503],[-124.4438525,42.6194503],[-124.4438525,39.8080662],[-123.8815685,39.8080662],[-123.8815685,39.1102825],[-123.75805,39.1102825],[-123.75805,38.4968799],[-123.2702803,38.4968799],[-123.2702803,37.9331905],[-122.8148084,37.9331905],[-122.8148084,37.8019606],[-122.5664316,37.8019606],[-122.5664316,36.9319611],[-121.8784026,36.9319611],[-121.8784026,36.6897596],[-122.0034748,36.6897596],[-122.0034748,36.4341056],[-121.9414159,36.4341056],[-121.9414159,35.9297636],[-121.5040977,35.9297636],[-121.5040977,35.8100273],[-121.3790276,35.8100273],[-121.3790276,35.4239164],[-120.9426515,35.4239164],[-120.9426515,35.1849683],[-120.8171978,35.1849683],[-120.8171978,35.1219894],[-120.6918447,35.1219894],[-120.6918447,34.4966794],[-120.5045898,34.4966794],[-120.5045898,34.4339651],[-120.0078775,34.4339651],[-120.0078775,34.3682626],[-119.5283517,34.3682626],[-119.5283517,34.0576434],[-119.0060985,34.0576434],[-119.0060985,33.9975267],[-118.5046259,33.9975267],[-118.5046259,33.8694631],[-118.4413209,33.8694631],[-118.4413209,33.6865253],[-118.066912,33.6865253],[-118.066912,33.3063832],[-117.5030045,33.3063832],[-117.5030045,33.0500337],[-117.3188195,33.0500337],[-117.3188195,32.6205888],[-117.1917023,32.6205888],[-117.1917023,32.4974566],[-116.746496,32.4974566],[-116.746496,32.5609161],[-115.9970138,32.5609161],[-115.9970138,32.6264942],[-114.8808125,32.6264942],[-114.8808125,32.4340796],[-114.6294474,32.4340796],[-114.6294474,32.3731636],[-114.4447437,32.3731636],[-114.4447437,32.3075418],[-114.2557628,32.3075418],[-114.2557628,32.2444561],[-114.0680274,32.2444561],[-114.0680274,32.1829113],[-113.8166499,32.1829113],[-113.8166499,32.1207622],[-113.6307421,32.1207622],[-113.6307421,32.0565099],[-113.4417495,32.0565099],[-113.4417495,31.9984372],[-113.2546027,31.9984372],[-113.2546027,31.9325434],[-113.068072,31.9325434],[-113.068072,31.8718062],[-112.8161105,31.8718062],[-112.8161105,31.8104171],[-112.6308756,31.8104171],[-112.6308756,31.7464723],[-112.4418918,31.7464723],[-112.4418918,31.6856001],[-112.257192,31.6856001],[-112.257192,31.6210352],[-112.0033787,31.6210352],[-112.0033787,31.559584],[-111.815619,31.559584],[-111.815619,31.4970238],[-111.6278586,31.4970238],[-111.6278586,31.4339867],[-111.4418978,31.4339867],[-111.4418978,31.3733859],[-111.2559708,31.3733859],[-111.2559708,31.3113225],[-108.1845822,31.3113225],[-108.1845822,31.7459502],[-106.5065055,31.7459502],[-106.5065055,31.6842308],[-106.3797265,31.6842308],[-106.3797265,31.621752],[-106.317434,31.621752],[-106.317434,31.4968167],[-106.2551769,31.4968167],[-106.2551769,31.4344889],[-106.1924698,31.4344889],[-106.1924698,31.3721296],[-106.0039212,31.3721296],[-106.0039212,31.309328],[-105.9416582,31.309328],[-105.9416582,31.2457547],[-105.8798174,31.2457547],[-105.8798174,31.1836194],[-105.8162349,31.1836194],[-105.8162349,31.1207155],[-105.6921198,31.1207155],[-105.6921198,31.0584835],[-105.6302881,31.0584835],[-105.6302881,30.9328271],[-105.5044418,30.9328271],[-105.5044418,30.8715864],[-105.4412973,30.8715864],[-105.4412973,30.808463],[-105.3781497,30.808463],[-105.3781497,30.7471828],[-105.1904658,30.7471828],[-105.1904658,30.6843231],[-105.1286244,30.6843231],[-105.1286244,30.6199737],[-105.0036504,30.6199737],[-105.0036504,30.5589058],[-104.9417962,30.5589058],[-104.9417962,30.4963236],[-104.8782018,30.4963236],[-104.8782018,30.3098261],[-104.8155257,30.3098261],[-104.8155257,30.2478305],[-104.7536079,30.2478305],[-104.7536079,29.9353916],[-104.690949,29.9353916],[-104.690949,29.8090156],[-104.6291301,29.8090156],[-104.6291301,29.6843577],[-104.5659869,29.6843577],[-104.5659869,29.6223459],[-104.5037188,29.6223459],[-104.5037188,29.5595436],[-104.4410072,29.5595436],[-104.4410072,29.4974832],[-104.2537551,29.4974832],[-104.2537551,29.3716718],[-104.1291984,29.3716718],[-104.1291984,29.3091621],[-104.0688737,29.3091621],[-104.0688737,29.2467276],[-103.8187309,29.2467276],[-103.8187309,29.1843076],[-103.755736,29.1843076],[-103.755736,29.1223174],[-103.5667542,29.1223174],[-103.5667542,29.0598119],[-103.5049819,29.0598119],[-103.5049819,28.9967506],[-103.3165753,28.9967506],[-103.3165753,28.9346923],[-103.0597572,28.9346923],[-103.0597572,29.0592965],[-102.9979694,29.0592965],[-102.9979694,29.1212855],[-102.9331397,29.1212855],[-102.9331397,29.1848575],[-102.8095989,29.1848575],[-102.8095989,29.2526154],[-102.8701345,29.2526154],[-102.8701345,29.308096],[-102.8096681,29.308096],[-102.8096681,29.3715484],[-102.7475655,29.3715484],[-102.7475655,29.5581899],[-102.684554,29.5581899],[-102.684554,29.6847655],[-102.4967764,29.6847655],[-102.4967764,29.7457694],[-102.3086647,29.7457694],[-102.3086647,29.8086627],[-102.1909323,29.8086627],[-102.1909323,29.7460097],[-101.5049914,29.7460097],[-101.5049914,29.6846777],[-101.3805796,29.6846777],[-101.3805796,29.5594459],[-101.3175057,29.5594459],[-101.3175057,29.4958934],[-101.1910075,29.4958934],[-101.1910075,29.4326115],[-101.067501,29.4326115],[-101.067501,29.308808],[-100.9418897,29.308808],[-100.9418897,29.2456231],[-100.8167271,29.2456231],[-100.8167271,29.1190449],[-100.7522672,29.1190449],[-100.7522672,29.0578214],[-100.6925358,29.0578214],[-100.6925358,28.8720431],[-100.6290158,28.8720431],[-100.6290158,28.8095363],[-100.5679901,28.8095363],[-100.5679901,28.622554],[-100.5040411,28.622554],[-100.5040411,28.5583804],[-100.4421832,28.5583804],[-100.4421832,28.4968266],[-100.379434,28.4968266],[-100.379434,28.3092865],[-100.3171942,28.3092865],[-100.3171942,28.1835681],[-100.254483,28.1835681],[-100.254483,28.1213885],[-100.1282282,28.1213885],[-100.1282282,28.059215],[-100.0659537,28.059215],[-100.0659537,27.9966087],[-100.0023855,27.9966087],[-100.0023855,27.9332152],[-99.9426497,27.9332152],[-99.9426497,27.7454658],[-99.816851,27.7454658],[-99.816851,27.6834301],[-99.7541346,27.6834301],[-99.7541346,27.6221543],[-99.6291629,27.6221543],[-99.6291629,27.5588977],[-99.5672838,27.5588977],[-99.5672838,27.4353752],[-99.5041798,27.4353752],[-99.5041798,27.3774021],[-99.5671796,27.3774021],[-99.5671796,27.2463726],[-99.504975,27.2463726],[-99.504975,26.9965649],[-99.4427427,26.9965649],[-99.4427427,26.872803],[-99.3800633,26.872803],[-99.3800633,26.8068179],[-99.3190684,26.8068179],[-99.3190684,26.7473614],[-99.2537541,26.7473614],[-99.2537541,26.6210068],[-99.1910617,26.6210068],[-99.1910617,26.4956737],[-99.1300639,26.4956737],[-99.1300639,26.3713808],[-99.0029473,26.3713808],[-99.0029473,26.3093836],[-98.816572,26.3093836],[-98.816572,26.2457762],[-98.6920082,26.2457762],[-98.6920082,26.1837096],[-98.4440896,26.1837096],[-98.4440896,26.1217217],[-98.3823181,26.1217217],[-98.3823181,26.0596488],[-98.2532707,26.0596488],[-98.2532707,25.9986871],[-98.0109084,25.9986871],[-98.0109084,25.9932255],[-97.6932319,25.9932255],[-97.6932319,25.9334103],[-97.6313904,25.9334103],[-97.6313904,25.8695893],[-97.5046779,25.8695893],[-97.5046779,25.8073488],[-97.3083401,25.8073488],[-97.3083401,25.8731159],[-97.2456326,25.8731159],[-97.2456326,25.9353731],[-97.1138939,25.9353731],[-97.1138939,27.6809179],[-97.0571035,27.6809179],[-97.0571035,27.8108242],[-95.5810766,27.8108242],[-95.5810766,28.7468827],[-94.271041,28.7468827],[-94.271041,29.5594076],[-92.5029947,29.5594076],[-92.5029947,29.4974754],[-91.8776216,29.4974754],[-91.8776216,29.3727013],[-91.378418,29.3727013],[-91.378418,29.2468326],[-91.3153953,29.2468326],[-91.3153953,29.1844301],[-91.1294702,29.1844301],[-91.1294702,29.1232559],[-91.0052632,29.1232559],[-91.0052632,28.9968437],[-89.4500159,28.9968437],[-89.4500159,28.8677422],[-88.8104309,28.8677422],[-88.8104309,30.1841864],[-85.8791527,30.1841864],[-85.8791527,29.5455038],[-84.8368083,29.5455038],[-84.8368083,29.6225158],[-84.7482786,29.6225158],[-84.7482786,29.683624],[-84.685894,29.683624],[-84.685894,29.7468386],[-83.6296975,29.7468386],[-83.6296975,29.4324361],[-83.3174937,29.4324361],[-83.3174937,29.0579442],[-82.879659,29.0579442],[-82.879659,27.7453529],[-82.8182822,27.7453529],[-82.8182822,26.9290868],[-82.3796782,26.9290868],[-82.3796782,26.3694183],[-81.8777106,26.3694183],[-81.8777106,25.805971],[-81.5036862,25.805971],[-81.5036862,25.7474753],[-81.4405462,25.7474753],[-81.4405462,25.6851489],[-81.3155883,25.6851489],[-81.3155883,25.5600985],[-81.2538534,25.5600985],[-81.2538534,25.4342361],[-81.1902012,25.4342361],[-81.1902012,25.1234341],[-81.1288133,25.1234341],[-81.1288133,25.0619389],[-81.0649231,25.0619389],[-81.0649231,24.8157807],[-81.6289469,24.8157807],[-81.6289469,24.7538367],[-81.6907173,24.7538367],[-81.6907173,24.6899374],[-81.8173189,24.6899374],[-81.8173189,24.6279161],[-82.1910041,24.6279161],[-82.1910041,24.496294],[-81.6216596,24.496294],[-81.6216596,24.559484],[-81.372006,24.559484],[-81.372006,24.6220687],[-81.0593278,24.6220687],[-81.0593278,24.684826],[-80.9347147,24.684826],[-80.9347147,24.7474828],[-80.7471081,24.7474828],[-80.7471081,24.8100618],[-80.3629898,24.8100618],[-80.3629898,25.1175858],[-80.122344,25.1175858],[-80.122344,25.7472357],[-80.0588458,25.7472357],[-80.0588458,26.3708251],[-79.995837,26.3708251],[-79.995837,26.9398003],[-80.0587265,26.9398003],[-80.0587265,27.1277466],[-80.1226251,27.1277466],[-80.1226251,27.2534279],[-80.1846956,27.2534279],[-80.1846956,27.3781229],[-80.246175,27.3781229],[-80.246175,27.5658729],[-80.3094768,27.5658729],[-80.3094768,27.7530311],[-80.3721485,27.7530311],[-80.3721485,27.8774451],[-80.4351457,27.8774451],[-80.4351457,28.0033366],[-80.4966078,28.0033366],[-80.4966078,28.1277326],[-80.5587159,28.1277326],[-80.5587159,28.3723509],[-80.4966335,28.3723509],[-80.4966335,29.5160326],[-81.1213644,29.5160326],[-81.1213644,31.6846966],[-80.6018723,31.6846966],[-80.6018723,32.2475309],[-79.4921024,32.2475309],[-79.4921024,32.9970261],[-79.1116488,32.9970261],[-79.1116488,33.3729457],[-78.6153621,33.3729457],[-78.6153621,33.8097638],[-77.9316963,33.8097638],[-77.9316963,33.8718243],[-77.8692252,33.8718243],[-77.8692252,34.0552454],[-77.6826392,34.0552454],[-77.6826392,34.2974598],[-77.2453509,34.2974598],[-77.2453509,34.5598585],[-76.4973277,34.5598585],[-76.4973277,34.622796],[-76.4337602,34.622796],[-76.4337602,34.6849285],[-76.373212,34.6849285],[-76.373212,34.7467674],[-76.3059364,34.7467674],[-76.3059364,34.808551],[-76.2468017,34.808551],[-76.2468017,34.8728418],[-76.1825922,34.8728418],[-76.1825922,34.9335332],[-76.120814,34.9335332],[-76.120814,34.9952359],[-75.9979015,34.9952359],[-75.9979015,35.0578182],[-75.870338,35.0578182],[-75.870338,35.1219097],[-75.7462194,35.1219097],[-75.7462194,35.1818911],[-75.4929694,35.1818911],[-75.4929694,35.3082988],[-75.4325662,35.3082988],[-75.4325662,35.7542495],[-75.4969907,35.7542495],[-75.4969907,37.8105602],[-75.3082972,37.8105602],[-75.3082972,37.8720088],[-75.245601,37.8720088],[-75.245601,37.9954849],[-75.1828751,37.9954849],[-75.1828751,38.0585079],[-75.1184793,38.0585079],[-75.1184793,38.2469091],[-75.0592098,38.2469091],[-75.0592098,38.3704316],[-74.9948111,38.3704316],[-74.9948111,38.8718417],[-74.4878252,38.8718417],[-74.4878252,39.3089428],[-74.1766317,39.3089428],[-74.1766317,39.6224653],[-74.0567045,39.6224653],[-74.0567045,39.933178],[-73.9959035,39.933178],[-73.9959035,40.1854852],[-73.9341593,40.1854852],[-73.9341593,40.4959486],[-73.8723024,40.4959486],[-73.8723024,40.5527135],[-71.8074506,40.5527135],[-71.8074506,41.3088005],[-70.882512,41.3088005],[-70.882512,41.184978],[-70.7461947,41.184978],[-70.7461947,41.3091865],[-70.4337553,41.3091865],[-70.4337553,41.4963885],[-69.9334281,41.4963885],[-69.9334281,41.6230802],[-69.869857,41.6230802],[-69.869857,41.8776895],[-69.935791,41.8776895],[-69.935791,42.0032342],[-69.9975823,42.0032342],[-69.9975823,42.0650191],[-70.0606103,42.0650191],[-70.0606103,42.1294348],[-70.5572884,42.1294348],[-70.5572884,43.2487079],[-70.4974097,43.2487079],[-70.4974097,43.3092194],[-70.3704249,43.3092194],[-70.3704249,43.371963],[-70.3085701,43.371963],[-70.3085701,43.4969879],[-70.183921,43.4969879],[-70.183921,43.6223531],[-70.057583,43.6223531],[-70.057583,43.6850173],[-69.7455247,43.6850173],[-69.7455247,43.7476571],[-69.2472845,43.7476571],[-69.2472845,43.8107035],[-69.0560701,43.8107035],[-69.0560701,43.8717247],[-68.9950522,43.8717247],[-68.9950522,43.9982022],[-68.4963672,43.9982022],[-68.4963672,44.0597368],[-68.3081038,44.0597368],[-68.3081038,44.122137],[-68.1851802,44.122137],[-68.1851802,44.3081382],[-67.9956019,44.3081382],[-67.9956019,44.3727489],[-67.8103041,44.3727489],[-67.8103041,44.435178],[-67.4965289,44.435178],[-67.4965289,44.4968776],[-67.37102,44.4968776],[-67.37102,44.5600642],[-67.1848753,44.5600642],[-67.1848753,44.6213345],[-67.1221208,44.6213345],[-67.1221208,44.6867918],[-67.059365,44.6867918],[-67.059365,44.7473657],[-66.9311098,44.7473657],[-66.9311098,44.9406566],[-66.994683,44.9406566],[-66.994683,45.0024514],[-67.0595847,45.0024514],[-67.0595847,45.1273377],[-67.1201974,45.1273377],[-67.1201974,45.1910115],[-67.2469811,45.1910115],[-67.2469811,45.253442],[-67.3177546,45.253442],[-67.3177546,45.1898369],[-67.370749,45.1898369],[-67.370749,45.2534001],[-67.4326888,45.2534001],[-67.4326888,45.3083409],[-67.3708571,45.3083409],[-67.3708571,45.4396986],[-67.4305573,45.4396986],[-67.4305573,45.4950095],[-67.37099,45.4950095],[-67.37099,45.6264543],[-67.6214982,45.6264543],[-67.6214982,45.6896133],[-67.683828,45.6896133],[-67.683828,45.753259],[-67.7462097,45.753259],[-67.7462097,47.1268165],[-67.8700141,47.1268165],[-67.8700141,47.1900278],[-67.9323803,47.1900278],[-67.9323803,47.2539678],[-67.9959387,47.2539678],[-67.9959387,47.3149737],[-68.1206676,47.3149737],[-68.1206676,47.3780823],[-68.4423175,47.3780823],[-68.4423175,47.3166082],[-68.6314305,47.3166082],[-68.6314305,47.2544676],[-68.9978037,47.2544676],[-68.9978037,47.439895],[-69.0607223,47.439895],[-69.0607223,47.5047558],[-69.2538122,47.5047558],[-69.2538122,47.4398084],[-69.3179284,47.4398084],[-69.3179284,47.378601],[-69.4438546,47.378601],[-69.4438546,47.3156274],[-69.5038204,47.3156274],[-69.5038204,47.2525839],[-69.5667838,47.2525839],[-69.5667838,47.1910884],[-69.6303478,47.1910884],[-69.6303478,47.128701],[-69.6933103,47.128701],[-69.6933103,47.0654307],[-69.7557063,47.0654307],[-69.7557063,47.0042751],[-69.8180391,47.0042751],[-69.8180391,46.9415344],[-69.8804023,46.9415344],[-69.8804023,46.8792519],[-69.9421674,46.8792519],[-69.9421674,46.8177399],[-70.0063088,46.8177399],[-70.0063088,46.6920295],[-70.0704265,46.6920295],[-70.0704265,46.4425926],[-70.1945902,46.4425926],[-70.1945902,46.3785887],[-70.2562047,46.3785887],[-70.2562047,46.3152628],[-70.3203651,46.3152628],[-70.3203651,46.0651209],[-70.3814988,46.0651209],[-70.3814988,45.93552],[-70.3201618,45.93552],[-70.3201618,45.879479],[-70.4493131,45.879479],[-70.4493131,45.7538713],[-70.5070021,45.7538713],[-70.5070021,45.6916912],[-70.6316642,45.6916912],[-70.6316642,45.6291619],[-70.7575538,45.6291619],[-70.7575538,45.4414685],[-70.8809878,45.4414685],[-70.8809878,45.3780612],[-71.13328,45.3780612],[-71.13328,45.3151452],[-71.3830282,45.3151452],[-71.3830282,45.253416],[-71.5076448,45.253416],[-71.5076448,45.0655726],[-73.9418929,45.0655726],[-73.9418929,45.0031242],[-74.7469725,45.0031242],[-74.7469725,45.0649003],[-74.8800964,45.0649003],[-74.8800964,45.0029023],[-75.0662455,45.0029023],[-75.0662455,44.9415167],[-75.2539363,44.9415167],[-75.2539363,44.8776043],[-75.3789648,44.8776043],[-75.3789648,44.8153462],[-75.4431283,44.8153462],[-75.4431283,44.7536053],[-75.5666566,44.7536053],[-75.5666566,44.6909879],[-75.6290205,44.6909879],[-75.6290205,44.6284958],[-75.7540484,44.6284958],[-75.7540484,44.566385],[-75.817312,44.566385],[-75.817312,44.5028932],[-75.8799549,44.5028932],[-75.8799549,44.3784946],[-76.1300319,44.3784946],[-76.1300319,44.3159227],[-76.1926961,44.3159227],[-76.1926961,44.2534378],[-76.3182619,44.2534378],[-76.3182619,44.1916726],[-76.3792975,44.1916726],[-76.3792975,44.0653733],[-76.4427584,44.0653733],[-76.4427584,43.9963825],[-76.317027,43.9963825],[-76.317027,43.9414581],[-76.5076611,43.9414581],[-76.5076611,43.8723335],[-76.3829974,43.8723335],[-76.3829974,43.8091872],[-76.2534102,43.8091872],[-76.2534102,43.5665222],[-76.5064833,43.5665222],[-76.5064833,43.5033881],[-76.6331208,43.5033881],[-76.6331208,43.4432252],[-76.6951085,43.4432252],[-76.6951085,43.3786858],[-76.8177798,43.3786858],[-76.8177798,43.318066],[-77.682,43.318066],[-77.682,43.3789376],[-78.0565883,43.3789376],[-78.0565883,43.4396918],[-78.4389748,43.4396918],[-78.4389748,43.3794382],[-78.8803396,43.3794382],[-78.8803396,43.3149724],[-79.1298858,43.3149724],[-79.1298858,43.2429286],[-79.0669615,43.2429286],[-79.0669615,43.1299931],[-79.1298858,43.1299931],[-79.1298858,43.0577305],[-79.071264,43.0577305],[-79.071264,42.9294906],[-78.943264,42.9294906],[-78.943264,42.7542165],[-79.069439,42.7542165],[-79.069439,42.6941622],[-79.133439,42.6941622],[-79.133439,42.6296973],[-79.1947499,42.6296973],[-79.1947499,42.5663538],[-79.3786827,42.5663538],[-79.3786827,42.5033425],[-79.4442961,42.5033425],[-79.4442961,42.4410614],[-79.5679936,42.4410614],[-79.5679936,42.3775264],[-79.6906154,42.3775264],[-79.6906154,42.3171086],[-79.8164642,42.3171086],[-79.8164642,42.2534481],[-80.0052373,42.2534481],[-80.0052373,42.1909188],[-80.1916829,42.1909188],[-80.1916829,42.1272555],[-80.3167992,42.1272555],[-80.3167992,42.0669857],[-80.5063234,42.0669857],[-80.5063234,42.0034331],[-80.6930471,42.0034331],[-80.6930471,41.9415141],[-80.9440403,41.9415141],[-80.9440403,41.8781193],[-81.1942729,41.8781193],[-81.1942729,41.8166455],[-81.3190089,41.8166455],[-81.3190089,41.7545453],[-81.4418435,41.7545453],[-81.4418435,41.690965],[-81.5053523,41.690965],[-81.5053523,41.6301643],[-82.7470081,41.6301643],[-82.7470081,41.7536942],[-82.8839135,41.7536942],[-82.8839135,41.5656075],[-82.9957195,41.5656075],[-82.9957195,41.6270375],[-83.1257796,41.6270375],[-83.1257796,41.6878411],[-83.2474733,41.6878411],[-83.2474733,41.7536942],[-83.3737305,41.7536942],[-83.3737305,41.809276],[-83.3106019,41.809276],[-83.3106019,41.8716064],[-83.2474733,41.8716064],[-83.2474733,41.9361393],[-83.1843447,41.9361393],[-83.1843447,41.9960851],[-83.1207681,41.9960851],[-83.1207681,42.2464812],[-83.0589194,42.2464812],[-83.0589194,42.3089555],[-82.8685328,42.3089555],[-82.8685328,42.3717652],[-82.8072219,42.3717652],[-82.8072219,42.558553],[-82.7553745,42.558553],[-82.7553745,42.4954945],[-82.5599041,42.4954945],[-82.5599041,42.558553],[-82.4967755,42.558553],[-82.4967755,42.6833607],[-82.4328863,42.6833607],[-82.4328863,42.9342196],[-82.3700552,42.9342196],[-82.3700552,43.0648071],[-82.4328863,43.0648071],[-82.4328863,43.1917566],[-82.4947464,43.1917566],[-82.4947464,43.5034627],[-82.557133,43.5034627],[-82.557133,43.8160901],[-82.6197884,43.8160901],[-82.6197884,43.9422098],[-82.6839499,43.9422098],[-82.6839499,44.0022641],[-82.7465346,44.0022641],[-82.7465346,44.0670545],[-82.8708696,44.0670545],[-82.8708696,44.1291935],[-83.008517,44.1291935],[-83.008517,44.0664786],[-83.1336086,44.0664786],[-83.1336086,44.0053949],[-83.2414522,44.0053949],[-83.2414522,44.9962034],[-83.1806112,44.9962034],[-83.1806112,45.067302],[-83.2455172,45.067302],[-83.2455172,45.1287382],[-83.3065878,45.1287382],[-83.3065878,45.2551509],[-83.3706087,45.2551509],[-83.3706087,45.3165923],[-83.4325644,45.3165923],[-83.4325644,45.3792105],[-83.6178415,45.3792105],[-83.6178415,45.4419665],[-83.8084291,45.4419665],[-83.8084291,45.5036189],[-84.0550718,45.5036189],[-84.0550718,45.5647907],[-84.1235181,45.5647907],[-84.1235181,45.6287845],[-84.1807534,45.6287845],[-84.1807534,45.6914688],[-84.3111554,45.6914688],[-84.3111554,45.9337076],[-83.8209974,45.9337076],[-83.8209974,45.8725113],[-83.4968086,45.8725113],[-83.4968086,45.9337076],[-83.4338066,45.9337076],[-83.4338066,46.0016863],[-83.4962697,46.0016863],[-83.4962697,46.0668178],[-83.5599956,46.0668178],[-83.5599956,46.1261576],[-83.9954558,46.1261576],[-83.9954558,46.1931747],[-84.0591816,46.1931747],[-84.0591816,46.3814972],[-84.1152614,46.3814972],[-84.1152614,46.4953584],[-84.0591816,46.4953584],[-84.0591816,46.5682653],[-84.2579545,46.5682653],[-84.2579545,46.5051232],[-84.3071879,46.5051232],[-84.3071879,46.5682653],[-84.4415364,46.5682653],[-84.4415364,46.504525],[-84.9965729,46.504525],[-84.9965729,46.6842882],[-84.9298158,46.6842882],[-84.9298158,46.818077],[-85.3165894,46.818077],[-85.3165894,46.7535825],[-87.5562645,46.7535825],[-87.5562645,47.4407371],[-87.6825361,47.4407371],[-87.6825361,47.5035554],[-88.2560738,47.5035554],[-88.2560738,47.4433716],[-88.4417419,47.4433716],[-88.4417419,47.3789949],[-88.50683,47.3789949],[-88.50683,47.3153881],[-88.6312821,47.3153881],[-88.6312821,47.2539782],[-88.7569636,47.2539782],[-88.7569636,47.1934682],[-88.8838253,47.1934682],[-88.8838253,47.1284735],[-88.9434208,47.1284735],[-88.9434208,47.0662127],[-89.0708726,47.0662127],[-89.0708726,47.0026826],[-89.2565553,47.0026826],[-89.2565553,46.9410806],[-90.3677669,46.9410806],[-90.3677669,47.6844827],[-90.3069978,47.6844827],[-90.3069978,47.7460174],[-89.994859,47.7460174],[-89.994859,47.8082719],[-89.8048615,47.8082719],[-89.8048615,47.8700562],[-89.6797699,47.8700562],[-89.6797699,47.9339637],[-89.4933757,47.9339637],[-89.4933757,47.9957956],[-89.4284697,47.9957956],[-89.4284697,48.0656377],[-89.9932739,48.0656377],[-89.9932739,48.1282966],[-90.7455933,48.1282966],[-90.7455933,48.1893056],[-90.8087291,48.1893056],[-90.8087291,48.2522065],[-91.067763,48.2522065],[-91.067763,48.1916658],[-91.1946247,48.1916658],[-91.1946247,48.1279027],[-91.6814196,48.1279027],[-91.6814196,48.2525994],[-91.9321927,48.2525994],[-91.9321927,48.3142454],[-91.9929683,48.3142454],[-91.9929683,48.3780845],[-92.3189383,48.3780845],[-92.3189383,48.2529081],[-92.3732233,48.2529081],[-92.3732233,48.3153385],[-92.4322288,48.3153385],[-92.4322288,48.4411448],[-92.4977248,48.4411448],[-92.4977248,48.501781],[-92.5679413,48.501781],[-92.5679413,48.439579],[-92.6210462,48.439579],[-92.6210462,48.5650783],[-92.8086835,48.5650783],[-92.8086835,48.6286865],[-92.8086835,48.6267365],[-92.933185,48.6267365],[-92.933185,48.6922145],[-93.0051716,48.6922145],[-93.0051716,48.6282965],[-93.1225924,48.6282965],[-93.1225924,48.6922145],[-93.3190806,48.6922145],[-93.3190806,48.6267365],[-93.5049477,48.6267365],[-93.5049477,48.5635164],[-93.7474601,48.5635164],[-93.7474601,48.6267365],[-93.8135461,48.6267365],[-93.8135461,48.6898775],[-94.2453121,48.6898775],[-94.2453121,48.7554327],[-94.6183171,48.7554327],[-94.6183171,48.941036],[-94.6809018,48.941036],[-94.6809018,49.0029737],[-94.7441532,49.0029737],[-94.7441532,49.2536079],[-94.8084069,49.2536079],[-94.8084069,49.3784134],[-95.1192391,49.3784134],[-95.1192391,49.4425264],[-95.1934341,49.4425264],[-95.1934341,49.0035292],[-96.87069,49.0035292],[-96.87069,49.0656063],[-99.0049312,49.0656063],[-99.0049312,49.0050714],[-109.3699257,49.0050714],[-109.3699257,49.0668231],[-109.5058746,49.0668231],[-109.5058746,49.0050714],[-114.1830014,49.0050714],[-114.1830014,49.0687317],[-114.7578709,49.0687317],[-114.7578709,49.0050714],[-115.433731,49.0050714],[-115.433731,49.0671412],[-116.5062706,49.0671412],[-116.5062706,49.0050714],[-117.3089504,49.0050714],[-117.3089504,49.0659803],[-119.882945,49.0659803],[-119.882945,49.0050714],[-120.1208555,49.0050714],[-120.1208555,49.0678367],[-121.4451636,49.0678367],[-121.4451636,49.0050714],[-121.9311808,49.0050714],[-121.9311808,49.0656099],[-122.817484,49.0656099],[-122.817484,49.0029143],[-122.8795155,49.0029143],[-122.8795155,48.9347018],[-122.8174629,48.9347018],[-122.8174629,48.8101998],[-122.7538859,48.8101998],[-122.7538859,48.7533758],[-122.8712937,48.7533758],[-122.8712937,48.8153948],[-123.0055391,48.8153948],[-123.0055391,48.7529529],[-123.1296926,48.7529529],[-123.1296926,48.6902201],[-123.1838197,48.6902201],[-123.1838197,48.7529029],[-123.2549305,48.7529029]],[[-122.9341743,37.7521547],[-122.9347457,37.6842013],[-123.0679013,37.6849023],[-123.0673747,37.7475251],[-123.1292603,37.7478506],[-123.1286894,37.815685],[-123.0590687,37.8153192],[-123.0595947,37.7528143],[-122.9341743,37.7521547]],[[-71.6299464,41.2540893],[-71.4966465,41.2541393],[-71.4965596,41.122965],[-71.6298594,41.1229149],[-71.6299464,41.2540893]],[[-70.3184265,41.3775196],[-70.3183384,41.2448243],[-70.1906612,41.2448722],[-70.1906239,41.1886019],[-69.9336025,41.1886984],[-69.933729,41.3791941],[-69.9950664,41.3791712],[-69.995109,41.443159],[-70.0707828,41.4431307],[-70.0706972,41.3144915],[-70.2461667,41.3144258],[-70.2462087,41.3775467],[-70.3184265,41.3775196]],[[-68.9403374,43.9404062],[-68.6856948,43.9404977],[-68.6856475,43.8721797],[-68.7465405,43.8721577],[-68.7464976,43.8102529],[-68.8090782,43.8102304],[-68.8090343,43.746728],[-68.8773094,43.7467034],[-68.8773544,43.8117826],[-68.9402483,43.8117599],[-68.9403374,43.9404062]],[[-123.1291466,49.0645144],[-122.9954224,49.0645144],[-122.9954224,48.9343243],[-123.1291466,48.9343243],[-123.1291466,49.0645144]],[[-82.9407144,24.7535913],[-82.8719398,24.7535913],[-82.8719398,24.6905653],[-82.7446233,24.6905653],[-82.7446233,24.6214593],[-82.8088038,24.6214593],[-82.8088038,24.5594908],[-82.9407144,24.5594908],[-82.9407144,24.7535913]]]},{"id":"USGS-Scanned_Topographic","name":"USGS Topographic Maps","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.us/usgs_scanned_topos/{zoom}/{x}/{y}.png","polygon":[[[-125.990173,48.9962416],[-125.989419,47.9948396],[-123.9929739,47.9955062],[-123.9922429,47.0059202],[-125.988688,47.0052409],[-125.9879604,46.0015618],[-123.9939396,46.0022529],[-123.9925238,43.9961708],[-124.9931832,43.9958116],[-124.9918175,41.9942149],[-125.9851789,41.9938465],[-125.9838655,40.0076111],[-123.9833285,40.0083757],[-123.9814115,37.002615],[-122.21903,37.0033173],[-122.2184144,36.011671],[-122.020087,36.011751],[-122.0188591,33.9961766],[-119.9787757,33.9970206],[-119.9775867,31.9987658],[-114.0122833,32.00129],[-114.0116894,30.9862401],[-105.998294,30.9896679],[-105.9971419,28.9901065],[-102.0210506,28.9918418],[-102.0204916,28.00733],[-100.0062436,28.0082173],[-100.0051143,25.991909],[-98.0109067,25.9928035],[-98.0103613,25.0063461],[-97.0161086,25.0067957],[-97.016654,25.9932494],[-95.9824825,25.9937132],[-95.9835999,27.9891175],[-94.0200898,27.9899826],[-94.0206586,28.9918129],[-88.0156706,28.9944338],[-88.0162494,30.0038862],[-86.0277506,30.0047454],[-86.0271719,28.9953016],[-84.0187909,28.9961781],[-84.017095,25.9817708],[-81.9971976,25.9826768],[-81.9966618,25.0134917],[-84.0165592,25.0125783],[-84.0160068,24.0052745],[-80.0199985,24.007096],[-80.0245309,32.0161282],[-78.0066484,32.0169819],[-78.0072238,32.9894278],[-77.8807233,32.9894807],[-77.8813253,33.9955918],[-76.0115411,33.9963653],[-76.0121459,34.9952552],[-74.0068449,34.9960749],[-74.0099997,40.0084254],[-72.0013745,40.0091931],[-72.002019,40.9912464],[-69.8797398,40.9920457],[-69.8804173,42.00893],[-69.9927682,42.0088883],[-69.9934462,43.0105166],[-67.9845366,43.0112496],[-67.985224,44.0103812],[-65.9892568,44.0110975],[-65.9921237,47.9993584],[-70.006442,47.9980181],[-70.005708,47.0042007],[-72.023686,47.003514],[-72.0222508,45.0059846],[-78.0146667,45.0038705],[-78.0139662,44.0026998],[-80.029686,44.0019763],[-80.0290052,43.0122994],[-81.995479,43.011582],[-81.9982986,47.0042713],[-87.505706,47.0023972],[-87.5064535,48.0142702],[-88.0260889,48.0140968],[-88.026838,49.0086686],[-93.9981078,49.0067142],[-93.9988778,50.0086456],[-96.0138899,50.0079995],[-96.0131199,49.0060547],[-125.990173,48.9962416]],[[-160.5787616,22.5062947],[-160.5782192,21.4984647],[-159.0030121,21.499196],[-159.0027422,20.9951068],[-157.5083185,20.995803],[-157.5080519,20.4960241],[-155.966889,20.4967444],[-155.9674267,21.5028287],[-157.5044717,21.5021151],[-157.5047384,21.9984962],[-159.0090946,21.9978002],[-159.0093692,22.5070181],[-160.5787616,22.5062947]],[[-168.006102,68.9941463],[-168.0047628,68.0107853],[-165.4842481,68.0112562],[-165.4829337,67.0037303],[-168.0034485,67.0032389],[-168.002195,66.0017503],[-169.0087448,66.001546],[-169.0075381,64.9987675],[-168.0009882,64.9989798],[-167.9998282,63.9982374],[-164.9871288,63.9988964],[-164.9860062,62.9950845],[-167.9987057,62.9944019],[-167.9946035,59.0153692],[-162.5027857,59.0167799],[-162.5018149,58.0005815],[-160.0159024,58.0012389],[-160.0149725,57.000035],[-160.5054788,56.9999017],[-160.5045719,55.9968161],[-164.012195,55.9958373],[-164.0113186,55.00107],[-165.994782,55.0005023],[-165.9941266,54.2400584],[-168.0002944,54.2394734],[-168.0000986,54.0094921],[-170.0156134,54.0089011],[-170.0147683,53.0016446],[-171.9993636,53.0010487],[-171.9989488,52.4977745],[-176.0083239,52.4965566],[-176.0081186,52.2452555],[-178.000097,52.2446469],[-177.9992996,51.2554252],[-176.0073212,51.2560472],[-176.0075146,51.4980163],[-171.9981395,51.4992617],[-171.9985419,51.9985373],[-167.9984317,51.9997661],[-167.9994645,53.2560877],[-165.9932968,53.2566866],[-165.9939308,54.0100804],[-159.0067205,54.0121291],[-159.0075717,55.002502],[-158.0190709,55.0027849],[-158.0199473,55.9975094],[-151.9963213,55.9991902],[-151.9981536,57.9986536],[-151.500341,57.9987853],[-151.5012894,58.9919816],[-138.5159989,58.9953194],[-138.5150471,57.9986434],[-136.6872422,57.9991267],[-136.6863158,57.0016688],[-135.9973698,57.001856],[-135.9964667,56.0030544],[-134.6717732,56.003424],[-134.6708865,54.9969623],[-133.9956734,54.9971556],[-133.9948193,54.0031685],[-130.0044418,54.0043387],[-130.0070826,57.0000507],[-131.975877,56.9995156],[-131.9787378,59.9933094],[-138.0071813,59.991805],[-138.0082158,61.0125755],[-140.9874011,61.0118551],[-140.99984,71.0039309],[-154.5023956,71.0017377],[-154.5039632,71.9983391],[-157.499048,71.9978773],[-157.4974758,70.9982877],[-163.0233611,70.9973899],[-163.0218273,69.9707435],[-164.9730896,69.97041],[-164.9717003,68.994689],[-168.006102,68.9941463]],[[-168.5133204,62.8689586],[-168.5144423,63.8765677],[-172.0202755,63.8757975],[-172.0191536,62.8681608],[-168.5133204,62.8689586]],[[-170.9947111,59.9954089],[-170.995726,60.9969787],[-174.0045311,60.9962508],[-174.0035162,59.9946581],[-170.9947111,59.9954089]],[[-156.0717261,20.2854602],[-154.7940471,20.2860582],[-154.7933145,18.9029464],[-156.0709936,18.9023432],[-156.0717261,20.2854602]]]},{"id":"sjcgis.org-General_Basemap_WM","name":"Vector Streetmap for San Juan County WA","type":"tms","template":"http://sjcgis.org/arcgis/rest/services/Basemaps/General_Basemap_WM/MapServer/tile/{zoom}/{y}/{x}","description":"Public domain street and address data from the San Juan County, WA. Updated at least quarterly.","scaleExtent":[0,19],"polygon":[[[-123.274024,48.692975],[-123.007726,48.767256],[-123.007619,48.831577],[-122.783495,48.758416],[-122.693402,48.658522],[-122.767451,48.603606],[-122.744842,48.387083],[-123.248221,48.283531],[-123.114524,48.422614],[-123.219035,48.548575],[-123.274024,48.692975]]],"best":true},{"id":"Vejmidte_Denmark","name":"Vejmidte (Denmark)","type":"tms","template":"http://{switch:a,b,c}.tile.openstreetmap.dk/danmark/vejmidte/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"polygon":[[[8.3743941,54.9551655],[8.3683809,55.4042149],[8.2103997,55.4039795],[8.2087314,55.4937345],[8.0502655,55.4924731],[8.0185123,56.7501399],[8.1819161,56.7509948],[8.1763274,57.0208898],[8.3413329,57.0219872],[8.3392467,57.1119574],[8.5054433,57.1123212],[8.5033923,57.2020499],[9.3316304,57.2027636],[9.3319079,57.2924835],[9.4978864,57.2919578],[9.4988593,57.3820608],[9.6649749,57.3811615],[9.6687295,57.5605591],[9.8351961,57.5596265],[9.8374896,57.6493322],[10.1725726,57.6462818],[10.1754245,57.7367768],[10.5118282,57.7330269],[10.5152095,57.8228945],[10.6834853,57.8207722],[10.6751613,57.6412021],[10.5077045,57.6433097],[10.5039992,57.5535088],[10.671038,57.5514113],[10.6507805,57.1024538],[10.4857673,57.1045138],[10.4786236,56.9249051],[10.3143981,56.9267573],[10.3112341,56.8369269],[10.4750295,56.83509],[10.4649016,56.5656681],[10.9524239,56.5589761],[10.9479249,56.4692243],[11.1099335,56.4664675],[11.1052639,56.376833],[10.9429901,56.3795284],[10.9341235,56.1994768],[10.7719685,56.2020244],[10.7694751,56.1120103],[10.6079695,56.1150259],[10.4466742,56.116717],[10.2865948,56.118675],[10.2831527,56.0281851],[10.4439274,56.0270388],[10.4417713,55.7579243],[10.4334961,55.6693533],[10.743814,55.6646861],[10.743814,55.5712253],[10.8969041,55.5712253],[10.9051793,55.3953852],[11.0613726,55.3812841],[11.0593038,55.1124061],[11.0458567,55.0318621],[11.2030844,55.0247474],[11.2030844,55.117139],[11.0593038,55.1124061],[11.0613726,55.3812841],[11.0789572,55.5712253],[10.8969041,55.5712253],[10.9258671,55.6670198],[10.743814,55.6646861],[10.7562267,55.7579243],[10.4417713,55.7579243],[10.4439274,56.0270388],[10.4466742,56.116717],[10.6079695,56.1150259],[10.6052053,56.0247462],[10.9258671,56.0201215],[10.9197132,55.9309388],[11.0802782,55.92792],[11.0858066,56.0178284],[11.7265047,56.005058],[11.7319981,56.0952142],[12.0540333,56.0871256],[12.0608477,56.1762576],[12.7023469,56.1594405],[12.6611131,55.7114318],[12.9792318,55.7014026],[12.9612912,55.5217294],[12.3268659,55.5412096],[12.3206071,55.4513655],[12.4778226,55.447067],[12.4702432,55.3570479],[12.6269738,55.3523837],[12.6200898,55.2632576],[12.4627339,55.26722],[12.4552949,55.1778223],[12.2987046,55.1822303],[12.2897344,55.0923641],[12.6048608,55.0832904],[12.5872011,54.9036285],[12.2766618,54.9119031],[12.2610181,54.7331602],[12.1070691,54.7378161],[12.0858621,54.4681655],[11.7794953,54.4753579],[11.7837381,54.5654783],[11.1658525,54.5782155],[11.1706443,54.6686508],[10.8617173,54.6733956],[10.8651245,54.7634667],[10.7713646,54.7643888],[10.7707276,54.7372807],[10.7551428,54.7375776],[10.7544039,54.7195666],[10.7389074,54.7197588],[10.7384368,54.7108482],[10.7074486,54.7113045],[10.7041094,54.6756741],[10.5510973,54.6781698],[10.5547184,54.7670245],[10.2423994,54.7705935],[10.2459845,54.8604673],[10.0902268,54.8622134],[10.0873731,54.7723851],[9.1555798,54.7769557],[9.1562752,54.8675369],[8.5321973,54.8663765],[8.531432,54.95516],[8.3743941,54.9551655]],[[11.4577738,56.819554],[11.7849181,56.8127385],[11.7716715,56.6332796],[11.4459621,56.6401087],[11.4577738,56.819554]],[[11.3274736,57.3612962],[11.3161808,57.1818004],[11.1508692,57.1847276],[11.1456628,57.094962],[10.8157703,57.1001693],[10.8290599,57.3695272],[11.3274736,57.3612962]],[[11.5843266,56.2777928],[11.5782882,56.1880397],[11.7392309,56.1845765],[11.7456428,56.2743186],[11.5843266,56.2777928]],[[14.6825922,55.3639405],[14.8395247,55.3565231],[14.8263755,55.2671261],[15.1393406,55.2517359],[15.1532015,55.3410836],[15.309925,55.3330556],[15.295719,55.2437356],[15.1393406,55.2517359],[15.1255631,55.1623802],[15.2815819,55.1544167],[15.2535578,54.9757646],[14.6317464,55.0062496],[14.6825922,55.3639405]]],"terms_url":"http://wiki.openstreetmap.org/wiki/Vejmidte","terms_text":"Danish municipalities"},{"id":"wien.gv.at-labels","name":"Vienna: Beschriftungen (annotations)","type":"tms","template":"https://maps.wien.gv.at/wmts/beschriftung/normal/google3857/{zoom}/{y}/{x}.png","scaleExtent":[12,19],"polygon":[[[16.17,48.1],[16.17,48.33],[16.58,48.33],[16.58,48.1],[16.17,48.1]]],"terms_url":"https://data.wien.gv.at/","terms_text":"Stadt Wien"},{"id":"wien.gv.at-gp","name":"Vienna: Mehrzweckkarte (general purpose)","type":"tms","template":"https://maps.wien.gv.at/wmts/fmzk/pastell/google3857/{zoom}/{y}/{x}.jpeg","scaleExtent":[10,19],"polygon":[[[16.17,48.1],[16.17,48.33],[16.58,48.33],[16.58,48.1],[16.17,48.1]]],"terms_url":"https://data.wien.gv.at/","terms_text":"Stadt Wien"},{"id":"wien.gv.at-aerial_image","name":"Vienna: Orthofoto (aerial image)","type":"tms","template":"https://maps.wien.gv.at/wmts/lb/farbe/google3857/{zoom}/{y}/{x}.jpeg","scaleExtent":[10,19],"polygon":[[[16.17,48.1],[16.17,48.33],[16.58,48.33],[16.58,48.1],[16.17,48.1]]],"terms_url":"https://data.wien.gv.at/","terms_text":"Stadt Wien"}];
18951 var presets = {"aerialway":{"fields":["aerialway"],"geometry":["point","vertex","line"],"tags":{"aerialway":"*"},"terms":["ski lift","funifor","funitel"],"searchable":false,"name":"Aerialway"},"aeroway":{"icon":"airport","fields":["aeroway"],"geometry":["point","vertex","line","area"],"tags":{"aeroway":"*"},"searchable":false,"name":"Aeroway"},"amenity":{"fields":["amenity"],"geometry":["point","vertex","area"],"tags":{"amenity":"*"},"searchable":false,"name":"Amenity"},"highway":{"fields":["highway"],"geometry":["point","vertex","line","area"],"tags":{"highway":"*"},"searchable":false,"name":"Highway"},"place":{"fields":["place"],"geometry":["point","vertex","area"],"tags":{"place":"*"},"searchable":false,"name":"Place"},"power":{"geometry":["point","vertex","line","area"],"tags":{"power":"*"},"fields":["power"],"searchable":false,"name":"Power"},"railway":{"fields":["railway"],"geometry":["point","vertex","line","area"],"tags":{"railway":"*"},"searchable":false,"name":"Railway"},"roundabout":{"geometry":["vertex","line"],"tags":{"junction":"roundabout"},"name":"Roundabout","searchable":false},"waterway":{"fields":["waterway"],"geometry":["point","vertex","line","area"],"tags":{"waterway":"*"},"searchable":false,"name":"Waterway"},"address":{"fields":["address"],"geometry":["point"],"tags":{"addr:housenumber":"*"},"addTags":{},"removeTags":{},"matchScore":0.2,"name":"Address"},"advertising/billboard":{"fields":["parallel_direction","lit"],"geometry":["point","vertex","line"],"tags":{"advertising":"billboard"},"name":"Billboard"},"aerialway/cable_car":{"geometry":["line"],"terms":["tramway","ropeway"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"cable_car"},"name":"Cable Car"},"aerialway/chair_lift":{"geometry":["line"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"chair_lift"},"name":"Chair Lift"},"aerialway/gondola":{"geometry":["line"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"gondola"},"name":"Gondola"},"aerialway/magic_carpet":{"geometry":["line"],"fields":["aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"magic_carpet"},"name":"Magic Carpet Lift"},"aerialway/platter":{"geometry":["line"],"terms":["button lift","poma lift"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"platter"},"name":"Platter Lift"},"aerialway/pylon":{"geometry":["point","vertex"],"fields":["ref"],"tags":{"aerialway":"pylon"},"name":"Aerialway Pylon"},"aerialway/rope_tow":{"geometry":["line"],"terms":["handle tow","bugel lift"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"rope_tow"},"name":"Rope Tow Lift"},"aerialway/station":{"geometry":["point","vertex"],"fields":["aerialway/access","aerialway/summer/access","elevation"],"tags":{"aerialway":"station"},"name":"Aerialway Station"},"aerialway/t-bar":{"geometry":["line"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"t-bar"},"name":"T-bar Lift"},"aeroway/aerodrome":{"icon":"airport","geometry":["point","area"],"fields":["ref","iata","icao","operator","internet_access","internet_access/fee","internet_access/ssid"],"terms":["airplane","airport","aerodrome"],"tags":{"aeroway":"aerodrome"},"name":"Airport"},"aeroway/apron":{"icon":"airport","geometry":["area"],"terms":["ramp"],"fields":["ref","surface"],"tags":{"aeroway":"apron"},"name":"Apron"},"aeroway/gate":{"icon":"airport","geometry":["point"],"fields":["ref"],"tags":{"aeroway":"gate"},"name":"Airport gate"},"aeroway/hangar":{"geometry":["area"],"fields":["building_area"],"tags":{"aeroway":"hangar"},"name":"Hangar"},"aeroway/helipad":{"icon":"heliport","geometry":["point","area"],"terms":["helicopter","helipad","heliport"],"tags":{"aeroway":"helipad"},"name":"Helipad"},"aeroway/runway":{"geometry":["line","area"],"terms":["landing strip"],"fields":["ref","surface","length","width"],"tags":{"aeroway":"runway"},"name":"Runway"},"aeroway/taxiway":{"geometry":["line"],"fields":["ref","surface"],"tags":{"aeroway":"taxiway"},"name":"Taxiway"},"aeroway/terminal":{"geometry":["point","area"],"terms":["airport","aerodrome"],"fields":["operator","building_area"],"tags":{"aeroway":"terminal"},"name":"Airport terminal"},"amenity/register_office":{"icon":"town-hall","fields":["address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"register_office"},"name":"Register Office","searchable":false},"amenity/swimming_pool":{"icon":"swimming","geometry":["point","vertex","area"],"tags":{"amenity":"swimming_pool"},"name":"Swimming Pool","searchable":false},"amenity/arts_centre":{"icon":"theatre","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"arts_centre"},"name":"Arts Center"},"amenity/atm":{"icon":"bank","fields":["operator","currency_multi","drive_through"],"geometry":["point","vertex"],"terms":["money","cash","machine"],"tags":{"amenity":"atm"},"name":"ATM"},"amenity/bank":{"icon":"bank","fields":["atm","operator","address","building_area","opening_hours","drive_through"],"geometry":["point","area"],"terms":["credit union","check","deposit","fund","investment","repository","reserve","safe","savings","stock","treasury","trust","vault"],"tags":{"amenity":"bank"},"name":"Bank"},"amenity/bar":{"icon":"bar","fields":["operator","address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["dive","beer","bier","booze"],"tags":{"amenity":"bar"},"name":"Bar"},"amenity/bbq":{"fields":["covered","fuel"],"geometry":["point"],"terms":["bbq","grill"],"tags":{"amenity":"bbq"},"name":"Barbecue/Grill"},"amenity/bench":{"fields":["backrest"],"geometry":["point","vertex","line"],"terms":["seat"],"tags":{"amenity":"bench"},"name":"Bench"},"amenity/bicycle_parking":{"icon":"bicycle","fields":["bicycle_parking","capacity","operator","covered","access_simple"],"geometry":["point","vertex","area"],"terms":["bike"],"tags":{"amenity":"bicycle_parking"},"name":"Bicycle Parking"},"amenity/bicycle_rental":{"icon":"bicycle","fields":["capacity","network","operator"],"geometry":["point","vertex","area"],"terms":["bike"],"tags":{"amenity":"bicycle_rental"},"name":"Bicycle Rental"},"amenity/bicycle_repair_station":{"icon":"bicycle","fields":["operator","brand","opening_hours","fee","service/bicycle"],"geometry":["point","vertex","area"],"terms":["bike","repair","chain","pump"],"tags":{"amenity":"bicycle_repair_station"},"name":"Bicycle Repair Tool Stand"},"amenity/biergarten":{"icon":"beer","fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"tags":{"amenity":"biergarten"},"terms":["beer","bier","booze"],"name":"Beer Garden"},"amenity/boat_rental":{"fields":["operator"],"geometry":["point","area"],"tags":{"amenity":"boat_rental"},"name":"Boat Rental"},"amenity/bureau_de_change":{"icon":"bank","fields":["operator","currency_multi"],"geometry":["point","vertex"],"terms":["bureau de change","money changer"],"tags":{"amenity":"bureau_de_change"},"name":"Currency Exchange"},"amenity/bus_station":{"icon":"bus","fields":["building_area","operator","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"amenity":"bus_station"},"name":"Bus Station"},"amenity/cafe":{"icon":"cafe","fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["bistro","coffee","tea"],"tags":{"amenity":"cafe"},"name":"Cafe"},"amenity/car_rental":{"icon":"car","fields":["operator"],"geometry":["point","area"],"tags":{"amenity":"car_rental"},"name":"Car Rental"},"amenity/car_sharing":{"icon":"car","fields":["operator","capacity"],"geometry":["point","area"],"tags":{"amenity":"car_sharing"},"name":"Car Sharing"},"amenity/car_wash":{"icon":"car","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"car_wash"},"name":"Car Wash"},"amenity/casino":{"fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["gambling","roulette","craps","poker","blackjack"],"tags":{"amenity":"casino"},"name":"Casino"},"amenity/charging_station":{"icon":"car","fields":["operator","capacity"],"geometry":["point","area"],"tags":{"amenity":"charging_station"},"terms":["EV","Electric Vehicle","Supercharger"],"name":"Charging Station"},"amenity/childcare":{"icon":"school","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["daycare","orphanage","playgroup"],"tags":{"amenity":"childcare"},"name":"Nursery/Childcare"},"amenity/cinema":{"icon":"cinema","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["drive-in","film","flick","movie","theater","picture","show","screen"],"tags":{"amenity":"cinema"},"name":"Cinema"},"amenity/clinic":{"icon":"hospital","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medical","urgentcare"],"tags":{"amenity":"clinic"},"name":"Clinic"},"amenity/clock":{"fields":["support","display","visibility","date"],"geometry":["point","vertex"],"tags":{"amenity":"clock"},"name":"Clock"},"amenity/college":{"icon":"college","fields":["operator","address","internet_access","internet_access/ssid"],"geometry":["point","area"],"terms":["university"],"tags":{"amenity":"college"},"name":"College Grounds"},"amenity/community_centre":{"icon":"town-hall","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["event","hall"],"tags":{"amenity":"community_centre"},"name":"Community Center"},"amenity/compressed_air":{"icon":"car","geometry":["point","area"],"tags":{"amenity":"compressed_air"},"name":"Compressed Air"},"amenity/courthouse":{"icon":"town-hall","fields":["operator","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"courthouse"},"name":"Courthouse"},"amenity/coworking_space":{"icon":"commercial","fields":["address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["coworking","office"],"tags":{"amenity":"coworking_space"},"name":"Coworking Space"},"amenity/crematorium":{"icon":"cemetery","fields":["website","phone","opening_hours","wheelchair"],"geometry":["area","point"],"tags":{"amenity":"crematorium"},"terms":["cemetery","funeral"],"name":"Crematorium"},"amenity/dentist":{"icon":"dentist","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["tooth","teeth"],"tags":{"amenity":"dentist"},"name":"Dentist"},"amenity/doctors":{"icon":"hospital","fields":["address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medic*"],"tags":{"amenity":"doctors"},"name":"Doctor"},"amenity/dojo":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["martial arts","dojang"],"tags":{"amenity":"dojo"},"name":"Dojo / Martial Arts Academy"},"amenity/drinking_water":{"icon":"water","geometry":["point"],"tags":{"amenity":"drinking_water"},"terms":["fountain","potable"],"name":"Drinking Water"},"amenity/embassy":{"icon":"embassy","fields":["country","address","building_area"],"geometry":["point","area"],"tags":{"amenity":"embassy"},"name":"Embassy"},"amenity/fast_food":{"icon":"fast-food","fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"geometry":["point","area"],"tags":{"amenity":"fast_food"},"terms":["restaurant","takeaway"],"name":"Fast Food"},"amenity/ferry_terminal":{"icon":"ferry","fields":["network","operator","address","building_area"],"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"ferry_terminal"},"name":"Ferry Terminal"},"amenity/fire_station":{"icon":"fire-station","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"fire_station"},"name":"Fire Station"},"amenity/food_court":{"icon":"restaurant","fields":["operator","address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["fast food","restaurant","food"],"tags":{"amenity":"food_court"},"name":"Food Court"},"amenity/fountain":{"geometry":["point","area"],"tags":{"amenity":"fountain"},"name":"Fountain"},"amenity/fuel":{"icon":"fuel","fields":["operator","address","opening_hours","fuel_multi"],"geometry":["point","area"],"terms":["petrol","fuel","gasoline","propane","diesel","lng","cng","biodiesel"],"tags":{"amenity":"fuel"},"name":"Gas Station"},"amenity/grave_yard":{"icon":"cemetery","fields":["religion","denomination"],"geometry":["point","area"],"tags":{"amenity":"grave_yard"},"name":"Graveyard"},"amenity/grit_bin":{"fields":["access_simple"],"geometry":["point","vertex"],"tags":{"amenity":"grit_bin"},"terms":["salt","sand"],"name":"Grit Bin"},"amenity/hospital":{"icon":"hospital","fields":["operator","address","emergency"],"geometry":["point","area"],"terms":["clinic","doctor","emergency room","health service","hospice","infirmary","institution","nursing home","sanatorium","sanitarium","sick","surgery","ward"],"tags":{"amenity":"hospital"},"name":"Hospital Grounds"},"amenity/hunting_stand":{"geometry":["point","vertex","area"],"terms":["game","lookout","shoot","wild","watch"],"tags":{"amenity":"hunting_stand"},"name":"Hunting Stand"},"amenity/ice_cream":{"icon":"ice-cream","fields":["address","building_area","opening_hours","takeaway","delivery","outdoor_seating"],"geometry":["point","area"],"terms":["gelato","sorbet","sherbet","frozen","yogurt"],"tags":{"amenity":"ice_cream"},"name":"Ice Cream Shop"},"amenity/internet_cafe":{"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["cybercafe","taxiphone","teleboutique","coffee","cafe","net","lanhouse"],"tags":{"amenity":"internet_cafe"},"name":"Internet Cafe"},"amenity/kindergarten":{"icon":"school","fields":["operator","address"],"geometry":["point","area"],"terms":["kindergarden","pre-school"],"tags":{"amenity":"kindergarten"},"name":"Preschool/Kindergarten Grounds"},"amenity/library":{"icon":"library","fields":["operator","building_area","address","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["book"],"tags":{"amenity":"library"},"name":"Library"},"amenity/marketplace":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"marketplace"},"name":"Marketplace"},"amenity/motorcycle_parking":{"icon":"scooter","fields":["capacity","operator","covered","access_simple"],"geometry":["point","vertex","area"],"tags":{"amenity":"motorcycle_parking"},"name":"Motorcycle Parking"},"amenity/nightclub":{"icon":"bar","fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"tags":{"amenity":"nightclub"},"terms":["disco*","night club","dancing","dance club"],"name":"Nightclub"},"amenity/parking_entrance":{"icon":"entrance","fields":["access_simple","ref"],"geometry":["vertex"],"tags":{"amenity":"parking_entrance"},"name":"Parking Garage Entrance/Exit"},"amenity/parking_space":{"fields":["capacity"],"geometry":["point","vertex","area"],"terms":[],"tags":{"amenity":"parking_space"},"name":"Parking Space"},"amenity/parking":{"icon":"parking","fields":["operator","parking","capacity","fee","access_simple","supervised","park_ride","surface","maxstay","address"],"geometry":["point","vertex","area"],"tags":{"amenity":"parking"},"terms":[],"name":"Car Parking"},"amenity/pharmacy":{"icon":"pharmacy","fields":["operator","address","building_area","opening_hours","drive_through"],"geometry":["point","area"],"tags":{"amenity":"pharmacy"},"terms":["drug*","med*","prescription"],"name":"Pharmacy"},"amenity/place_of_worship":{"icon":"place-of-worship","fields":["religion","denomination","address","building_area"],"geometry":["point","area"],"terms":["abbey","basilica","bethel","cathedral","chancel","chantry","chapel","church","fold","house of God","house of prayer","house of worship","minster","mission","mosque","oratory","parish","sacellum","sanctuary","shrine","synagogue","tabernacle","temple"],"tags":{"amenity":"place_of_worship"},"name":"Place of Worship"},"amenity/place_of_worship/buddhist":{"icon":"place-of-worship","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["stupa","vihara","monastery","temple","pagoda","zendo","dojo"],"tags":{"amenity":"place_of_worship","religion":"buddhist"},"name":"Buddhist Temple"},"amenity/place_of_worship/christian":{"icon":"religious-christian","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["christian","abbey","basilica","bethel","cathedral","chancel","chantry","chapel","fold","house of God","house of prayer","house of worship","minster","mission","oratory","parish","sacellum","sanctuary","shrine","tabernacle","temple"],"tags":{"amenity":"place_of_worship","religion":"christian"},"name":"Church"},"amenity/place_of_worship/jewish":{"icon":"religious-jewish","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["jewish"],"tags":{"amenity":"place_of_worship","religion":"jewish"},"name":"Synagogue"},"amenity/place_of_worship/muslim":{"icon":"religious-muslim","fields":["denomination","building_area","address"],"geometry":["point","area"],"terms":["muslim"],"tags":{"amenity":"place_of_worship","religion":"muslim"},"name":"Mosque"},"amenity/planetarium":{"icon":"museum","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["museum","astronomy","observatory"],"tags":{"amenity":"planetarium"},"name":"Planetarium"},"amenity/police":{"icon":"police","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["badge","constable","constabulary","cop","detective","fed","law","enforcement","officer","patrol"],"tags":{"amenity":"police"},"name":"Police"},"amenity/post_box":{"icon":"post","fields":["operator","collection_times","drive_through","ref"],"geometry":["point","vertex"],"tags":{"amenity":"post_box"},"terms":["letter","post"],"name":"Mailbox"},"amenity/post_office":{"icon":"post","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["letter","mail"],"tags":{"amenity":"post_office"},"name":"Post Office"},"amenity/prison":{"icon":"prison","fields":["operator","address"],"geometry":["point","area"],"terms":["cell","jail"],"tags":{"amenity":"prison"},"name":"Prison Grounds"},"amenity/pub":{"icon":"beer","fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"geometry":["point","area"],"tags":{"amenity":"pub"},"terms":["alcohol","drink","dive","beer","bier","booze"],"name":"Pub"},"amenity/public_bath":{"icon":"water","fields":["bath/type","bath/open_air","bath/sand_bath","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"public_bath"},"terms":["onsen","foot bath","hot springs"],"name":"Public Bath"},"amenity/public_bookcase":{"icon":"library","fields":["name","operator","capacity","website"],"geometry":["point","area"],"terms":["library","bookcrossing"],"tags":{"amenity":"public_bookcase"},"name":"Public Bookcase"},"amenity/ranger_station":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["visitor center","visitor centre","permit center","permit centre","backcountry office","warden office","warden center"],"tags":{"amenity":"ranger_station"},"name":"Ranger Station"},"amenity/recycling_centre":{"icon":"waste-basket","fields":["operator","address","opening_hours","recycling_accepts"],"geometry":["point","area"],"terms":["bottle","can","dump","glass","garbage","rubbish","scrap","trash"],"tags":{"amenity":"recycling","recycling_type":"centre"},"name":"Recycling Center"},"amenity/recycling":{"icon":"waste-basket","fields":["recycling_type","recycling_accepts","collection_times"],"geometry":["point","area"],"terms":["bin","can","bottle","glass","garbage","rubbish","scrap","trash"],"tags":{"amenity":"recycling"},"name":"Recycling"},"amenity/restaurant":{"icon":"restaurant","fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"geometry":["point","area"],"terms":["bar","breakfast","cafe","café","canteen","coffee","dine","dining","dinner","drive-in","eat","grill","lunch","table"],"tags":{"amenity":"restaurant"},"name":"Restaurant"},"amenity/sanitary_dump_station":{"fields":["operator","access_toilets","fee","water_point"],"geometry":["point","vertex","area"],"terms":["Motor Home","Camper","Sanitary","Dump Station","Elsan","CDP","CTDP","Chemical Toilet"],"tags":{"amenity":"sanitary_dump_station"},"name":"RV Toilet Disposal"},"amenity/school":{"icon":"school","fields":["operator","address"],"geometry":["point","area"],"terms":["academy","elementary school","middle school","high school"],"tags":{"amenity":"school"},"name":"School Grounds"},"amenity/shelter":{"fields":["shelter_type","bin"],"geometry":["point","vertex","area"],"terms":["lean-to","gazebo","picnic"],"tags":{"amenity":"shelter"},"name":"Shelter"},"amenity/social_facility":{"fields":["operator","address","building_area","opening_hours","wheelchair","social_facility_for"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility"},"name":"Social Facility"},"amenity/social_facility/food_bank":{"fields":["operator","address","building_area","opening_hours","social_facility_for"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility","social_facility":"food_bank"},"name":"Food Bank"},"amenity/social_facility/group_home":{"fields":["operator","address","building_area","opening_hours","wheelchair","social_facility_for"],"geometry":["point","area"],"terms":["old","senior","living"],"tags":{"amenity":"social_facility","social_facility":"group_home","social_facility:for":"senior"},"name":"Elderly Group Home"},"amenity/social_facility/homeless_shelter":{"fields":["operator","address","building_area","opening_hours","wheelchair","social_facility_for","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["houseless","unhoused","displaced"],"tags":{"amenity":"social_facility","social_facility":"shelter","social_facility:for":"homeless"},"name":"Homeless Shelter"},"amenity/studio":{"icon":"music","fields":["studio","address","building_area"],"geometry":["point","area"],"terms":["recording","radio","television"],"tags":{"amenity":"studio"},"name":"Studio"},"amenity/taxi":{"icon":"car","fields":["operator","capacity"],"geometry":["point","vertex","area"],"terms":["cab"],"tags":{"amenity":"taxi"},"name":"Taxi Stand"},"amenity/telephone":{"icon":"telephone","geometry":["point","vertex"],"tags":{"amenity":"telephone"},"terms":["phone"],"name":"Telephone"},"amenity/theatre":{"icon":"theatre","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["theatre","performance","play","musical"],"tags":{"amenity":"theatre"},"name":"Theater"},"amenity/toilets":{"icon":"toilets","fields":["toilets/disposal","operator","building_area","access_toilets","gender","fee","diaper"],"geometry":["point","vertex","area"],"terms":["bathroom","restroom","outhouse","privy","head","lavatory","latrine","water closet","WC","W.C."],"tags":{"amenity":"toilets"},"name":"Toilets"},"amenity/townhall":{"icon":"town-hall","fields":["operator","address","building_area"],"geometry":["point","area"],"terms":["village","city","government","courthouse","municipal"],"tags":{"amenity":"townhall"},"name":"Town Hall"},"amenity/university":{"icon":"college","fields":["operator","address","internet_access","internet_access/ssid"],"geometry":["point","area"],"terms":["college"],"tags":{"amenity":"university"},"name":"University Grounds"},"amenity/vending_machine/cigarettes":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["cigarette"],"tags":{"amenity":"vending_machine","vending":"cigarettes"},"name":"Cigarette Vending Machine"},"amenity/vending_machine/condoms":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["condom"],"tags":{"amenity":"vending_machine","vending":"condoms"},"name":"Condom Vending Machine"},"amenity/vending_machine/drinks":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["drink","soda","beverage","juice","pop"],"tags":{"amenity":"vending_machine","vending":"drinks"},"name":"Drink Vending Machine"},"amenity/vending_machine/excrement_bags":{"fields":["operator","fee","bin","payment_multi","currency_multi"],"geometry":["point"],"terms":["excrement bags","poop","dog","animal"],"tags":{"amenity":"vending_machine","vending":"excrement_bags"},"name":"Excrement Bag Vending Machine"},"amenity/vending_machine/news_papers":{"fields":["operator","fee","payment_multi","currency_multi"],"geometry":["point"],"terms":["newspaper"],"tags":{"amenity":"vending_machine","vending":"news_papers"},"name":"Newspaper Vending Machine"},"amenity/vending_machine/parcel_pickup_dropoff":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parcel","mail","pickup"],"tags":{"amenity":"vending_machine","vending":"parcel_pickup;parcel_mail_in"},"name":"Parcel Pickup/Dropoff Vending Machine"},"amenity/vending_machine/parking_tickets":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["parking","ticket"],"tags":{"amenity":"vending_machine","vending":"parking_tickets"},"name":"Parking Ticket Vending Machine"},"amenity/vending_machine/public_transport_tickets":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["bus","train","ferry","rail","ticket","transportation"],"tags":{"amenity":"vending_machine","vending":"public_transport_tickets"},"name":"Transit Ticket Vending Machine"},"amenity/vending_machine/sweets":{"fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["candy","gum","chip","pretzel","cookie","cracker"],"tags":{"amenity":"vending_machine","vending":"sweets"},"name":"Snack Vending Machine"},"amenity/vending_machine/vending_machine":{"fields":["vending","operator","payment_multi","currency_multi"],"geometry":["point"],"terms":[],"tags":{"amenity":"vending_machine"},"name":"Vending Machine"},"amenity/veterinary":{"icon":"dog-park","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["pet clinic","veterinarian","animal hospital","pet doctor"],"tags":{"amenity":"veterinary"},"name":"Veterinary"},"amenity/waste_basket":{"icon":"waste-basket","fields":["collection_times"],"geometry":["point","vertex","area"],"tags":{"amenity":"waste_basket"},"terms":["bin","garbage","rubbish","litter","trash"],"name":"Waste Basket"},"amenity/waste_disposal":{"icon":"waste-basket","fields":["collection_times"],"geometry":["point","vertex","area"],"tags":{"amenity":"waste_disposal"},"terms":["garbage","rubbish","litter","trash"],"name":"Garbage Dumpster"},"amenity/waste_transfer_station":{"icon":"waste-basket","fields":["operator","address","opening_hours"],"geometry":["point","area"],"terms":["dump","garbage","recycling","rubbish","scrap","trash"],"tags":{"amenity":"waste_transfer_station"},"name":"Waste Transfer Station"},"amenity/water_point":{"icon":"water","geometry":["area","vertex","point"],"tags":{"amenity":"water_point"},"name":"RV Drinking Water"},"area":{"name":"Area","tags":{"area":"yes"},"geometry":["area"],"matchScore":0.1},"area/highway":{"fields":["area/highway"],"geometry":["area"],"tags":{"area:highway":"*"},"name":"Road Surface"},"barrier":{"icon":"roadblock","geometry":["point","vertex","line","area"],"tags":{"barrier":"*"},"fields":["barrier"],"name":"Barrier","matchScore":0.4},"barrier/entrance":{"icon":"entrance","geometry":["vertex"],"tags":{"barrier":"entrance"},"name":"Entrance","searchable":false},"barrier/block":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex"],"tags":{"barrier":"block"},"name":"Block"},"barrier/bollard":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex","line"],"tags":{"barrier":"bollard"},"name":"Bollard"},"barrier/cattle_grid":{"icon":"prison","geometry":["vertex"],"tags":{"barrier":"cattle_grid"},"name":"Cattle Grid"},"barrier/city_wall":{"icon":"prison","fields":["height"],"geometry":["line","area"],"tags":{"barrier":"city_wall"},"name":"City Wall"},"barrier/cycle_barrier":{"icon":"roadblock","fields":["access"],"geometry":["vertex"],"tags":{"barrier":"cycle_barrier"},"name":"Cycle Barrier"},"barrier/ditch":{"icon":"roadblock","geometry":["line","area"],"tags":{"barrier":"ditch"},"name":"Trench","matchScore":0.25},"barrier/fence":{"icon":"prison","fields":["fence_type","height"],"geometry":["line"],"tags":{"barrier":"fence"},"name":"Fence","matchScore":0.25},"barrier/gate":{"icon":"prison","fields":["access"],"geometry":["point","vertex","line"],"tags":{"barrier":"gate"},"name":"Gate"},"barrier/hedge":{"fields":["height"],"geometry":["line","area"],"tags":{"barrier":"hedge"},"name":"Hedge","matchScore":0.25},"barrier/kissing_gate":{"icon":"prison","fields":["access"],"geometry":["vertex"],"tags":{"barrier":"kissing_gate"},"name":"Kissing Gate"},"barrier/lift_gate":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex"],"tags":{"barrier":"lift_gate"},"name":"Lift Gate"},"barrier/retaining_wall":{"geometry":["line","area"],"tags":{"barrier":"retaining_wall"},"name":"Retaining Wall"},"barrier/stile":{"icon":"roadblock","fields":["access"],"geometry":["point","vertex"],"tags":{"barrier":"stile"},"name":"Stile"},"barrier/toll_booth":{"icon":"roadblock","fields":["access"],"geometry":["vertex"],"tags":{"barrier":"toll_booth"},"name":"Toll Booth"},"barrier/wall":{"icon":"prison","fields":["wall","height"],"geometry":["line","area"],"tags":{"barrier":"wall"},"name":"Wall","matchScore":0.25},"boundary/administrative":{"name":"Administrative Boundary","geometry":["line"],"tags":{"boundary":"administrative"},"fields":["admin_level"]},"building":{"icon":"building","fields":["building","levels","address"],"geometry":["point","area"],"tags":{"building":"*"},"matchScore":0.6,"terms":[],"name":"Building"},"building/bunker":{"fields":["address","levels"],"geometry":["area"],"tags":{"building":"bunker"},"matchScore":0.5,"name":"Bunker","searchable":false},"building/entrance":{"icon":"entrance","geometry":["vertex"],"tags":{"building":"entrance"},"name":"Entrance/Exit","searchable":false},"building/train_station":{"icon":"building","fields":["address","levels"],"geometry":["point","vertex","area"],"tags":{"building":"train_station"},"matchScore":0.5,"name":"Train Station","searchable":false},"building/apartments":{"icon":"commercial","fields":["address","levels"],"geometry":["area"],"tags":{"building":"apartments"},"matchScore":0.5,"name":"Apartments"},"building/barn":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"barn"},"matchScore":0.5,"name":"Barn"},"building/cabin":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"cabin"},"matchScore":0.5,"name":"Cabin"},"building/cathedral":{"icon":"place-of-worship","fields":["address","levels"],"geometry":["area"],"tags":{"building":"cathedral"},"matchScore":0.5,"name":"Cathedral Building"},"building/chapel":{"icon":"place-of-worship","fields":["address","levels"],"geometry":["area"],"tags":{"building":"chapel"},"matchScore":0.5,"name":"Chapel Building"},"building/church":{"icon":"place-of-worship","fields":["address","levels"],"geometry":["area"],"tags":{"building":"church"},"matchScore":0.5,"name":"Church Building"},"building/college":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["university"],"tags":{"building":"college"},"matchScore":0.5,"name":"College Building"},"building/commercial":{"icon":"commercial","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"commercial"},"matchScore":0.5,"name":"Commercial Building"},"building/construction":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"construction"},"matchScore":0.5,"name":"Building Under Construction"},"building/detached":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"detached"},"terms":["home","single","family","residence","dwelling"],"matchScore":0.5,"name":"Detached House"},"building/dormitory":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"dormitory"},"matchScore":0.5,"name":"Dormitory"},"building/garage":{"icon":"warehouse","fields":["capacity"],"geometry":["area"],"tags":{"building":"garage"},"matchScore":0.5,"name":"Garage"},"building/garages":{"icon":"warehouse","fields":["capacity"],"geometry":["area"],"tags":{"building":"garages"},"matchScore":0.5,"name":"Garages"},"building/greenhouse":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"greenhouse"},"matchScore":0.5,"name":"Greenhouse"},"building/hospital":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"hospital"},"matchScore":0.5,"name":"Hospital Building"},"building/hotel":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"hotel"},"matchScore":0.5,"name":"Hotel Building"},"building/house":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"house"},"terms":["home","family","residence","dwelling"],"matchScore":0.5,"name":"House"},"building/hut":{"geometry":["area"],"tags":{"building":"hut"},"matchScore":0.5,"name":"Hut"},"building/industrial":{"icon":"industrial","fields":["address","levels"],"geometry":["area"],"tags":{"building":"industrial"},"matchScore":0.5,"name":"Industrial Building"},"building/kindergarten":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["kindergarden","pre-school"],"tags":{"building":"kindergarten"},"matchScore":0.5,"name":"Preschool/Kindergarten Building"},"building/public":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"public"},"matchScore":0.5,"name":"Public Building"},"building/residential":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"residential"},"matchScore":0.5,"name":"Residential Building"},"building/retail":{"icon":"building","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"retail"},"matchScore":0.5,"name":"Retail Building"},"building/roof":{"icon":"building","fields":["address"],"geometry":["area"],"tags":{"building":"roof"},"matchScore":0.5,"name":"Roof"},"building/school":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["academy","elementary school","middle school","high school"],"tags":{"building":"school"},"matchScore":0.5,"name":"School Building"},"building/semidetached_house":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"semidetached_house"},"terms":["home","double","duplex","twin","family","residence","dwelling"],"matchScore":0.5,"name":"Semi-Detached House"},"building/shed":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"shed"},"matchScore":0.5,"name":"Shed"},"building/stable":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"stable"},"matchScore":0.5,"name":"Stable"},"building/static_caravan":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"static_caravan"},"matchScore":0.5,"name":"Static Mobile Home"},"building/terrace":{"icon":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"terrace"},"terms":["home","terrace","brownstone","family","residence","dwelling"],"matchScore":0.5,"name":"Row Houses"},"building/university":{"icon":"building","fields":["address","levels"],"geometry":["area"],"terms":["college"],"tags":{"building":"university"},"matchScore":0.5,"name":"University Building"},"building/warehouse":{"icon":"warehouse","fields":["address","levels"],"geometry":["area"],"tags":{"building":"warehouse"},"matchScore":0.5,"name":"Warehouse"},"camp_site/camp_pitch":{"icon":"campsite","fields":["ref"],"geometry":["point","area"],"terms":["tent","rv"],"tags":{"camp_site":"camp_pitch"},"name":"Camp Pitch"},"craft":{"icon":"marker-stroked","fields":["craft","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"*"},"terms":[],"name":"Craft"},"craft/jeweler":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"jeweler"},"name":"Jeweler","searchable":false},"craft/locksmith":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"locksmith"},"name":"Locksmith","searchable":false},"craft/optician":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"optician"},"name":"Optician","searchable":false},"craft/tailor":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"craft":"tailor"},"name":"Tailor","searchable":false},"craft/basket_maker":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"basket_maker"},"name":"Basket Maker"},"craft/beekeeper":{"icon":"farm","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"beekeeper"},"name":"Beekeeper"},"craft/blacksmith":{"icon":"farm","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"blacksmith"},"name":"Blacksmith"},"craft/boatbuilder":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"boatbuilder"},"name":"Boat Builder"},"craft/bookbinder":{"icon":"library","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["book repair"],"tags":{"craft":"bookbinder"},"name":"Bookbinder"},"craft/brewery":{"icon":"beer","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["beer","bier"],"tags":{"craft":"brewery"},"name":"Brewery"},"craft/carpenter":{"icon":"logging","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["woodworker"],"tags":{"craft":"carpenter"},"name":"Carpenter"},"craft/carpet_layer":{"icon":"square","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"carpet_layer"},"name":"Carpet Layer"},"craft/caterer":{"icon":"bakery","fields":["cuisine","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"caterer"},"name":"Caterer"},"craft/clockmaker":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"clockmaker"},"name":"Clockmaker"},"craft/confectionery":{"icon":"bakery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sweets","candy"],"tags":{"craft":"confectionery"},"name":"Confectionery"},"craft/dressmaker":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["seamstress"],"tags":{"craft":"dressmaker"},"name":"Dressmaker"},"craft/electrician":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["power","wire"],"tags":{"craft":"electrician"},"name":"Electrician"},"craft/gardener":{"icon":"garden","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["landscaper","grounds keeper"],"tags":{"craft":"gardener"},"name":"Gardener"},"craft/glaziery":{"icon":"fire-station","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["glass","stained-glass","window"],"tags":{"craft":"glaziery"},"name":"Glaziery"},"craft/handicraft":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"handicraft"},"name":"Handicraft"},"craft/hvac":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["heat*","vent*","air conditioning"],"tags":{"craft":"hvac"},"name":"HVAC"},"craft/insulator":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"insulation"},"name":"Insulator"},"craft/key_cutter":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"key_cutter"},"name":"Key Cutter"},"craft/metal_construction":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"metal_construction"},"name":"Metal Construction"},"craft/painter":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"painter"},"name":"Painter"},"craft/photographer":{"icon":"camera","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"photographer"},"name":"Photographer"},"craft/photographic_laboratory":{"icon":"camera","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["film"],"tags":{"craft":"photographic_laboratory"},"name":"Photographic Laboratory"},"craft/plasterer":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"plasterer"},"name":"Plasterer"},"craft/plumber":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["pipe"],"tags":{"craft":"plumber"},"name":"Plumber"},"craft/pottery":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ceramic"],"tags":{"craft":"pottery"},"name":"Pottery"},"craft/rigger":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"rigger"},"name":"Rigger"},"craft/roofer":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"roofer"},"name":"Roofer"},"craft/saddler":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"saddler"},"name":"Saddler"},"craft/sailmaker":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sailmaker"},"name":"Sailmaker"},"craft/sawmill":{"icon":"park","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["lumber"],"tags":{"craft":"sawmill"},"name":"Sawmill"},"craft/scaffolder":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"scaffolder"},"name":"Scaffolder"},"craft/sculpter":{"icon":"art-gallery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sculpter"},"name":"Sculpter"},"craft/shoemaker":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["cobbler"],"tags":{"craft":"shoemaker"},"name":"Shoemaker"},"craft/stonemason":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["masonry"],"tags":{"craft":"stonemason"},"name":"Stonemason"},"craft/sweep":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sweep"},"name":"Chimney Sweep"},"craft/tiler":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tiler"},"name":"Tiler"},"craft/tinsmith":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"tinsmith"},"name":"Tinsmith"},"craft/upholsterer":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"upholsterer"},"name":"Upholsterer"},"craft/watchmaker":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"watchmaker"},"name":"Watchmaker"},"craft/window_construction":{"icon":"marker-stroked","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["glass"],"tags":{"craft":"window_construction"},"name":"Window Construction"},"craft/winery":{"icon":"alcohol-shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"winery"},"name":"Winery"},"embankment":{"geometry":["line"],"tags":{"embankment":"yes"},"name":"Embankment","matchScore":0.2},"emergency/designated":{"fields":[],"geometry":["line"],"tags":{"emergency":"designated"},"terms":[],"name":"Emergency Access Designated","searchable":false,"matchScore":0.01},"emergency/destination":{"fields":[],"geometry":["line"],"tags":{"emergency":"destination"},"terms":[],"name":"Emergency Access Destination","searchable":false,"matchScore":0.01},"emergency/no":{"fields":[],"geometry":["line"],"tags":{"emergency":"no"},"terms":[],"name":"Emergency Access No","searchable":false,"matchScore":0.01},"emergency/official":{"fields":[],"geometry":["line"],"tags":{"emergency":"official"},"terms":[],"name":"Emergency Access Official","searchable":false,"matchScore":0.01},"emergency/private":{"fields":[],"geometry":["line"],"tags":{"emergency":"private"},"terms":[],"name":"Emergency Access Private","searchable":false,"matchScore":0.01},"emergency/yes":{"fields":[],"geometry":["line"],"tags":{"emergency":"yes"},"terms":[],"name":"Emergency Access Yes","searchable":false,"matchScore":0.01},"emergency/ambulance_station":{"icon":"hospital","fields":["operator","building_area","address"],"geometry":["point","area"],"terms":["EMS","EMT","rescue"],"tags":{"emergency":"ambulance_station"},"name":"Ambulance Station"},"emergency/defibrillator":{"fields":["access","opening_hours","indoor","phone"],"geometry":["point"],"terms":["AED"],"tags":{"emergency":"defibrillator"},"name":"Defibrillator"},"emergency/fire_hydrant":{"icon":"fire-station","fields":["fire_hydrant/type"],"geometry":["point","vertex"],"tags":{"emergency":"fire_hydrant"},"name":"Fire Hydrant"},"emergency/phone":{"icon":"emergency-telephone","fields":["operator"],"geometry":["point","vertex"],"tags":{"emergency":"phone"},"name":"Emergency Phone"},"entrance":{"icon":"entrance","geometry":["vertex"],"tags":{"entrance":"*"},"fields":["entrance","access_simple","address"],"name":"Entrance/Exit"},"footway/crossing":{"fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing"},"terms":[],"name":"Street Crossing"},"footway/crosswalk":{"icon":"highway-footway","fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","crossing":"zebra"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"footway/sidewalk":{"icon":"highway-footway","fields":["surface","lit","width","structure","access"],"geometry":["line"],"tags":{"highway":"footway","footway":"sidewalk"},"terms":[],"name":"Sidewalk"},"ford":{"geometry":["vertex"],"tags":{"ford":"yes"},"name":"Ford"},"golf/bunker":{"icon":"golf","geometry":["area"],"tags":{"golf":"bunker","natural":"sand"},"terms":["hazard","bunker"],"name":"Sand Trap"},"golf/fairway":{"icon":"golf","geometry":["area"],"tags":{"golf":"fairway","landuse":"grass"},"name":"Fairway"},"golf/green":{"icon":"golf","geometry":["area"],"tags":{"golf":"green","landuse":"grass","leisure":"pitch","sport":"golf"},"name":"Putting Green"},"golf/hole":{"icon":"golf","fields":["golf_hole","par","handicap"],"geometry":["line"],"tags":{"golf":"hole"},"name":"Golf Hole"},"golf/lateral_water_hazard_area":{"icon":"golf","geometry":["area"],"tags":{"golf":"lateral_water_hazard","natural":"water"},"name":"Lateral Water Hazard"},"golf/lateral_water_hazard_line":{"icon":"golf","geometry":["line"],"tags":{"golf":"lateral_water_hazard"},"name":"Lateral Water Hazard"},"golf/rough":{"icon":"golf","geometry":["area"],"tags":{"golf":"rough","landuse":"grass"},"name":"Rough"},"golf/tee":{"icon":"golf","geometry":["area"],"tags":{"golf":"tee","landuse":"grass"},"terms":["teeing ground"],"name":"Tee Box"},"golf/water_hazard_area":{"icon":"golf","geometry":["area"],"tags":{"golf":"water_hazard","natural":"water"},"name":"Water Hazard"},"golf/water_hazard_line":{"icon":"golf","geometry":["line"],"tags":{"golf":"water_hazard"},"name":"Water Hazard"},"healthcare/blood_donation":{"icon":"hospital","fields":["operator","address","blood_components","opening_hours","ref"],"geometry":["point","area"],"terms":["blood bank","blood donation","blood transfusion","apheresis","plasmapheresis","plateletpheresis","stem cell donation"],"tags":{"healthcare":"blood_donation"},"name":"Blood Donor Center"},"highway/bridleway":{"fields":["surface","width","structure","access"],"icon":"highway-bridleway","geometry":["line"],"tags":{"highway":"bridleway"},"terms":["bridleway","equestrian","horse"],"name":"Bridle Path"},"highway/bus_stop":{"icon":"bus","fields":["network","operator","bench","shelter"],"geometry":["point","vertex"],"tags":{"highway":"bus_stop"},"terms":[],"name":"Bus Stop"},"highway/corridor":{"icon":"highway-footway","fields":["width","level","access_simple"],"geometry":["line"],"tags":{"highway":"corridor"},"terms":["gallery","hall","hallway","indoor","passage","passageway"],"name":"Indoor Corridor"},"highway/crossing":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing"},"terms":[],"name":"Street Crossing"},"highway/crosswalk":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","crossing":"zebra"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"highway/cycleway":{"icon":"highway-cycleway","fields":["surface","lit","width","oneway","structure","access"],"geometry":["line"],"tags":{"highway":"cycleway"},"terms":["bike"],"name":"Cycle Path"},"highway/footway":{"icon":"highway-footway","fields":["surface","lit","width","structure","access"],"geometry":["line","area"],"terms":["hike","hiking","trackway","trail","walk"],"tags":{"highway":"footway"},"name":"Foot Path"},"highway/give_way":{"fields":["parallel_direction"],"geometry":["vertex"],"tags":{"highway":"give_way"},"terms":["give way","yield","sign"],"name":"Yield Sign"},"highway/living_street":{"icon":"highway-living-street","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","cycleway"],"geometry":["line"],"tags":{"highway":"living_street"},"name":"Living Street"},"highway/mini_roundabout":{"icon":"circle-stroked","geometry":["vertex"],"tags":{"highway":"mini_roundabout"},"fields":["clock_direction"],"name":"Mini-Roundabout"},"highway/motorway_junction":{"geometry":["vertex"],"tags":{"highway":"motorway_junction"},"fields":["ref"],"name":"Motorway Junction / Exit"},"highway/motorway_link":{"icon":"highway-motorway-link","fields":["oneway_yes","maxspeed","structure","access","lanes","surface","maxheight","ref"],"geometry":["line"],"tags":{"highway":"motorway_link"},"addTags":{"highway":"motorway_link","oneway":"yes"},"removeTags":{"highway":"motorway_link","oneway":"yes"},"terms":["ramp","on ramp","off ramp"],"name":"Motorway Link"},"highway/motorway":{"icon":"highway-motorway","fields":["oneway_yes","maxspeed","structure","access","lanes","surface","maxheight","ref"],"geometry":["line"],"tags":{"highway":"motorway"},"terms":[],"name":"Motorway"},"highway/path":{"icon":"highway-path","fields":["surface","width","structure","access","incline","sac_scale","trail_visibility","mtb/scale","mtb/scale/uphill","mtb/scale/imba","ref"],"geometry":["line"],"terms":["hike","hiking","trackway","trail","walk"],"tags":{"highway":"path"},"name":"Path"},"highway/pedestrian":{"icon":"highway-footway","fields":["surface","lit","width","oneway","structure","access"],"geometry":["line","area"],"tags":{"highway":"pedestrian"},"terms":[],"name":"Pedestrian Street"},"highway/primary_link":{"icon":"highway-primary-link","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref","cycleway"],"geometry":["line"],"tags":{"highway":"primary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Primary Link"},"highway/primary":{"icon":"highway-primary","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref","cycleway"],"geometry":["line"],"tags":{"highway":"primary"},"terms":[],"name":"Primary Road"},"highway/raceway":{"icon":"highway-unclassified","fields":["oneway","surface","sport_racing","structure"],"geometry":["line"],"tags":{"highway":"raceway"},"addTags":{"highway":"raceway","sport":"motor"},"terms":["auto*","race*","nascar"],"name":"Motor Raceway"},"highway/residential":{"icon":"highway-residential","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","cycleway"],"geometry":["line"],"tags":{"highway":"residential"},"terms":[],"name":"Residential Road"},"highway/rest_area":{"geometry":["point","vertex","area"],"tags":{"highway":"rest_area"},"terms":["rest stop"],"name":"Rest Area"},"highway/road":{"icon":"highway-road","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight"],"geometry":["line"],"tags":{"highway":"road"},"terms":[],"name":"Unknown Road"},"highway/secondary_link":{"icon":"highway-secondary-link","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref","cycleway"],"geometry":["line"],"tags":{"highway":"secondary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Secondary Link"},"highway/secondary":{"icon":"highway-secondary","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref","cycleway"],"geometry":["line"],"tags":{"highway":"secondary"},"terms":[],"name":"Secondary Road"},"highway/service":{"icon":"highway-service","fields":["service","oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service"},"terms":[],"name":"Service Road"},"highway/service/alley":{"icon":"highway-service","fields":["oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"alley"},"name":"Alley"},"highway/service/drive-through":{"icon":"highway-service","fields":["oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"drive-through"},"name":"Drive-Through"},"highway/service/driveway":{"icon":"highway-service","fields":["oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"driveway"},"name":"Driveway"},"highway/service/emergency_access":{"icon":"highway-service","fields":["oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"emergency_access"},"name":"Emergency Access"},"highway/service/parking_aisle":{"icon":"highway-service","fields":["oneway","maxspeed","structure","access","surface","maxheight"],"geometry":["line"],"tags":{"highway":"service","service":"parking_aisle"},"name":"Parking Aisle"},"highway/services":{"geometry":["point","vertex","area"],"tags":{"highway":"services"},"terms":["services","travel plaza","service station"],"name":"Service Area"},"highway/steps":{"fields":["surface","lit","width","incline_steps","handrail"],"icon":"highway-steps","geometry":["line"],"tags":{"highway":"steps"},"terms":["stairs","staircase"],"name":"Steps"},"highway/stop":{"fields":["stop","parallel_direction"],"geometry":["vertex"],"tags":{"highway":"stop"},"terms":["stop","halt","sign"],"name":"Stop Sign"},"highway/street_lamp":{"geometry":["point","vertex"],"tags":{"highway":"street_lamp"},"fields":["lamp_type","ref"],"terms":["streetlight","street light","lamp","light","gaslight"],"name":"Street Lamp"},"highway/tertiary_link":{"icon":"highway-tertiary-link","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref","cycleway"],"geometry":["line"],"tags":{"highway":"tertiary_link"},"terms":["ramp","on ramp","off ramp"],"name":"Tertiary Link"},"highway/tertiary":{"icon":"highway-tertiary","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref","cycleway"],"geometry":["line"],"tags":{"highway":"tertiary"},"terms":[],"name":"Tertiary Road"},"highway/track":{"icon":"highway-track","fields":["surface","width","structure","access","incline","tracktype","smoothness","mtb/scale","mtb/scale/uphill","mtb/scale/imba"],"geometry":["line"],"tags":{"highway":"track"},"terms":["woods road","forest road","logging road","fire road","farm road","agricultural road","ranch road","carriage road","primitive","unmaintained","rut","offroad","4wd","4x4","four wheel drive","atv","quad","jeep","double track","two track"],"name":"Unmaintained Track Road"},"highway/traffic_mirror":{"geometry":["point"],"tags":{"highway":"traffic_mirror"},"terms":["blind spot","convex","corner","curved","roadside","round","safety","sphere","visibility"],"name":"Traffic Mirror"},"highway/traffic_signals":{"geometry":["vertex"],"tags":{"highway":"traffic_signals"},"fields":["traffic_signals"],"terms":["light","stoplight","traffic light"],"name":"Traffic Signals"},"highway/trunk_link":{"icon":"highway-trunk-link","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref"],"geometry":["line"],"tags":{"highway":"trunk_link"},"terms":["ramp","on ramp","off ramp"],"name":"Trunk Link"},"highway/trunk":{"icon":"highway-trunk","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","ref"],"geometry":["line"],"tags":{"highway":"trunk"},"terms":[],"name":"Trunk Road"},"highway/turning_circle":{"icon":"circle-stroked","geometry":["vertex"],"tags":{"highway":"turning_circle"},"terms":["cul-de-sac"],"name":"Turning Circle"},"highway/turning_loop":{"icon":"circle","geometry":["vertex"],"tags":{"highway":"turning_loop"},"terms":["cul-de-sac"],"name":"Turning Loop (Island)"},"highway/unclassified":{"icon":"highway-unclassified","fields":["oneway","maxspeed","structure","access","lanes","surface","maxheight","cycleway"],"geometry":["line"],"tags":{"highway":"unclassified"},"terms":[],"name":"Minor/Unclassified Road"},"historic":{"fields":["historic"],"geometry":["point","vertex","area"],"tags":{"historic":"*"},"name":"Historic Site"},"historic/archaeological_site":{"geometry":["point","vertex","area"],"tags":{"historic":"archaeological_site"},"name":"Archaeological Site"},"historic/boundary_stone":{"geometry":["point","vertex"],"tags":{"historic":"boundary_stone"},"name":"Boundary Stone"},"historic/castle":{"geometry":["point","area"],"tags":{"historic":"castle"},"name":"Castle"},"historic/memorial":{"icon":"monument","geometry":["point","vertex","area"],"tags":{"historic":"memorial"},"name":"Memorial"},"historic/monument":{"icon":"monument","geometry":["point","vertex","area"],"tags":{"historic":"monument"},"name":"Monument"},"historic/ruins":{"geometry":["point","vertex","area"],"tags":{"historic":"ruins"},"name":"Ruins"},"historic/wayside_cross":{"icon":"religious-christian","geometry":["point","vertex","area"],"tags":{"historic":"wayside_cross"},"name":"Wayside Cross"},"historic/wayside_shrine":{"geometry":["point","vertex","area"],"tags":{"historic":"wayside_shrine"},"name":"Wayside Shrine"},"junction":{"geometry":["vertex","area"],"tags":{"junction":"yes"},"name":"Junction"},"landuse":{"fields":["landuse"],"geometry":["area"],"tags":{"landuse":"*"},"name":"Land Use"},"landuse/farm":{"icon":"farm","fields":["crop"],"geometry":["point","area"],"tags":{"landuse":"farm"},"terms":[],"name":"Farmland","searchable":false},"landuse/allotments":{"geometry":["area"],"tags":{"landuse":"allotments"},"terms":["allotment","garden"],"name":"Community Garden"},"landuse/basin":{"geometry":["area"],"tags":{"landuse":"basin"},"terms":[],"name":"Basin"},"landuse/cemetery":{"icon":"cemetery","fields":["religion","denomination"],"geometry":["area"],"tags":{"landuse":"cemetery"},"terms":[],"name":"Cemetery"},"landuse/churchyard":{"fields":["religion","denomination"],"geometry":["area"],"tags":{"landuse":"churchyard"},"terms":[],"name":"Churchyard"},"landuse/commercial":{"icon":"commercial","geometry":["area"],"tags":{"landuse":"commercial"},"terms":[],"name":"Commercial Area"},"landuse/construction":{"fields":["construction","operator"],"geometry":["area"],"tags":{"landuse":"construction"},"terms":[],"name":"Construction"},"landuse/farmland":{"icon":"farm","fields":["crop"],"geometry":["area"],"tags":{"landuse":"farmland"},"terms":[],"name":"Farmland"},"landuse/farmyard":{"icon":"farm","fields":["crop"],"geometry":["area"],"tags":{"landuse":"farmyard"},"terms":[],"name":"Farmyard"},"landuse/forest":{"icon":"park2","fields":["leaf_type","leaf_cycle"],"geometry":["area"],"tags":{"landuse":"forest"},"terms":["tree"],"name":"Forest"},"landuse/garages":{"geometry":["area"],"tags":{"landuse":"garages"},"terms":[],"name":"Garages"},"landuse/grass":{"geometry":["area"],"tags":{"landuse":"grass"},"terms":[],"name":"Grass"},"landuse/industrial":{"icon":"industrial","geometry":["area"],"tags":{"landuse":"industrial"},"terms":[],"name":"Industrial Area"},"landuse/landfill":{"geometry":["area"],"tags":{"landuse":"landfill"},"terms":["dump"],"name":"Landfill"},"landuse/meadow":{"geometry":["area"],"tags":{"landuse":"meadow"},"terms":[],"name":"Meadow"},"landuse/military":{"geometry":["area"],"tags":{"landuse":"military"},"terms":[],"name":"Military Area"},"landuse/orchard":{"icon":"park2","fields":["trees"],"geometry":["area"],"tags":{"landuse":"orchard"},"terms":[],"name":"Orchard"},"landuse/plant_nursery":{"icon":"garden","fields":["name"],"geometry":["point","area"],"tags":{"landuse":"plant_nursery"},"terms":["vivero"],"name":"Plant Nursery"},"landuse/quarry":{"geometry":["area"],"tags":{"landuse":"quarry"},"terms":[],"name":"Quarry"},"landuse/recreation_ground":{"geometry":["area"],"tags":{"landuse":"recreation_ground"},"terms":["playing fields"],"name":"Recreation Ground"},"landuse/residential":{"icon":"building","geometry":["area"],"tags":{"landuse":"residential"},"terms":[],"name":"Residential Area"},"landuse/retail":{"icon":"shop","geometry":["area"],"tags":{"landuse":"retail"},"name":"Retail Area"},"landuse/vineyard":{"geometry":["area"],"tags":{"landuse":"vineyard"},"terms":[],"name":"Vineyard"},"leisure":{"fields":["leisure"],"geometry":["point","vertex","area"],"tags":{"leisure":"*"},"name":"Leisure"},"leisure/adult_gaming_centre":{"fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":["gambling","slot machine"],"tags":{"leisure":"adult_gaming_centre"},"name":"Adult Gaming Center"},"leisure/bird_hide":{"fields":["building_area"],"geometry":["point","area"],"tags":{"leisure":"bird_hide"},"terms":["machan","ornithology"],"name":"Bird Hide"},"leisure/bowling_alley":{"fields":["operator","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"terms":[],"tags":{"leisure":"bowling_alley"},"name":"Bowling Alley"},"leisure/common":{"geometry":["point","area"],"terms":["open space"],"tags":{"leisure":"common"},"name":"Common"},"leisure/dance":{"fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ballroom","jive","swing","tango","waltz"],"tags":{"leisure":"dance"},"name":"Dance Hall"},"leisure/dog_park":{"icon":"dog-park","geometry":["point","area"],"terms":[],"tags":{"leisure":"dog_park"},"name":"Dog Park"},"leisure/firepit":{"geometry":["point","area"],"tags":{"leisure":"firepit"},"terms":["fireplace","campfire"],"name":"Firepit"},"leisure/fitness_centre":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_centre"},"terms":["health","gym","leisure","studio"],"name":"Gym / Fitness Center"},"leisure/fitness_centre/yoga":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["studio"],"tags":{"leisure":"fitness_centre","sport":"yoga"},"name":"Yoga Studio"},"leisure/fitness_station":{"icon":"pitch","fields":["sport","address","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station"},"terms":["fitness","gym"],"name":"Outdoor Fitness Station"},"leisure/garden":{"icon":"garden","fields":["access_simple"],"geometry":["point","vertex","area"],"tags":{"leisure":"garden"},"name":"Garden"},"leisure/golf_course":{"icon":"golf","fields":["operator","address","opening_hours"],"geometry":["point","area"],"terms":["links"],"tags":{"leisure":"golf_course"},"name":"Golf Course"},"leisure/ice_rink":{"icon":"pitch","fields":["seasonal","sport_ice","operator","address","building","opening_hours"],"geometry":["point","area"],"terms":["hockey","skating","curling"],"tags":{"leisure":"ice_rink"},"name":"Ice Rink"},"leisure/marina":{"icon":"harbor","fields":["operator","address","capacity","fee","sanitary_dump_station","power_supply","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"terms":["boat"],"tags":{"leisure":"marina"},"name":"Marina"},"leisure/miniature_golf":{"icon":"golf","fields":["operator","address","opening_hours"],"geometry":["point","area"],"terms":["crazy golf","mini golf","putt-putt"],"tags":{"leisure":"miniature_golf"},"name":"Miniature Golf"},"leisure/nature_reserve":{"icon":"park","geometry":["point","area"],"tags":{"leisure":"nature_reserve"},"terms":["protected","wildlife"],"name":"Nature Reserve"},"leisure/park":{"icon":"park","geometry":["point","area"],"terms":["esplanade","estate","forest","garden","grass","green","grounds","lawn","lot","meadow","parkland","place","playground","plaza","pleasure garden","recreation area","square","tract","village green","woodland"],"tags":{"leisure":"park"},"name":"Park"},"leisure/picnic_table":{"geometry":["point"],"tags":{"leisure":"picnic_table"},"terms":["bench"],"name":"Picnic Table"},"leisure/pitch":{"icon":"pitch","fields":["sport","surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch"},"terms":["field"],"name":"Sport Pitch"},"leisure/pitch/american_football":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"american_football"},"terms":[],"name":"American Football Field"},"leisure/pitch/baseball":{"icon":"baseball","fields":["lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"baseball"},"terms":[],"name":"Baseball Diamond"},"leisure/pitch/basketball":{"icon":"basketball","fields":["surface","hoops","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"basketball"},"terms":[],"name":"Basketball Court"},"leisure/pitch/bowls":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"bowls"},"terms":[],"name":"Bowling Green"},"leisure/pitch/rugby_league":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"rugby_league"},"terms":[],"name":"Rugby League Field"},"leisure/pitch/rugby_union":{"icon":"america-football","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"rugby_union"},"terms":[],"name":"Rugby Union Field"},"leisure/pitch/skateboard":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"skateboard"},"terms":[],"name":"Skate Park"},"leisure/pitch/soccer":{"icon":"soccer","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"soccer"},"terms":[],"name":"Soccer Field"},"leisure/pitch/tennis":{"icon":"tennis","fields":["surface","lit","access_simple"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"tennis"},"terms":[],"name":"Tennis Court"},"leisure/pitch/volleyball":{"icon":"pitch","fields":["surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"volleyball"},"terms":[],"name":"Volleyball Court"},"leisure/playground":{"icon":"playground","geometry":["point","area"],"terms":["jungle gym","play area"],"tags":{"leisure":"playground"},"name":"Playground"},"leisure/resort":{"fields":["operator","address","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"resort"},"name":"Resort"},"leisure/running_track":{"icon":"pitch","fields":["surface","sport_racing","lit","width","lanes"],"geometry":["point","line"],"tags":{"leisure":"track","sport":"running"},"name":"Running Track"},"leisure/slipway":{"geometry":["point","line"],"terms":["boat launch","boat ramp"],"tags":{"leisure":"slipway"},"name":"Slipway"},"leisure/sports_centre":{"icon":"pitch","fields":["sport","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"sports_centre"},"terms":[],"name":"Sports Center / Complex"},"leisure/sports_centre/swimming":{"icon":"swimming","fields":["access_simple","operator","address","building"],"geometry":["point","area"],"terms":["dive","water"],"tags":{"leisure":"sports_centre","sport":"swimming"},"name":"Swimming Pool Facility"},"leisure/stadium":{"icon":"pitch","fields":["sport","address"],"geometry":["point","area"],"tags":{"leisure":"stadium"},"name":"Stadium"},"leisure/swimming_pool":{"icon":"swimming","fields":["access_simple","operator","address"],"geometry":["point","area"],"terms":["dive","water"],"tags":{"leisure":"swimming_pool"},"name":"Swimming Pool"},"leisure/track":{"icon":"highway-road","fields":["surface","sport_racing","lit","width","lanes"],"geometry":["point","line"],"tags":{"leisure":"track"},"name":"Racetrack (non-Motorsport)"},"leisure/water_park":{"icon":"swimming","fields":["operator","address"],"geometry":["point","area"],"terms":["swim","pool","dive"],"tags":{"leisure":"water_park"},"name":"Water Park"},"line":{"name":"Line","tags":{},"geometry":["line"],"matchScore":0.1},"man_made":{"fields":["man_made"],"geometry":["point","vertex","line","area"],"tags":{"man_made":"*"},"name":"Man Made"},"man_made/embankment":{"geometry":["line"],"tags":{"man_made":"embankment"},"name":"Embankment","searchable":false},"man_made/adit":{"geometry":["point","area"],"fields":["operator"],"terms":["entrance","underground","mine","cave"],"tags":{"man_made":"adit"},"name":"Adit"},"man_made/breakwater":{"geometry":["line","area"],"tags":{"man_made":"breakwater"},"name":"Breakwater"},"man_made/bridge":{"geometry":["area"],"tags":{"man_made":"bridge"},"name":"Bridge"},"man_made/chimney":{"geometry":["point","area"],"tags":{"man_made":"chimney"},"name":"Chimney"},"man_made/cutline":{"geometry":["line"],"tags":{"man_made":"cutline"},"name":"Cut line"},"man_made/flagpole":{"geometry":["point"],"tags":{"man_made":"flagpole"},"name":"Flagpole","icon":"embassy"},"man_made/gasometer":{"geometry":["point","area"],"terms":["gas holder"],"tags":{"man_made":"gasometer"},"name":"Gasometer"},"man_made/groyne":{"geometry":["line","area"],"tags":{"man_made":"groyne"},"name":"Groyne"},"man_made/lighthouse":{"icon":"lighthouse","fields":["building_area"],"geometry":["point","area"],"tags":{"man_made":"lighthouse"},"name":"Lighthouse"},"man_made/mast":{"fields":["tower/type","tower/construction","height"],"geometry":["point"],"terms":["broadcast tower","cell phone tower","cell tower","guyed tower","mobile phone tower","radio tower","television tower","transmission mast","transmission tower","tv tower"],"tags":{"man_made":"mast"},"name":"Radio Mast"},"man_made/observation":{"geometry":["point","area"],"terms":["lookout tower","fire tower"],"tags":{"man_made":"tower","tower:type":"observation"},"name":"Observation Tower"},"man_made/petroleum_well":{"geometry":["point"],"terms":["drilling rig","oil derrick","oil drill","oil horse","oil rig","oil pump","petroleum well","pumpjack"],"tags":{"man_made":"petroleum_well"},"name":"Oil Well"},"man_made/pier":{"geometry":["line","area"],"terms":["dock"],"tags":{"man_made":"pier"},"name":"Pier"},"man_made/pipeline":{"icon":"pipeline-line","fields":["location","operator"],"geometry":["line"],"tags":{"man_made":"pipeline"},"name":"Pipeline"},"man_made/pumping_station":{"geometry":["point","area"],"tags":{"man_made":"pumping_station"},"name":"Pumping Station"},"man_made/silo":{"fields":["building_area","crop"],"geometry":["point","area"],"terms":["grain","corn","wheat"],"tags":{"man_made":"silo"},"name":"Silo"},"man_made/storage_tank":{"fields":["building_area","content"],"geometry":["point","area"],"terms":["water","oil","gas","petrol"],"tags":{"man_made":"storage_tank"},"name":"Storage Tank"},"man_made/surveillance_camera":{"icon":"camera","geometry":["point"],"fields":["surveillance","surveillance/type","camera/type","camera/mount","camera/direction","surveillance/zone","contact/webcam"],"terms":["anpr","alpr","camera","car plate recognition","cctv","guard","license plate recognition","monitoring","number plate recognition","security","video","webcam"],"tags":{"man_made":"surveillance","surveillance:type":"camera"},"name":"Surveillance Camera"},"man_made/surveillance":{"icon":"camera","geometry":["point"],"fields":["surveillance","surveillance/type","surveillance/zone"],"terms":["anpr","alpr","camera","car plate recognition","cctv","guard","license plate recognition","monitoring","number plate recognition","security","video","webcam"],"tags":{"man_made":"surveillance"},"name":"Surveillance"},"man_made/survey_point":{"icon":"monument","fields":["ref"],"geometry":["point","vertex"],"tags":{"man_made":"survey_point"},"name":"Survey Point"},"man_made/tower":{"fields":["tower/type","tower/construction","height"],"geometry":["point","area"],"tags":{"man_made":"tower"},"name":"Tower"},"man_made/wastewater_plant":{"icon":"water","fields":["operator","address"],"geometry":["point","area"],"terms":["sewage*","water treatment plant","reclamation plant"],"tags":{"man_made":"wastewater_plant"},"name":"Wastewater Plant"},"man_made/water_tower":{"icon":"water","fields":["operator"],"geometry":["point","area"],"tags":{"man_made":"water_tower"},"name":"Water Tower"},"man_made/water_well":{"fields":["operator"],"geometry":["point","area"],"tags":{"man_made":"water_well"},"name":"Water Well"},"man_made/water_works":{"icon":"water","fields":["operator","address"],"geometry":["point","area"],"tags":{"man_made":"water_works"},"name":"Water Works"},"man_made/works":{"geometry":["point","area"],"terms":["car assembly plant","aluminium processing plant","brewery","furniture manufacture factory","oil refinery","plastic recycling"],"tags":{"man_made":"works"},"name":"Works"},"military/airfield":{"icon":"airfield","geometry":["point","vertex","area"],"terms":[],"tags":{"military":"airfield"},"name":"Airfield"},"military/barracks":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"barracks"},"name":"Barracks"},"military/bunker":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"bunker"},"name":"Bunker"},"military/checkpoint":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"checkpoint"},"name":"Checkpoint"},"military/danger_area":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"danger_area"},"name":"Danger Area"},"military/naval_base":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"naval_base"},"name":"Naval Base"},"military/obstacle_course":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"obstacle_course"},"name":"Obstacle Course"},"military/range":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"range"},"name":"Military Range"},"military/training_area":{"geometry":["point","vertex","area"],"terms":[],"tags":{"military":"training_area"},"name":"Training area"},"natural":{"fields":["natural"],"geometry":["point","vertex","area"],"tags":{"natural":"*"},"name":"Natural"},"natural/bay":{"geometry":["point","area"],"terms":[],"tags":{"natural":"bay"},"name":"Bay"},"natural/beach":{"fields":["surface"],"geometry":["point","area"],"terms":[],"tags":{"natural":"beach"},"name":"Beach"},"natural/cave_entrance":{"geometry":["point","area"],"fields":["fee","access_simple"],"terms":["cavern","hollow","grotto","shelter","cavity"],"tags":{"natural":"cave_entrance"},"name":"Cave Entrance"},"natural/cliff":{"geometry":["point","vertex","line","area"],"terms":[],"tags":{"natural":"cliff"},"name":"Cliff"},"natural/coastline":{"geometry":["line"],"terms":["shore"],"tags":{"natural":"coastline"},"name":"Coastline"},"natural/fell":{"geometry":["area"],"terms":[],"tags":{"natural":"fell"},"name":"Fell"},"natural/glacier":{"geometry":["area"],"terms":[],"tags":{"natural":"glacier"},"name":"Glacier"},"natural/grassland":{"geometry":["point","area"],"terms":[],"tags":{"natural":"grassland"},"name":"Grassland"},"natural/heath":{"geometry":["area"],"terms":[],"tags":{"natural":"heath"},"name":"Heath"},"natural/peak":{"icon":"triangle","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"peak"},"terms":["acme","aiguille","alp","climax","crest","crown","hill","mount","mountain","pinnacle","summit","tip","top"],"name":"Peak"},"natural/saddle":{"icon":"triangle-stroked","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"saddle"},"terms":["pass","mountain pass","top"],"name":"Saddle"},"natural/scree":{"geometry":["area"],"tags":{"natural":"scree"},"terms":["loose rocks"],"name":"Scree"},"natural/scrub":{"geometry":["area"],"tags":{"natural":"scrub"},"terms":["bush","shrubs"],"name":"Scrub"},"natural/spring":{"geometry":["point","vertex"],"terms":[],"tags":{"natural":"spring"},"name":"Spring"},"natural/tree_row":{"fields":["leaf_type","leaf_cycle","denotation"],"icon":"park","geometry":["line"],"terms":[],"tags":{"natural":"tree_row"},"name":"Tree row"},"natural/tree":{"fields":["leaf_type_singular","leaf_cycle_singular","denotation"],"icon":"park","geometry":["point","vertex"],"terms":[],"tags":{"natural":"tree"},"name":"Tree"},"natural/volcano":{"icon":"triangle","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"volcano"},"terms":["mountain","crater"],"name":"Volcano"},"natural/water":{"fields":["water"],"geometry":["area"],"tags":{"natural":"water"},"icon":"water","name":"Water"},"natural/water/lake":{"geometry":["area"],"tags":{"natural":"water","water":"lake"},"terms":["lakelet","loch","mere"],"icon":"water","name":"Lake"},"natural/water/pond":{"geometry":["area"],"tags":{"natural":"water","water":"pond"},"terms":["lakelet","millpond","tarn","pool","mere"],"icon":"water","name":"Pond"},"natural/water/reservoir":{"geometry":["area"],"tags":{"natural":"water","water":"reservoir"},"icon":"water","name":"Reservoir"},"natural/wetland":{"icon":"wetland","fields":["wetland"],"geometry":["point","area"],"tags":{"natural":"wetland"},"terms":[],"name":"Wetland"},"natural/wood":{"icon":"park2","fields":["leaf_type","leaf_cycle"],"geometry":["point","area"],"tags":{"natural":"wood"},"terms":["tree"],"name":"Wood"},"office":{"icon":"commercial","fields":["office","address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"*"},"terms":[],"name":"Office"},"office/travel_agent":{"icon":"suitcase","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"travel_agent"},"terms":[],"name":"Travel Agency","searchable":false},"office/accountant":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"accountant"},"terms":[],"name":"Accountant"},"office/administrative":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"administrative"},"terms":[],"name":"Administrative Office"},"office/architect":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"architect"},"terms":[],"name":"Architect"},"office/company":{"icon":"commercial","fields":["address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"company"},"terms":[],"name":"Company Office"},"office/educational_institution":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"educational_institution"},"terms":[],"name":"Educational Institution"},"office/employment_agency":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"employment_agency"},"terms":["job"],"name":"Employment Agency"},"office/estate_agent":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"estate_agent"},"terms":[],"name":"Real Estate Office"},"office/financial":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"financial"},"terms":[],"name":"Financial Office"},"office/government":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"government"},"terms":[],"name":"Government Office"},"office/government/register_office":{"icon":"town-hall","fields":["address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":["clerk","marriage","death","birth","certificate"],"tags":{"office":"government","government":"register_office"},"name":"Register Office"},"office/insurance":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"insurance"},"terms":[],"name":"Insurance Office"},"office/it":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"it"},"terms":[],"name":"IT Office"},"office/lawyer":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"lawyer"},"terms":[],"name":"Law Office"},"office/newspaper":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"newspaper"},"terms":[],"name":"Newspaper"},"office/ngo":{"icon":"commercial","fields":["address","building_area","opening_hours","smoking"],"geometry":["point","vertex","area"],"tags":{"office":"ngo"},"terms":[],"name":"NGO Office"},"office/physician":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"physician"},"terms":[],"name":"Physician"},"office/political_party":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"political_party"},"terms":[],"name":"Political Party"},"office/research":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"research"},"terms":[],"name":"Research Office"},"office/telecommunication":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"telecommunication"},"terms":[],"name":"Telecom Office"},"office/therapist":{"icon":"commercial","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"therapist"},"terms":[],"name":"Therapist"},"piste":{"icon":"skiing","fields":["piste/type","piste/difficulty","piste/grooming","oneway","lit"],"geometry":["point","line","area"],"terms":["ski","sled","sleigh","snowboard","nordic","downhill","snowmobile"],"tags":{"piste:type":"*"},"name":"Piste/Ski Trail"},"place/city":{"icon":"city","fields":["population"],"geometry":["point","area"],"tags":{"place":"city"},"name":"City"},"place/farm":{"icon":"farm","geometry":["point","area"],"tags":{"place":"farm"},"name":"Farm"},"place/hamlet":{"icon":"triangle-stroked","fields":["population"],"geometry":["point","area"],"tags":{"place":"hamlet"},"name":"Hamlet"},"place/island":{"geometry":["point","area"],"terms":["archipelago","atoll","bar","cay","isle","islet","key","reef"],"tags":{"place":"island"},"name":"Island"},"place/isolated_dwelling":{"geometry":["point","area"],"tags":{"place":"isolated_dwelling"},"name":"Isolated Dwelling"},"place/locality":{"icon":"marker","geometry":["point","area"],"tags":{"place":"locality"},"name":"Locality"},"place/neighbourhood":{"icon":"triangle-stroked","fields":["population"],"geometry":["point","area"],"tags":{"place":"neighbourhood"},"terms":["neighbourhood"],"name":"Neighborhood"},"place/suburb":{"icon":"triangle-stroked","fields":["population"],"geometry":["point","area"],"tags":{"place":"suburb"},"terms":["Boro","Quarter"],"name":"Borough"},"place/town":{"icon":"town","fields":["population"],"geometry":["point","area"],"tags":{"place":"town"},"name":"Town"},"place/village":{"icon":"village","fields":["population"],"geometry":["point","area"],"tags":{"place":"village"},"name":"Village"},"point":{"name":"Point","tags":{},"geometry":["point"],"matchScore":0.1},"power/sub_station":{"fields":["substation","operator","building"],"geometry":["point","area"],"tags":{"power":"sub_station"},"name":"Substation","searchable":false},"power/generator":{"fields":["operator","generator/source","generator/method","generator/type"],"geometry":["point","vertex","area"],"tags":{"power":"generator"},"name":"Power Generator"},"power/line":{"geometry":["line"],"tags":{"power":"line"},"name":"Power Line","icon":"power-line"},"power/minor_line":{"geometry":["line"],"tags":{"power":"minor_line"},"name":"Minor Power Line","icon":"power-line"},"power/pole":{"geometry":["vertex"],"tags":{"power":"pole"},"name":"Power Pole"},"power/substation":{"fields":["substation","operator","building"],"geometry":["point","area"],"tags":{"power":"substation"},"name":"Substation"},"power/tower":{"geometry":["vertex"],"tags":{"power":"tower"},"name":"High-Voltage Tower"},"power/transformer":{"geometry":["point","vertex","area"],"tags":{"power":"transformer"},"name":"Transformer"},"public_transport/platform":{"fields":["ref","network","operator","shelter"],"geometry":["point","vertex","line","area"],"tags":{"public_transport":"platform"},"name":"Platform"},"public_transport/stop_position":{"icon":"bus","fields":["ref","network","operator"],"geometry":["vertex"],"tags":{"public_transport":"stop_position"},"name":"Stop Position"},"railway/abandoned":{"icon":"railway-abandoned","geometry":["line"],"tags":{"railway":"abandoned"},"fields":["structure","service_rail"],"terms":[],"name":"Abandoned Railway"},"railway/crossing":{"icon":"cross","geometry":["vertex"],"tags":{"railway":"crossing"},"terms":["crossing","pedestrian crossing","railroad crossing","level crossing","grade crossing","path through railroad","train crossing"],"name":"Railway Crossing (Path)"},"railway/disused":{"icon":"railway-disused","geometry":["line"],"tags":{"railway":"disused"},"fields":["structure","service_rail"],"terms":[],"name":"Disused Railway"},"railway/funicular":{"geometry":["line"],"terms":["venicular","cliff railway","cable car","cable railway","funicular railway"],"fields":["structure","gauge","service_rail"],"tags":{"railway":"funicular"},"icon":"railway-rail","name":"Funicular"},"railway/halt":{"icon":"rail","geometry":["point","vertex"],"tags":{"railway":"halt"},"name":"Railway Halt","terms":["break","interrupt","rest","wait","interruption"]},"railway/level_crossing":{"icon":"cross","geometry":["vertex"],"tags":{"railway":"level_crossing"},"terms":["crossing","railroad crossing","level crossing","grade crossing","road through railroad","train crossing"],"name":"Railway Crossing (Road)"},"railway/monorail":{"icon":"railway-monorail","geometry":["line"],"tags":{"railway":"monorail"},"fields":["structure","electrified","service_rail"],"terms":[],"name":"Monorail"},"railway/narrow_gauge":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"narrow_gauge"},"fields":["structure","gauge","electrified","service_rail"],"terms":["narrow gauge railway","narrow gauge railroad"],"name":"Narrow Gauge Rail"},"railway/platform":{"geometry":["point","vertex","line","area"],"tags":{"railway":"platform"},"name":"Railway Platform"},"railway/rail":{"icon":"railway-rail","geometry":["line"],"tags":{"railway":"rail"},"fields":["structure","gauge","electrified","maxspeed","service_rail"],"terms":[],"name":"Rail"},"railway/station":{"icon":"rail","fields":["network","operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"tags":{"railway":"station"},"terms":["train station","station"],"name":"Railway Station"},"railway/subway_entrance":{"icon":"rail-metro","geometry":["point"],"tags":{"railway":"subway_entrance"},"terms":[],"name":"Subway Entrance"},"railway/subway":{"icon":"railway-subway","geometry":["line"],"tags":{"railway":"subway"},"fields":["structure","gauge","electrified","service_rail"],"terms":[],"name":"Subway"},"railway/tram":{"icon":"railway-light-rail","geometry":["line"],"tags":{"railway":"tram"},"fields":["structure","gauge","electrified","service_rail"],"terms":["streetcar"],"name":"Tram"},"relation":{"name":"Relation","icon":"relation","tags":{},"geometry":["relation"],"fields":["relation"]},"route/ferry":{"icon":"ferry-line","geometry":["line"],"tags":{"route":"ferry"},"name":"Ferry Route"},"shop":{"icon":"shop","fields":["shop","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"*"},"terms":[],"name":"Shop"},"shop/fishmonger":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"fishmonger"},"name":"Fishmonger","searchable":false},"shop/vacant":{"icon":"shop","fields":["address","building_area"],"geometry":["point","area"],"tags":{"shop":"vacant"},"name":"Vacant Shop","searchable":false},"shop/alcohol":{"icon":"alcohol-shop","fields":["operator","address","building_area","opening_hours","drive_through"],"geometry":["point","area"],"terms":["alcohol","beer","booze","wine"],"tags":{"shop":"alcohol"},"name":"Liquor Store"},"shop/anime":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"anime"},"terms":["manga","japan","cosplay","figurine","dakimakura"],"name":"Anime Shop"},"shop/antiques":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"antiques"},"name":"Antiques Shop"},"shop/art":{"icon":"shop","fields":["artwork_type","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["art*","exhibit*","gallery"],"tags":{"shop":"art"},"name":"Art Store"},"shop/baby_goods":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"baby_goods"},"name":"Baby Goods Store"},"shop/bag":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["handbag","purse"],"tags":{"shop":"bag"},"name":"Bag/Luggage Store"},"shop/bakery":{"icon":"bakery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bakery"},"name":"Bakery"},"shop/bathroom_furnishing":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bathroom_furnishing"},"name":"Bathroom Furnishing Store"},"shop/beauty":{"icon":"shop","fields":["operator","address","building_area","opening_hours","beauty"],"geometry":["point","area"],"terms":["spa","salon","tanning"],"tags":{"shop":"beauty"},"name":"Beauty Shop"},"shop/beauty/nails":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["manicure","pedicure"],"tags":{"shop":"beauty","beauty":"nails"},"name":"Nail Salon"},"shop/beauty/tanning":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"beauty","beauty":"tanning"},"name":"Tanning Salon"},"shop/bed":{"icon":"lodging","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"bed"},"name":"Bedding/Mattress Store"},"shop/beverages":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"beverages"},"name":"Beverage Store"},"shop/bicycle":{"icon":"bicycle","fields":["operator","address","building_area","opening_hours","service/bicycle"],"geometry":["point","area"],"terms":["bike","repair"],"tags":{"shop":"bicycle"},"name":"Bicycle Shop"},"shop/bookmaker":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["betting"],"tags":{"shop":"bookmaker"},"name":"Bookmaker"},"shop/books":{"icon":"shop","fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"shop":"books"},"name":"Book Store"},"shop/boutique":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"boutique"},"name":"Boutique"},"shop/butcher":{"icon":"slaughterhouse","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["meat"],"tags":{"shop":"butcher"},"name":"Butcher"},"shop/candles":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"candles"},"name":"Candle Shop"},"shop/car_parts":{"icon":"car","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["auto"],"tags":{"shop":"car_parts"},"name":"Car Parts Store"},"shop/car_repair":{"icon":"car","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["auto","garage","service"],"tags":{"shop":"car_repair"},"name":"Car Repair Shop"},"shop/car":{"icon":"car","fields":["operator","address","building_area","opening_hours","second_hand"],"geometry":["point","area"],"terms":["auto"],"tags":{"shop":"car"},"name":"Car Dealership"},"shop/carpet":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["rug"],"tags":{"shop":"carpet"},"name":"Carpet Store"},"shop/charity":{"icon":"shop","fields":["operator","address","building_area","opening_hours","second_hand"],"geometry":["point","area"],"terms":["thrift","op shop","nonprofit"],"tags":{"shop":"charity"},"name":"Charity Store"},"shop/cheese":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"cheese"},"name":"Cheese Store"},"shop/chemist":{"icon":"grocery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"chemist"},"terms":["med*","drug*","gift"],"name":"Drugstore"},"shop/chocolate":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"chocolate"},"name":"Chocolate Store"},"shop/clothes":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"clothes"},"name":"Clothing Store"},"shop/coffee":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"coffee"},"name":"Coffee Store"},"shop/computer":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"computer"},"name":"Computer Store"},"shop/confectionery":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"confectionery"},"name":"Candy Store"},"shop/convenience":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"convenience"},"name":"Convenience Store"},"shop/copyshop":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"copyshop"},"name":"Copy Store"},"shop/cosmetics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"cosmetics"},"name":"Cosmetics Store"},"shop/craft":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"craft"},"terms":["art*","paint*","frame"],"name":"Arts and Crafts Store"},"shop/curtain":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["drape*","window"],"tags":{"shop":"curtain"},"name":"Curtain Store"},"shop/dairy":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["milk","egg","cheese"],"tags":{"shop":"dairy"},"name":"Dairy Store"},"shop/deli":{"icon":"restaurant","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["lunch","meat","sandwich"],"tags":{"shop":"deli"},"name":"Deli"},"shop/department_store":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"department_store"},"name":"Department Store"},"shop/doityourself":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"doityourself"},"name":"DIY Store"},"shop/dry_cleaning":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"dry_cleaning"},"name":"Dry Cleaner"},"shop/e-cigarette":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"e-cigarette"},"terms":["electronic","vapor"],"name":"E-Cigarette Shop"},"shop/electronics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["appliance","audio","computer","tv"],"tags":{"shop":"electronics"},"name":"Electronics Store"},"shop/erotic":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sex","porn"],"tags":{"shop":"erotic"},"name":"Erotic Store"},"shop/fabric":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["sew"],"tags":{"shop":"fabric"},"name":"Fabric Store"},"shop/farm":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["farm shop","farm stand"],"tags":{"shop":"farm"},"name":"Produce Stand"},"shop/fashion":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"fashion"},"name":"Fashion Store"},"shop/florist":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["flower"],"tags":{"shop":"florist"},"name":"Florist"},"shop/frame":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"frame"},"terms":["art*","paint*","photo*","frame"],"name":"Framing Shop"},"shop/funeral_directors":{"icon":"cemetery","fields":["operator","address","building_area","religion","denomination"],"geometry":["point","area"],"terms":["undertaker","memorial home"],"tags":{"shop":"funeral_directors"},"name":"Funeral Home"},"shop/furnace":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["oven","stove"],"tags":{"shop":"furnace"},"name":"Furnace Store"},"shop/furniture":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["chair","sofa","table"],"tags":{"shop":"furniture"},"name":"Furniture Store"},"shop/garden_centre":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["landscape","mulch","shrub","tree"],"tags":{"shop":"garden_centre"},"name":"Garden Center"},"shop/gift":{"icon":"gift","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["souvenir"],"tags":{"shop":"gift"},"name":"Gift Shop"},"shop/greengrocer":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fruit","vegetable"],"tags":{"shop":"greengrocer"},"name":"Greengrocer"},"shop/hairdresser":{"icon":"hairdresser","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["barber"],"tags":{"shop":"hairdresser"},"name":"Hairdresser"},"shop/hardware":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"hardware"},"name":"Hardware Store"},"shop/hearing_aids":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"hearing_aids"},"name":"Hearing Aids Store"},"shop/herbalist":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"herbalist"},"name":"Herbalist"},"shop/hifi":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["stereo","video"],"tags":{"shop":"hifi"},"name":"Hifi Store"},"shop/houseware":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["home","household"],"tags":{"shop":"houseware"},"name":"Houseware Store"},"shop/interior_decoration":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"interior_decoration"},"name":"Interior Decoration Store"},"shop/jewelry":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["diamond","gem","ring"],"tags":{"shop":"jewelry"},"name":"Jeweler"},"shop/kiosk":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"kiosk"},"name":"News Kiosk"},"shop/kitchen":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"kitchen"},"name":"Kitchen Design Store"},"shop/laundry":{"icon":"laundry","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"laundry"},"name":"Laundry"},"shop/leather":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"leather"},"name":"Leather Store"},"shop/locksmith":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["key","lockpick"],"tags":{"shop":"locksmith"},"name":"Locksmith"},"shop/lottery":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"lottery"},"name":"Lottery Shop"},"shop/mall":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["shopping"],"tags":{"shop":"mall"},"name":"Mall"},"shop/massage":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"massage"},"name":"Massage Shop"},"shop/medical_supply":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"medical_supply"},"name":"Medical Supply Store"},"shop/mobile_phone":{"icon":"mobilephone","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"mobile_phone"},"name":"Mobile Phone Store"},"shop/money_lender":{"icon":"bank","fields":["operator","address","building_area","opening_hours","currency_multi"],"geometry":["point","area"],"tags":{"shop":"money_lender"},"name":"Money Lender"},"shop/motorcycle":{"icon":"scooter","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["bike"],"tags":{"shop":"motorcycle"},"name":"Motorcycle Dealership"},"shop/music":{"icon":"music","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["CD","vinyl"],"tags":{"shop":"music"},"name":"Music Store"},"shop/musical_instrument":{"icon":"music","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["guitar"],"tags":{"shop":"musical_instrument"},"name":"Musical Instrument Store"},"shop/newsagent":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"newsagent"},"name":"Newspaper/Magazine Shop"},"shop/nutrition_supplements":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"nutrition_supplements"},"name":"Nutrition Supplements Store"},"shop/optician":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["eye","glasses"],"tags":{"shop":"optician"},"name":"Optician"},"shop/organic":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"supermarket","organic":"only"},"name":"Organic Goods Store"},"shop/outdoor":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["camping","climbing","hiking"],"tags":{"shop":"outdoor"},"name":"Outdoors Store"},"shop/paint":{"icon":"water","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"paint"},"name":"Paint Store"},"shop/pastry":{"icon":"bakery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pastry"},"terms":["patisserie","cake shop","cakery"],"name":"Pastry Shop"},"shop/pawnbroker":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pawnbroker"},"name":"Pawn Shop"},"shop/pet":{"icon":"dog-park","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["cat","dog","fish"],"tags":{"shop":"pet"},"name":"Pet Store"},"shop/photo":{"icon":"camera","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["camera","film"],"tags":{"shop":"photo"},"name":"Photography Store"},"shop/pyrotechnics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"pyrotechnics"},"name":"Fireworks Store"},"shop/radiotechnics":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"radiotechnics"},"name":"Radio/Electronic Component Store"},"shop/religion":{"icon":"shop","fields":["operator","address","building_area","opening_hours","religion","denomination"],"geometry":["point","area"],"tags":{"shop":"religion"},"name":"Religious Store"},"shop/scuba_diving":{"icon":"swimming","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"scuba_diving"},"name":"Scuba Diving Shop"},"shop/seafood":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fishmonger"],"tags":{"shop":"seafood"},"name":"Seafood Shop"},"shop/second_hand":{"icon":"shop","fields":["operator","address","building_area","opening_hours","second_hand"],"geometry":["point","area"],"terms":["secondhand","second hand","resale","thrift","used"],"tags":{"shop":"second_hand"},"name":"Consignment/Thrift Store"},"shop/shoes":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"shoes"},"name":"Shoe Store"},"shop/sports":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"sports"},"name":"Sporting Goods Store"},"shop/stationery":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["card","paper"],"tags":{"shop":"stationery"},"name":"Stationery Store"},"shop/storage_rental":{"icon":"shop","fields":["operator","address","building","opening_hours"],"geometry":["point","area"],"tags":{"shop":"storage_rental"},"name":"Storage Rental"},"shop/supermarket":{"icon":"grocery","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["grocery","store","shop"],"tags":{"shop":"supermarket"},"name":"Supermarket"},"shop/tailor":{"icon":"clothing-store","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["clothes","suit"],"tags":{"shop":"tailor"},"name":"Tailor"},"shop/tattoo":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tattoo"},"name":"Tattoo Parlor"},"shop/tea":{"icon":"cafe","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tea"},"name":"Tea Store"},"shop/ticket":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"ticket"},"name":"Ticket Seller"},"shop/tobacco":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tobacco"},"name":"Tobacco Shop"},"shop/toys":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"toys"},"name":"Toy Store"},"shop/travel_agency":{"icon":"suitcase","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"travel_agency"},"name":"Travel Agency"},"shop/tyres":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tyres"},"name":"Tire Store"},"shop/vacuum_cleaner":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"vacuum_cleaner"},"name":"Vacuum Cleaner Store"},"shop/variety_store":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"variety_store"},"name":"Variety Store"},"shop/video_games":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"video_games"},"name":"Video Game Store"},"shop/video":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["DVD"],"tags":{"shop":"video"},"name":"Video Store"},"shop/water_sports":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"water_sports"},"name":"Watersport/Swim Shop"},"shop/weapons":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["ammo","gun","knife","knives"],"tags":{"shop":"weapons"},"name":"Weapon Shop"},"shop/window_blind":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"window_blind"},"name":"Window Blind Store"},"shop/wine":{"icon":"alcohol-shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"wine"},"name":"Wine Shop"},"tourism":{"fields":["tourism"],"geometry":["point","vertex","area"],"tags":{"tourism":"*"},"name":"Tourism"},"tourism/alpine_hut":{"icon":"lodging","fields":["operator","address","building_area","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"alpine_hut"},"name":"Alpine Hut"},"tourism/apartment":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"apartment"},"name":"Guest Apartment / Condo"},"tourism/aquarium":{"icon":"water","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["fish","sea","water"],"tags":{"tourism":"aquarium"},"name":"Aquarium"},"tourism/artwork":{"icon":"art-gallery","fields":["artwork_type","artist"],"geometry":["point","vertex","area"],"tags":{"tourism":"artwork"},"terms":["mural","sculpture","statue"],"name":"Artwork"},"tourism/attraction":{"icon":"monument","fields":["operator","address"],"geometry":["point","vertex","area"],"tags":{"tourism":"attraction"},"name":"Tourist Attraction"},"tourism/camp_site":{"icon":"campsite","fields":["operator","address","capacity","fee","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"terms":["tent","rv"],"tags":{"tourism":"camp_site"},"name":"Campground"},"tourism/caravan_site":{"icon":"bus","fields":["operator","address","capacity","fee","sanitary_dump_station","power_supply","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","vertex","area"],"terms":["Motor Home","Camper"],"tags":{"tourism":"caravan_site"},"name":"RV Park"},"tourism/chalet":{"icon":"lodging","fields":["operator","address","building_area","smoking","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"chalet"},"name":"Chalet"},"tourism/gallery":{"icon":"art-gallery","fields":["artwork_type","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["art*","exhibit*","paint*","photo*","sculpt*"],"tags":{"tourism":"gallery"},"name":"Art Gallery"},"tourism/guest_house":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"guest_house"},"terms":["B&B","Bed and Breakfast"],"name":"Guest House"},"tourism/hostel":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"hostel"},"name":"Hostel"},"tourism/hotel":{"icon":"lodging","fields":["operator","address","building_area","smoking","stars","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"hotel"},"name":"Hotel"},"tourism/information":{"fields":["information","operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information"},"name":"Information"},"tourism/information/board":{"fields":["operator","board_type"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"board"},"name":"Information Board"},"tourism/information/guidepost":{"fields":["operator","ref"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"guidepost"},"name":"Guidepost"},"tourism/information/map":{"fields":["operator","map_type","map_size"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"map"},"name":"Map"},"tourism/information/office":{"fields":["operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information","information":"office"},"name":"Tourist Information Office"},"tourism/motel":{"icon":"lodging","fields":["operator","address","building_area","smoking","rooms","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"tourism":"motel"},"name":"Motel"},"tourism/museum":{"icon":"museum","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["art*","exhibit*","gallery","foundation","hall","institution","paint*","photo*","sculpt*"],"tags":{"tourism":"museum"},"name":"Museum"},"tourism/picnic_site":{"icon":"park","fields":["operator","address","smoking"],"geometry":["point","vertex","area"],"terms":["camp"],"tags":{"tourism":"picnic_site"},"name":"Picnic Site"},"tourism/theme_park":{"fields":["operator","address","opening_hours"],"geometry":["point","area"],"tags":{"tourism":"theme_park"},"name":"Theme Park"},"tourism/viewpoint":{"geometry":["point","vertex"],"tags":{"tourism":"viewpoint"},"name":"Viewpoint"},"tourism/zoo":{"icon":"zoo","fields":["operator","address","opening_hours"],"geometry":["point","area"],"terms":["animal"],"tags":{"tourism":"zoo"},"name":"Zoo"},"traffic_calming":{"fields":["traffic_calming","parallel_direction"],"geometry":["vertex","line"],"tags":{"traffic_calming":"*"},"terms":["bump","hump","slow","speed"],"name":"Traffic Calming"},"traffic_calming/bump":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["hump","speed","slow"],"tags":{"traffic_calming":"bump"},"name":"Speed Bump"},"traffic_calming/chicane":{"fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["driveway link","speed","slow"],"tags":{"traffic_calming":"chicane"},"name":"Traffic Chicane"},"traffic_calming/choker":{"fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"choker"},"name":"Traffic Choker"},"traffic_calming/cushion":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["bump","hump","speed","slow"],"tags":{"traffic_calming":"cushion"},"name":"Speed Cushion"},"traffic_calming/dip":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["speed","slow"],"tags":{"traffic_calming":"dip"},"name":"Dip"},"traffic_calming/hump":{"fields":["surface","parallel_direction"],"geometry":["vertex","line"],"terms":["bump","speed","slow"],"tags":{"traffic_calming":"hump"},"name":"Speed Hump"},"traffic_calming/island":{"icon":"circle","geometry":["vertex"],"terms":["circle","roundabout","slow"],"tags":{"traffic_calming":"island"},"name":"Traffic Island"},"traffic_calming/rumble_strip":{"fields":["parallel_direction"],"geometry":["vertex","line"],"terms":["audible lines","sleeper lines","growlers"],"tags":{"traffic_calming":"rumble_strip"},"name":"Rumble Strip"},"traffic_calming/table":{"fields":["surface"],"geometry":["vertex","line"],"terms":["flat top","hump","speed","slow"],"tags":{"highway":"crossing","traffic_calming":"table"},"name":"Raised Pedestrian Crossing"},"type/multipolygon":{"geometry":["area","relation"],"tags":{"type":"multipolygon"},"removeTags":{},"name":"Multipolygon","icon":"multipolygon","searchable":false,"matchScore":0.1},"type/boundary":{"geometry":["relation"],"tags":{"type":"boundary"},"name":"Boundary","icon":"boundary","fields":["boundary"]},"type/boundary/administrative":{"name":"Administrative Boundary","geometry":["relation"],"tags":{"type":"boundary","boundary":"administrative"},"fields":["admin_level"],"icon":"boundary"},"type/restriction":{"geometry":["relation"],"tags":{"type":"restriction"},"name":"Restriction","icon":"restriction","fields":["restriction","except"]},"type/restriction/no_left_turn":{"name":"No Left Turn","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_left_turn"},"fields":["except"],"icon":"restriction-no-left-turn"},"type/restriction/no_right_turn":{"name":"No Right Turn","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_right_turn"},"fields":["except"],"icon":"restriction-no-right-turn"},"type/restriction/no_straight_on":{"name":"No Straight On","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_straight_on"},"fields":["except"],"icon":"restriction-no-straight-on"},"type/restriction/no_u_turn":{"name":"No U-turn","geometry":["relation"],"tags":{"type":"restriction","restriction":"no_u_turn"},"fields":["except"],"icon":"restriction-no-u-turn"},"type/restriction/only_left_turn":{"name":"Left Turn Only","geometry":["relation"],"tags":{"type":"restriction","restriction":"only_left_turn"},"fields":["except"],"icon":"restriction-only-left-turn"},"type/restriction/only_right_turn":{"name":"Right Turn Only","geometry":["relation"],"tags":{"type":"restriction","restriction":"only_right_turn"},"fields":["except"],"icon":"restriction-only-right-turn"},"type/restriction/only_straight_on":{"name":"No Turns","geometry":["relation"],"tags":{"type":"restriction","restriction":"only_straight_on"},"fields":["except"],"icon":"restriction-only-straight-on"},"type/route_master":{"geometry":["relation"],"tags":{"type":"route_master"},"name":"Route Master","icon":"route-master","fields":["route_master","ref","operator","network"]},"type/route":{"geometry":["relation"],"tags":{"type":"route"},"name":"Route","icon":"route","fields":["route","ref","operator","network"]},"type/route/bicycle":{"geometry":["relation"],"tags":{"type":"route","route":"bicycle"},"name":"Cycle Route","icon":"route-bicycle","fields":["ref","network_bicycle","cycle_network"]},"type/route/bus":{"geometry":["relation"],"tags":{"type":"route","route":"bus"},"name":"Bus Route","icon":"route-bus","fields":["ref","operator","network"]},"type/route/detour":{"geometry":["relation"],"tags":{"type":"route","route":"detour"},"name":"Detour Route","icon":"route-detour","fields":["ref"]},"type/route/ferry":{"geometry":["relation"],"tags":{"type":"route","route":"ferry"},"name":"Ferry Route","icon":"route-ferry","fields":["ref","operator","network"]},"type/route/foot":{"geometry":["relation"],"tags":{"type":"route","route":"foot"},"name":"Foot Route","icon":"route-foot","fields":["ref","operator","network_foot"]},"type/route/hiking":{"geometry":["relation"],"tags":{"type":"route","route":"hiking"},"name":"Hiking Route","icon":"route-foot","fields":["ref","operator","network_foot"]},"type/route/horse":{"geometry":["relation"],"tags":{"type":"route","route":"horse"},"name":"Riding Route","icon":"route-horse","fields":["ref","operator","network_horse"]},"type/route/pipeline":{"geometry":["relation"],"tags":{"type":"route","route":"pipeline"},"name":"Pipeline Route","icon":"route-pipeline","fields":["ref","operator"]},"type/route/power":{"geometry":["relation"],"tags":{"type":"route","route":"power"},"name":"Power Route","icon":"route-power","fields":["ref","operator"]},"type/route/road":{"geometry":["relation"],"tags":{"type":"route","route":"road"},"name":"Road Route","icon":"route-road","fields":["ref","network_road"]},"type/route/train":{"geometry":["relation"],"tags":{"type":"route","route":"train"},"name":"Train Route","icon":"route-train","fields":["ref","operator","network"]},"type/route/tram":{"geometry":["relation"],"tags":{"type":"route","route":"tram"},"name":"Tram Route","icon":"route-tram","fields":["ref","operator","network"]},"type/site":{"geometry":["relation"],"tags":{"type":"site"},"name":"Site","icon":"relation","fields":["site"]},"vertex":{"name":"Other","tags":{},"geometry":["vertex"],"matchScore":0.1},"waterway/boatyard":{"icon":"harbor","fields":["operator"],"geometry":["area","vertex","point"],"tags":{"waterway":"boatyard"},"name":"Boatyard"},"waterway/canal":{"icon":"waterway-canal","fields":["width"],"geometry":["line"],"tags":{"waterway":"canal"},"name":"Canal"},"waterway/dam":{"icon":"dam","geometry":["point","vertex","line","area"],"tags":{"waterway":"dam"},"name":"Dam"},"waterway/ditch":{"icon":"waterway-ditch","fields":["tunnel"],"geometry":["line"],"tags":{"waterway":"ditch"},"name":"Ditch"},"waterway/dock":{"icon":"harbor","fields":["dock","operator"],"geometry":["area","vertex","point"],"terms":["boat","ship","vessel","marine"],"tags":{"waterway":"dock"},"name":"Wet Dock / Dry Dock"},"waterway/drain":{"icon":"waterway-stream","fields":["tunnel"],"geometry":["line"],"tags":{"waterway":"drain"},"name":"Drain"},"waterway/fuel":{"icon":"fuel","fields":["operator","address","opening_hours","fuel_multi"],"geometry":["point","area"],"terms":["petrol","gas","diesel","boat"],"tags":{"waterway":"fuel"},"name":"Marine Fuel Station"},"waterway/river":{"icon":"waterway-river","fields":["tunnel","width"],"geometry":["line"],"terms":["beck","branch","brook","course","creek","estuary","rill","rivulet","run","runnel","stream","tributary","watercourse"],"tags":{"waterway":"river"},"name":"River"},"waterway/riverbank":{"icon":"water","geometry":["area"],"tags":{"waterway":"riverbank"},"name":"Riverbank"},"waterway/sanitary_dump_station":{"fields":["operator","access_toilets","fee","water_point"],"geometry":["point","vertex","area"],"terms":["Boat","Watercraft","Sanitary","Dump Station","Pumpout","Pump out","Elsan","CDP","CTDP","Chemical Toilet"],"tags":{"waterway":"sanitary_dump_station"},"name":"Marine Toilet Disposal"},"waterway/stream":{"icon":"waterway-stream","fields":["tunnel","width"],"geometry":["line"],"terms":["beck","branch","brook","burn","course","creek","current","drift","flood","flow","freshet","race","rill","rindle","rivulet","run","runnel","rush","spate","spritz","surge","tide","torrent","tributary","watercourse"],"tags":{"waterway":"stream"},"name":"Stream"},"waterway/water_point":{"icon":"water","geometry":["area","vertex","point"],"tags":{"waterway":"water_point"},"name":"Marine Drinking Water"},"waterway/waterfall":{"icon":"water","fields":["height","width"],"geometry":["vertex"],"terms":["fall"],"tags":{"waterway":"waterfall"},"name":"Waterfall"},"waterway/weir":{"icon":"dam","geometry":["vertex","line"],"tags":{"waterway":"weir"},"name":"Weir"},"amenity/fuel/76":{"tags":{"name":"76","amenity":"fuel"},"name":"76","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Neste":{"tags":{"name":"Neste","amenity":"fuel"},"name":"Neste","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BP":{"tags":{"name":"BP","amenity":"fuel"},"name":"BP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Shell":{"tags":{"name":"Shell","amenity":"fuel"},"name":"Shell","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Agip":{"tags":{"name":"Agip","amenity":"fuel"},"name":"Agip","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Migrol":{"tags":{"name":"Migrol","amenity":"fuel"},"name":"Migrol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Avia":{"tags":{"name":"Avia","amenity":"fuel"},"name":"Avia","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Texaco":{"tags":{"name":"Texaco","amenity":"fuel"},"name":"Texaco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Total":{"tags":{"name":"Total","amenity":"fuel"},"name":"Total","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Statoil":{"tags":{"name":"Statoil","amenity":"fuel"},"name":"Statoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Esso":{"tags":{"name":"Esso","amenity":"fuel"},"name":"Esso","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Jet":{"tags":{"name":"Jet","amenity":"fuel"},"name":"Jet","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Avanti":{"tags":{"name":"Avanti","amenity":"fuel"},"name":"Avanti","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OMV":{"tags":{"name":"OMV","amenity":"fuel"},"name":"OMV","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Aral":{"tags":{"name":"Aral","amenity":"fuel"},"name":"Aral","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/JET":{"tags":{"name":"JET","amenity":"fuel"},"name":"JET","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/United":{"tags":{"name":"United","amenity":"fuel"},"name":"United","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Mobil":{"tags":{"name":"Mobil","amenity":"fuel"},"name":"Mobil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Caltex":{"tags":{"name":"Caltex","amenity":"fuel"},"name":"Caltex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sunoco":{"tags":{"name":"Sunoco","amenity":"fuel"},"name":"Sunoco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Q8":{"tags":{"name":"Q8","amenity":"fuel"},"name":"Q8","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ARAL":{"tags":{"name":"ARAL","amenity":"fuel"},"name":"ARAL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CEPSA":{"tags":{"name":"CEPSA","amenity":"fuel"},"name":"CEPSA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BFT":{"tags":{"name":"BFT","amenity":"fuel"},"name":"BFT","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petron":{"tags":{"name":"Petron","amenity":"fuel"},"name":"Petron","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Total Access":{"tags":{"name":"Total Access","amenity":"fuel"},"name":"Total Access","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Elf":{"tags":{"name":"Elf","amenity":"fuel"},"name":"Elf","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Station Service E. Leclerc":{"tags":{"name":"Station Service E. Leclerc","amenity":"fuel"},"name":"Station Service E. Leclerc","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Shell Express":{"tags":{"name":"Shell Express","amenity":"fuel"},"name":"Shell Express","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Hess":{"tags":{"name":"Hess","amenity":"fuel"},"name":"Hess","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Flying V":{"tags":{"name":"Flying V","amenity":"fuel"},"name":"Flying V","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/bft":{"tags":{"name":"bft","amenity":"fuel"},"name":"bft","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Gulf":{"tags":{"name":"Gulf","amenity":"fuel"},"name":"Gulf","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PTT":{"tags":{"name":"PTT","amenity":"fuel"},"name":"PTT","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/St1":{"tags":{"name":"St1","amenity":"fuel"},"name":"St1","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Teboil":{"tags":{"name":"Teboil","amenity":"fuel"},"name":"Teboil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/HEM":{"tags":{"name":"HEM","amenity":"fuel"},"name":"HEM","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/GALP":{"tags":{"name":"GALP","amenity":"fuel"},"name":"GALP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OK":{"tags":{"name":"OK","amenity":"fuel"},"name":"OK","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ÖMV":{"tags":{"name":"ÖMV","amenity":"fuel"},"name":"ÖMV","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tinq":{"tags":{"name":"Tinq","amenity":"fuel"},"name":"Tinq","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OKQ8":{"tags":{"name":"OKQ8","amenity":"fuel"},"name":"OKQ8","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Repsol":{"tags":{"name":"Repsol","amenity":"fuel"},"name":"Repsol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Westfalen":{"tags":{"name":"Westfalen","amenity":"fuel"},"name":"Westfalen","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Esso Express":{"tags":{"name":"Esso Express","amenity":"fuel"},"name":"Esso Express","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tamoil":{"tags":{"name":"Tamoil","amenity":"fuel"},"name":"Tamoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Engen":{"tags":{"name":"Engen","amenity":"fuel"},"name":"Engen","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sasol":{"tags":{"name":"Sasol","amenity":"fuel"},"name":"Sasol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Topaz":{"tags":{"name":"Topaz","amenity":"fuel"},"name":"Topaz","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/LPG":{"tags":{"name":"LPG","amenity":"fuel"},"name":"LPG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Orlen":{"tags":{"name":"Orlen","amenity":"fuel"},"name":"Orlen","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Oilibya":{"tags":{"name":"Oilibya","amenity":"fuel"},"name":"Oilibya","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tango":{"tags":{"name":"Tango","amenity":"fuel"},"name":"Tango","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Star":{"tags":{"name":"Star","amenity":"fuel"},"name":"Star","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Петрол":{"tags":{"name":"Петрол","amenity":"fuel"},"name":"Петрол","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Cepsa":{"tags":{"name":"Cepsa","amenity":"fuel"},"name":"Cepsa","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OIL!":{"tags":{"name":"OIL!","amenity":"fuel"},"name":"OIL!","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ultramar":{"tags":{"name":"Ultramar","amenity":"fuel"},"name":"Ultramar","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Irving":{"tags":{"name":"Irving","amenity":"fuel"},"name":"Irving","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Lukoil":{"tags":{"name":"Lukoil","amenity":"fuel"},"name":"Lukoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petro-Canada":{"tags":{"name":"Petro-Canada","amenity":"fuel"},"name":"Petro-Canada","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Agrola":{"tags":{"name":"Agrola","amenity":"fuel"},"name":"Agrola","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Husky":{"tags":{"name":"Husky","amenity":"fuel"},"name":"Husky","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Slovnaft":{"tags":{"name":"Slovnaft","amenity":"fuel"},"name":"Slovnaft","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sheetz":{"tags":{"name":"Sheetz","amenity":"fuel"},"name":"Sheetz","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Mol":{"tags":{"name":"Mol","amenity":"fuel"},"name":"Mol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petronas":{"tags":{"name":"Petronas","amenity":"fuel"},"name":"Petronas","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Газпромнефть":{"tags":{"name":"Газпромнефть","amenity":"fuel"},"name":"Газпромнефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Лукойл":{"tags":{"name":"Лукойл","amenity":"fuel"},"name":"Лукойл","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Elan":{"tags":{"name":"Elan","amenity":"fuel"},"name":"Elan","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Роснефть":{"tags":{"name":"Роснефть","amenity":"fuel"},"name":"Роснефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Turmöl":{"tags":{"name":"Turmöl","amenity":"fuel"},"name":"Turmöl","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Neste A24":{"tags":{"name":"Neste A24","amenity":"fuel"},"name":"Neste A24","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Marathon":{"tags":{"name":"Marathon","amenity":"fuel"},"name":"Marathon","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Valero":{"tags":{"name":"Valero","amenity":"fuel"},"name":"Valero","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eni":{"tags":{"name":"Eni","amenity":"fuel"},"name":"Eni","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Chevron":{"tags":{"name":"Chevron","amenity":"fuel"},"name":"Chevron","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ТНК":{"tags":{"name":"ТНК","amenity":"fuel"},"name":"ТНК","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/REPSOL":{"tags":{"name":"REPSOL","amenity":"fuel"},"name":"REPSOL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/MOL":{"tags":{"name":"MOL","amenity":"fuel"},"name":"MOL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Bliska":{"tags":{"name":"Bliska","amenity":"fuel"},"name":"Bliska","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Api":{"tags":{"name":"Api","amenity":"fuel"},"name":"Api","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Arco":{"tags":{"name":"Arco","amenity":"fuel"},"name":"Arco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pemex":{"tags":{"name":"Pemex","amenity":"fuel"},"name":"Pemex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Exxon":{"tags":{"name":"Exxon","amenity":"fuel"},"name":"Exxon","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Coles Express":{"tags":{"name":"Coles Express","amenity":"fuel"},"name":"Coles Express","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrom":{"tags":{"name":"Petrom","amenity":"fuel"},"name":"Petrom","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/PETRONOR":{"tags":{"name":"PETRONOR","amenity":"fuel"},"name":"PETRONOR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Rompetrol":{"tags":{"name":"Rompetrol","amenity":"fuel"},"name":"Rompetrol","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Lotos":{"tags":{"name":"Lotos","amenity":"fuel"},"name":"Lotos","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ОМВ":{"tags":{"name":"ОМВ","amenity":"fuel"},"name":"ОМВ","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/BR":{"tags":{"name":"BR","amenity":"fuel"},"name":"BR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Copec":{"tags":{"name":"Copec","amenity":"fuel"},"name":"Copec","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrobras":{"tags":{"name":"Petrobras","amenity":"fuel"},"name":"Petrobras","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Liberty":{"tags":{"name":"Liberty","amenity":"fuel"},"name":"Liberty","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IP":{"tags":{"name":"IP","amenity":"fuel"},"name":"IP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Erg":{"tags":{"name":"Erg","amenity":"fuel"},"name":"Erg","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eneos":{"tags":{"name":"Eneos","amenity":"fuel"},"name":"Eneos","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Citgo":{"tags":{"name":"Citgo","amenity":"fuel"},"name":"Citgo","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Metano":{"tags":{"name":"Metano","amenity":"fuel"},"name":"Metano","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Сургутнефтегаз":{"tags":{"name":"Сургутнефтегаз","amenity":"fuel"},"name":"Сургутнефтегаз","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/EKO":{"tags":{"name":"EKO","amenity":"fuel"},"name":"EKO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Eko":{"tags":{"name":"Eko","amenity":"fuel"},"name":"Eko","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Indipend.":{"tags":{"name":"Indipend.","amenity":"fuel"},"name":"Indipend.","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IES":{"tags":{"name":"IES","amenity":"fuel"},"name":"IES","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/TotalErg":{"tags":{"name":"TotalErg","amenity":"fuel"},"name":"TotalErg","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Cenex":{"tags":{"name":"Cenex","amenity":"fuel"},"name":"Cenex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ПТК":{"tags":{"name":"ПТК","amenity":"fuel"},"name":"ПТК","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/HP":{"tags":{"name":"HP","amenity":"fuel"},"name":"HP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Phillips 66":{"tags":{"name":"Phillips 66","amenity":"fuel"},"name":"Phillips 66","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CARREFOUR":{"tags":{"name":"CARREFOUR","amenity":"fuel"},"name":"CARREFOUR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ERG":{"tags":{"name":"ERG","amenity":"fuel"},"name":"ERG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Speedway":{"tags":{"name":"Speedway","amenity":"fuel"},"name":"Speedway","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Benzina":{"tags":{"name":"Benzina","amenity":"fuel"},"name":"Benzina","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Татнефть":{"tags":{"name":"Татнефть","amenity":"fuel"},"name":"Татнефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Terpel":{"tags":{"name":"Terpel","amenity":"fuel"},"name":"Terpel","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/WOG":{"tags":{"name":"WOG","amenity":"fuel"},"name":"WOG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Seaoil":{"tags":{"name":"Seaoil","amenity":"fuel"},"name":"Seaoil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/АЗС":{"tags":{"name":"АЗС","amenity":"fuel"},"name":"АЗС","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kwik Trip":{"tags":{"name":"Kwik Trip","amenity":"fuel"},"name":"Kwik Trip","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Pertamina":{"tags":{"name":"Pertamina","amenity":"fuel"},"name":"Pertamina","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/COSMO":{"tags":{"name":"COSMO","amenity":"fuel"},"name":"COSMO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Z":{"tags":{"name":"Z","amenity":"fuel"},"name":"Z","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Indian Oil":{"tags":{"name":"Indian Oil","amenity":"fuel"},"name":"Indian Oil","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/АГЗС":{"tags":{"name":"АГЗС","amenity":"fuel"},"name":"АГЗС","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/INA":{"tags":{"name":"INA","amenity":"fuel"},"name":"INA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/JOMO":{"tags":{"name":"JOMO","amenity":"fuel"},"name":"JOMO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Holiday":{"tags":{"name":"Holiday","amenity":"fuel"},"name":"Holiday","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/YPF":{"tags":{"name":"YPF","amenity":"fuel"},"name":"YPF","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/IDEMITSU":{"tags":{"name":"IDEMITSU","amenity":"fuel"},"name":"IDEMITSU","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ENEOS":{"tags":{"name":"ENEOS","amenity":"fuel"},"name":"ENEOS","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Bharat Petroleum":{"tags":{"name":"Bharat Petroleum","amenity":"fuel"},"name":"Bharat Petroleum","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CAMPSA":{"tags":{"name":"CAMPSA","amenity":"fuel"},"name":"CAMPSA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Casey's General Store":{"tags":{"name":"Casey's General Store","amenity":"fuel"},"name":"Casey's General Store","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Башнефть":{"tags":{"name":"Башнефть","amenity":"fuel"},"name":"Башнефть","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kangaroo":{"tags":{"name":"Kangaroo","amenity":"fuel"},"name":"Kangaroo","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/コスモ石油 (COSMO)":{"tags":{"name":"コスモ石油 (COSMO)","amenity":"fuel"},"name":"コスモ石油 (COSMO)","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/MEROIL":{"tags":{"name":"MEROIL","amenity":"fuel"},"name":"MEROIL","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/1-2-3":{"tags":{"name":"1-2-3","amenity":"fuel"},"name":"1-2-3","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/出光":{"tags":{"name":"出光","name:en":"IDEMITSU","amenity":"fuel"},"name":"出光","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/НК Альянс":{"tags":{"name":"НК Альянс","amenity":"fuel"},"name":"НК Альянс","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sinclair":{"tags":{"name":"Sinclair","amenity":"fuel"},"name":"Sinclair","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Conoco":{"tags":{"name":"Conoco","amenity":"fuel"},"name":"Conoco","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/SPBU":{"tags":{"name":"SPBU","amenity":"fuel"},"name":"SPBU","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Макпетрол":{"tags":{"name":"Макпетрол","amenity":"fuel"},"name":"Макпетрол","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto Ipiranga":{"tags":{"name":"Posto Ipiranga","amenity":"fuel"},"name":"Posto Ipiranga","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto Shell":{"tags":{"name":"Posto Shell","amenity":"fuel"},"name":"Posto Shell","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Phoenix":{"tags":{"name":"Phoenix","amenity":"fuel"},"name":"Phoenix","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Ipiranga":{"tags":{"name":"Ipiranga","amenity":"fuel"},"name":"Ipiranga","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/OKKO":{"tags":{"name":"OKKO","amenity":"fuel"},"name":"OKKO","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ОККО":{"tags":{"name":"ОККО","amenity":"fuel"},"name":"ОККО","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/บางจาก":{"tags":{"name":"บางจาก","amenity":"fuel"},"name":"บางจาก","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/QuikTrip":{"tags":{"name":"QuikTrip","amenity":"fuel"},"name":"QuikTrip","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto BR":{"tags":{"name":"Posto BR","amenity":"fuel"},"name":"Posto BR","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ป ต ท":{"tags":{"name":"ป ต ท","amenity":"fuel"},"name":"ป ต ท","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ปตท":{"tags":{"name":"ปตท","amenity":"fuel"},"name":"ปตท","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/ANP":{"tags":{"name":"ANP","amenity":"fuel"},"name":"ANP","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Kum & Go":{"tags":{"name":"Kum & Go","amenity":"fuel"},"name":"Kum & Go","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Petrolimex":{"tags":{"name":"Petrolimex","amenity":"fuel"},"name":"Petrolimex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Sokimex":{"tags":{"name":"Sokimex","amenity":"fuel"},"name":"Sokimex","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Tela":{"tags":{"name":"Tela","amenity":"fuel"},"name":"Tela","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Posto":{"tags":{"name":"Posto","amenity":"fuel"},"name":"Posto","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Укрнафта":{"tags":{"name":"Укрнафта","amenity":"fuel"},"name":"Укрнафта","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Татнефтепродукт":{"tags":{"name":"Татнефтепродукт","amenity":"fuel"},"name":"Татнефтепродукт","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Afriquia":{"tags":{"name":"Afriquia","amenity":"fuel"},"name":"Afriquia","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/Murphy USA":{"tags":{"name":"Murphy USA","amenity":"fuel"},"name":"Murphy USA","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/昭和シェル (Showa-shell)":{"tags":{"name":"昭和シェル (Showa-shell)","amenity":"fuel"},"name":"昭和シェル (Showa-shell)","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/エネオス":{"tags":{"name":"エネオス","amenity":"fuel"},"name":"エネオス","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/fuel/CNG":{"tags":{"name":"CNG","amenity":"fuel"},"name":"CNG","icon":"fuel","geometry":["point","area"],"fields":["operator","address","opening_hours","fuel_multi"],"suggestion":true},"amenity/pub/Kings Arms":{"tags":{"name":"Kings Arms","amenity":"pub"},"name":"Kings Arms","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Ship":{"tags":{"name":"The Ship","amenity":"pub"},"name":"The Ship","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The White Horse":{"tags":{"name":"The White Horse","amenity":"pub"},"name":"The White Horse","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The White Hart":{"tags":{"name":"The White Hart","amenity":"pub"},"name":"The White Hart","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Royal Oak":{"tags":{"name":"Royal Oak","amenity":"pub"},"name":"Royal Oak","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Red Lion":{"tags":{"name":"The Red Lion","amenity":"pub"},"name":"The Red Lion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Kings Arms":{"tags":{"name":"The Kings Arms","amenity":"pub"},"name":"The Kings Arms","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Star":{"tags":{"name":"The Star","amenity":"pub"},"name":"The Star","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Anchor":{"tags":{"name":"The Anchor","amenity":"pub"},"name":"The Anchor","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Cross Keys":{"tags":{"name":"The Cross Keys","amenity":"pub"},"name":"The Cross Keys","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Wheatsheaf":{"tags":{"name":"The Wheatsheaf","amenity":"pub"},"name":"The Wheatsheaf","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Crown Inn":{"tags":{"name":"The Crown Inn","amenity":"pub"},"name":"The Crown Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Kings Head":{"tags":{"name":"The Kings Head","amenity":"pub"},"name":"The Kings Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Castle":{"tags":{"name":"The Castle","amenity":"pub"},"name":"The Castle","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Railway":{"tags":{"name":"The Railway","amenity":"pub"},"name":"The Railway","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The White Lion":{"tags":{"name":"The White Lion","amenity":"pub"},"name":"The White Lion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Bell":{"tags":{"name":"The Bell","amenity":"pub"},"name":"The Bell","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Bull":{"tags":{"name":"The Bull","amenity":"pub"},"name":"The Bull","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Plough":{"tags":{"name":"The Plough","amenity":"pub"},"name":"The Plough","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The George":{"tags":{"name":"The George","amenity":"pub"},"name":"The George","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Royal Oak":{"tags":{"name":"The Royal Oak","amenity":"pub"},"name":"The Royal Oak","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Fox":{"tags":{"name":"The Fox","amenity":"pub"},"name":"The Fox","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Prince of Wales":{"tags":{"name":"Prince of Wales","amenity":"pub"},"name":"Prince of Wales","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Rising Sun":{"tags":{"name":"The Rising Sun","amenity":"pub"},"name":"The Rising Sun","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Prince of Wales":{"tags":{"name":"The Prince of Wales","amenity":"pub"},"name":"The Prince of Wales","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Crown":{"tags":{"name":"The Crown","amenity":"pub"},"name":"The Crown","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Chequers":{"tags":{"name":"The Chequers","amenity":"pub"},"name":"The Chequers","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Swan":{"tags":{"name":"The Swan","amenity":"pub"},"name":"The Swan","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Rose and Crown":{"tags":{"name":"Rose and Crown","amenity":"pub"},"name":"Rose and Crown","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Victoria":{"tags":{"name":"The Victoria","amenity":"pub"},"name":"The Victoria","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/New Inn":{"tags":{"name":"New Inn","amenity":"pub"},"name":"New Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Royal Hotel":{"tags":{"name":"Royal Hotel","amenity":"pub"},"name":"Royal Hotel","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Red Lion":{"tags":{"name":"Red Lion","amenity":"pub"},"name":"Red Lion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Cross Keys":{"tags":{"name":"Cross Keys","amenity":"pub"},"name":"Cross Keys","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Greyhound":{"tags":{"name":"The Greyhound","amenity":"pub"},"name":"The Greyhound","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Black Horse":{"tags":{"name":"The Black Horse","amenity":"pub"},"name":"The Black Horse","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The New Inn":{"tags":{"name":"The New Inn","amenity":"pub"},"name":"The New Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Kings Head":{"tags":{"name":"Kings Head","amenity":"pub"},"name":"Kings Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Albion":{"tags":{"name":"The Albion","amenity":"pub"},"name":"The Albion","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Angel":{"tags":{"name":"The Angel","amenity":"pub"},"name":"The Angel","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Queens Head":{"tags":{"name":"The Queens Head","amenity":"pub"},"name":"The Queens Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/The Ship Inn":{"tags":{"name":"The Ship Inn","amenity":"pub"},"name":"The Ship Inn","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Rose & Crown":{"tags":{"name":"Rose & Crown","amenity":"pub"},"name":"Rose & Crown","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Queens Head":{"tags":{"name":"Queens Head","amenity":"pub"},"name":"Queens Head","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/pub/Irish Pub":{"tags":{"name":"Irish Pub","amenity":"pub"},"name":"Irish Pub","icon":"beer","geometry":["point","area"],"fields":["address","building_area","opening_hours","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Quick":{"tags":{"name":"Quick","amenity":"fast_food"},"name":"Quick","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/McDonald's":{"tags":{"name":"McDonald's","cuisine":"burger","amenity":"fast_food"},"name":"McDonald's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Subway":{"tags":{"name":"Subway","cuisine":"sandwich","amenity":"fast_food"},"name":"Subway","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Burger King":{"tags":{"name":"Burger King","cuisine":"burger","amenity":"fast_food"},"name":"Burger King","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Ali Baba":{"tags":{"name":"Ali Baba","amenity":"fast_food"},"name":"Ali Baba","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Hungry Jacks":{"tags":{"name":"Hungry Jacks","cuisine":"burger","amenity":"fast_food"},"name":"Hungry Jacks","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Red Rooster":{"tags":{"name":"Red Rooster","amenity":"fast_food"},"name":"Red Rooster","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/KFC":{"tags":{"name":"KFC","cuisine":"chicken","amenity":"fast_food"},"name":"KFC","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Domino's Pizza":{"tags":{"name":"Domino's Pizza","cuisine":"pizza","amenity":"fast_food"},"name":"Domino's Pizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Chowking":{"tags":{"name":"Chowking","amenity":"fast_food"},"name":"Chowking","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jollibee":{"tags":{"name":"Jollibee","amenity":"fast_food"},"name":"Jollibee","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Hesburger":{"tags":{"name":"Hesburger","amenity":"fast_food"},"name":"Hesburger","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/肯德基":{"tags":{"name":"肯德基","amenity":"fast_food"},"name":"肯德基","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Wendy's":{"tags":{"name":"Wendy's","cuisine":"burger","amenity":"fast_food"},"name":"Wendy's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Tim Hortons":{"tags":{"name":"Tim Hortons","amenity":"fast_food"},"name":"Tim Hortons","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Steers":{"tags":{"name":"Steers","amenity":"fast_food"},"name":"Steers","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Hardee's":{"tags":{"name":"Hardee's","cuisine":"burger","amenity":"fast_food"},"name":"Hardee's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Arby's":{"tags":{"name":"Arby's","amenity":"fast_food"},"name":"Arby's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/A&W":{"tags":{"name":"A&W","amenity":"fast_food"},"name":"A&W","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Dairy Queen":{"tags":{"name":"Dairy Queen","amenity":"fast_food"},"name":"Dairy Queen","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Hallo Pizza":{"tags":{"name":"Hallo Pizza","amenity":"fast_food"},"name":"Hallo Pizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Fish & Chips":{"tags":{"name":"Fish & Chips","amenity":"fast_food"},"name":"Fish & Chips","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Harvey's":{"tags":{"name":"Harvey's","amenity":"fast_food"},"name":"Harvey's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/麥當勞":{"tags":{"name":"麥當勞","amenity":"fast_food"},"name":"麥當勞","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza Pizza":{"tags":{"name":"Pizza Pizza","amenity":"fast_food"},"name":"Pizza Pizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kotipizza":{"tags":{"name":"Kotipizza","amenity":"fast_food"},"name":"Kotipizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jack in the Box":{"tags":{"name":"Jack in the Box","cuisine":"burger","amenity":"fast_food"},"name":"Jack in the Box","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Istanbul":{"tags":{"name":"Istanbul","amenity":"fast_food"},"name":"Istanbul","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Kochlöffel":{"tags":{"name":"Kochlöffel","amenity":"fast_food"},"name":"Kochlöffel","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Döner":{"tags":{"name":"Döner","amenity":"fast_food"},"name":"Döner","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Telepizza":{"tags":{"name":"Telepizza","amenity":"fast_food"},"name":"Telepizza","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Sibylla":{"tags":{"name":"Sibylla","amenity":"fast_food"},"name":"Sibylla","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Carl's Jr.":{"tags":{"name":"Carl's Jr.","cuisine":"burger","amenity":"fast_food"},"name":"Carl's Jr.","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Quiznos":{"tags":{"name":"Quiznos","cuisine":"sandwich","amenity":"fast_food"},"name":"Quiznos","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Wimpy":{"tags":{"name":"Wimpy","amenity":"fast_food"},"name":"Wimpy","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Sonic":{"tags":{"name":"Sonic","cuisine":"burger","amenity":"fast_food"},"name":"Sonic","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Bell":{"tags":{"name":"Taco Bell","cuisine":"mexican","amenity":"fast_food"},"name":"Taco Bell","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pizza Nova":{"tags":{"name":"Pizza Nova","amenity":"fast_food"},"name":"Pizza Nova","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Papa John's":{"tags":{"name":"Papa John's","cuisine":"pizza","amenity":"fast_food"},"name":"Papa John's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Nordsee":{"tags":{"name":"Nordsee","amenity":"fast_food"},"name":"Nordsee","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Mr. Sub":{"tags":{"name":"Mr. Sub","amenity":"fast_food"},"name":"Mr. Sub","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Макдоналдс":{"tags":{"name":"Макдоналдс","name:en":"McDonald's","amenity":"fast_food"},"name":"Макдоналдс","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Asia Imbiss":{"tags":{"name":"Asia Imbiss","amenity":"fast_food"},"name":"Asia Imbiss","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Chipotle":{"tags":{"name":"Chipotle","cuisine":"mexican","amenity":"fast_food"},"name":"Chipotle","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/マクドナルド":{"tags":{"name":"マクドナルド","name:en":"McDonald's","cuisine":"burger","amenity":"fast_food"},"name":"マクドナルド","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/In-N-Out Burger":{"tags":{"name":"In-N-Out Burger","amenity":"fast_food"},"name":"In-N-Out Burger","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jimmy John's":{"tags":{"name":"Jimmy John's","amenity":"fast_food"},"name":"Jimmy John's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Jamba Juice":{"tags":{"name":"Jamba Juice","amenity":"fast_food"},"name":"Jamba Juice","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Робин Сдобин":{"tags":{"name":"Робин Сдобин","amenity":"fast_food"},"name":"Робин Сдобин","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Baskin Robbins":{"tags":{"name":"Baskin Robbins","amenity":"fast_food"},"name":"Baskin Robbins","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/ケンタッキーフライドチキン":{"tags":{"name":"ケンタッキーフライドチキン","name:en":"KFC","cuisine":"chicken","amenity":"fast_food"},"name":"ケンタッキーフライドチキン","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/吉野家":{"tags":{"name":"吉野家","amenity":"fast_food"},"name":"吉野家","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco Time":{"tags":{"name":"Taco Time","amenity":"fast_food"},"name":"Taco Time","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/松屋":{"tags":{"name":"松屋","name:en":"Matsuya","amenity":"fast_food"},"name":"松屋","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Little Caesars":{"tags":{"name":"Little Caesars","amenity":"fast_food"},"name":"Little Caesars","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/El Pollo Loco":{"tags":{"name":"El Pollo Loco","amenity":"fast_food"},"name":"El Pollo Loco","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Del Taco":{"tags":{"name":"Del Taco","amenity":"fast_food"},"name":"Del Taco","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/White Castle":{"tags":{"name":"White Castle","amenity":"fast_food"},"name":"White Castle","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Boston Market":{"tags":{"name":"Boston Market","amenity":"fast_food"},"name":"Boston Market","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Chick-fil-A":{"tags":{"name":"Chick-fil-A","cuisine":"chicken","amenity":"fast_food"},"name":"Chick-fil-A","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Panda Express":{"tags":{"name":"Panda Express","cuisine":"chinese","amenity":"fast_food"},"name":"Panda Express","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Whataburger":{"tags":{"name":"Whataburger","amenity":"fast_food"},"name":"Whataburger","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Taco John's":{"tags":{"name":"Taco John's","amenity":"fast_food"},"name":"Taco John's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Теремок":{"tags":{"name":"Теремок","amenity":"fast_food"},"name":"Теремок","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Culver's":{"tags":{"name":"Culver's","amenity":"fast_food"},"name":"Culver's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Five Guys":{"tags":{"name":"Five Guys","amenity":"fast_food"},"name":"Five Guys","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Church's Chicken":{"tags":{"name":"Church's Chicken","amenity":"fast_food"},"name":"Church's Chicken","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Popeye's":{"tags":{"name":"Popeye's","cuisine":"chicken","amenity":"fast_food"},"name":"Popeye's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Long John Silver's":{"tags":{"name":"Long John Silver's","amenity":"fast_food"},"name":"Long John Silver's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Pollo Campero":{"tags":{"name":"Pollo Campero","amenity":"fast_food"},"name":"Pollo Campero","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Zaxby's":{"tags":{"name":"Zaxby's","amenity":"fast_food"},"name":"Zaxby's","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/すき家":{"tags":{"name":"すき家","name:en":"SUKIYA","amenity":"fast_food"},"name":"すき家","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/モスバーガー":{"tags":{"name":"モスバーガー","name:en":"MOS BURGER","amenity":"fast_food"},"name":"モスバーガー","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/Русский Аппетит":{"tags":{"name":"Русский Аппетит","amenity":"fast_food"},"name":"Русский Аппетит","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/fast_food/なか卯":{"tags":{"name":"なか卯","amenity":"fast_food"},"name":"なか卯","icon":"fast-food","geometry":["point","area"],"fields":["cuisine","operator","address","building_area","opening_hours","takeaway","delivery","drive_through","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Hut":{"tags":{"name":"Pizza Hut","cuisine":"pizza","amenity":"restaurant"},"name":"Pizza Hut","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Little Chef":{"tags":{"name":"Little Chef","amenity":"restaurant"},"name":"Little Chef","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Adler":{"tags":{"name":"Adler","amenity":"restaurant"},"name":"Adler","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Krone":{"tags":{"name":"Zur Krone","amenity":"restaurant"},"name":"Zur Krone","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Deutsches Haus":{"tags":{"name":"Deutsches Haus","amenity":"restaurant"},"name":"Deutsches Haus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Krone":{"tags":{"name":"Krone","amenity":"restaurant"},"name":"Krone","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Akropolis":{"tags":{"name":"Akropolis","amenity":"restaurant"},"name":"Akropolis","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Schützenhaus":{"tags":{"name":"Schützenhaus","amenity":"restaurant"},"name":"Schützenhaus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kreuz":{"tags":{"name":"Kreuz","amenity":"restaurant"},"name":"Kreuz","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Waldschänke":{"tags":{"name":"Waldschänke","amenity":"restaurant"},"name":"Waldschänke","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Piazza":{"tags":{"name":"La Piazza","amenity":"restaurant"},"name":"La Piazza","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Lamm":{"tags":{"name":"Lamm","amenity":"restaurant"},"name":"Lamm","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Sonne":{"tags":{"name":"Zur Sonne","amenity":"restaurant"},"name":"Zur Sonne","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Linde":{"tags":{"name":"Zur Linde","amenity":"restaurant"},"name":"Zur Linde","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Poseidon":{"tags":{"name":"Poseidon","amenity":"restaurant"},"name":"Poseidon","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shanghai":{"tags":{"name":"Shanghai","amenity":"restaurant"},"name":"Shanghai","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Red Lobster":{"tags":{"name":"Red Lobster","amenity":"restaurant"},"name":"Red Lobster","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zum Löwen":{"tags":{"name":"Zum Löwen","amenity":"restaurant"},"name":"Zum Löwen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Swiss Chalet":{"tags":{"name":"Swiss Chalet","amenity":"restaurant"},"name":"Swiss Chalet","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Olympia":{"tags":{"name":"Olympia","amenity":"restaurant"},"name":"Olympia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Wagamama":{"tags":{"name":"Wagamama","amenity":"restaurant"},"name":"Wagamama","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Frankie & Benny's":{"tags":{"name":"Frankie & Benny's","amenity":"restaurant"},"name":"Frankie & Benny's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hooters":{"tags":{"name":"Hooters","amenity":"restaurant"},"name":"Hooters","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sternen":{"tags":{"name":"Sternen","amenity":"restaurant"},"name":"Sternen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hirschen":{"tags":{"name":"Hirschen","amenity":"restaurant"},"name":"Hirschen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Denny's":{"tags":{"name":"Denny's","amenity":"restaurant"},"name":"Denny's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Athen":{"tags":{"name":"Athen","amenity":"restaurant"},"name":"Athen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sonne":{"tags":{"name":"Sonne","amenity":"restaurant"},"name":"Sonne","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hirsch":{"tags":{"name":"Hirsch","amenity":"restaurant"},"name":"Hirsch","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ratskeller":{"tags":{"name":"Ratskeller","amenity":"restaurant"},"name":"Ratskeller","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Cantina":{"tags":{"name":"La Cantina","amenity":"restaurant"},"name":"La Cantina","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gasthaus Krone":{"tags":{"name":"Gasthaus Krone","amenity":"restaurant"},"name":"Gasthaus Krone","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/El Greco":{"tags":{"name":"El Greco","amenity":"restaurant"},"name":"El Greco","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Gasthof zur Post":{"tags":{"name":"Gasthof zur Post","amenity":"restaurant"},"name":"Gasthof zur Post","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Nando's":{"tags":{"name":"Nando's","amenity":"restaurant"},"name":"Nando's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Löwen":{"tags":{"name":"Löwen","amenity":"restaurant"},"name":"Löwen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Pataterie":{"tags":{"name":"La Pataterie","amenity":"restaurant"},"name":"La Pataterie","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bella Napoli":{"tags":{"name":"Bella Napoli","amenity":"restaurant"},"name":"Bella Napoli","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizza Express":{"tags":{"name":"Pizza Express","amenity":"restaurant"},"name":"Pizza Express","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mandarin":{"tags":{"name":"Mandarin","amenity":"restaurant"},"name":"Mandarin","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hong Kong":{"tags":{"name":"Hong Kong","amenity":"restaurant"},"name":"Hong Kong","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zizzi":{"tags":{"name":"Zizzi","amenity":"restaurant"},"name":"Zizzi","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Cracker Barrel":{"tags":{"name":"Cracker Barrel","amenity":"restaurant"},"name":"Cracker Barrel","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rhodos":{"tags":{"name":"Rhodos","amenity":"restaurant"},"name":"Rhodos","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Lindenhof":{"tags":{"name":"Lindenhof","amenity":"restaurant"},"name":"Lindenhof","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Milano":{"tags":{"name":"Milano","amenity":"restaurant"},"name":"Milano","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Dolce Vita":{"tags":{"name":"Dolce Vita","amenity":"restaurant"},"name":"Dolce Vita","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kirchenwirt":{"tags":{"name":"Kirchenwirt","amenity":"restaurant"},"name":"Kirchenwirt","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kantine":{"tags":{"name":"Kantine","amenity":"restaurant"},"name":"Kantine","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ochsen":{"tags":{"name":"Ochsen","amenity":"restaurant"},"name":"Ochsen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Spur":{"tags":{"name":"Spur","amenity":"restaurant"},"name":"Spur","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mykonos":{"tags":{"name":"Mykonos","amenity":"restaurant"},"name":"Mykonos","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Lotus":{"tags":{"name":"Lotus","amenity":"restaurant"},"name":"Lotus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Applebee's":{"tags":{"name":"Applebee's","amenity":"restaurant"},"name":"Applebee's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Flunch":{"tags":{"name":"Flunch","amenity":"restaurant"},"name":"Flunch","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Zur Post":{"tags":{"name":"Zur Post","amenity":"restaurant"},"name":"Zur Post","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Town":{"tags":{"name":"China Town","amenity":"restaurant"},"name":"China Town","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Dolce Vita":{"tags":{"name":"La Dolce Vita","amenity":"restaurant"},"name":"La Dolce Vita","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Waffle House":{"tags":{"name":"Waffle House","amenity":"restaurant"},"name":"Waffle House","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Delphi":{"tags":{"name":"Delphi","amenity":"restaurant"},"name":"Delphi","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Linde":{"tags":{"name":"Linde","amenity":"restaurant"},"name":"Linde","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Outback Steakhouse":{"tags":{"name":"Outback Steakhouse","amenity":"restaurant"},"name":"Outback Steakhouse","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Dionysos":{"tags":{"name":"Dionysos","amenity":"restaurant"},"name":"Dionysos","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Kelsey's":{"tags":{"name":"Kelsey's","amenity":"restaurant"},"name":"Kelsey's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Boston Pizza":{"tags":{"name":"Boston Pizza","amenity":"restaurant"},"name":"Boston Pizza","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bella Italia":{"tags":{"name":"Bella Italia","amenity":"restaurant"},"name":"Bella Italia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sizzler":{"tags":{"name":"Sizzler","amenity":"restaurant"},"name":"Sizzler","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Grüner Baum":{"tags":{"name":"Grüner Baum","amenity":"restaurant"},"name":"Grüner Baum","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Taj Mahal":{"tags":{"name":"Taj Mahal","amenity":"restaurant"},"name":"Taj Mahal","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Rössli":{"tags":{"name":"Rössli","amenity":"restaurant"},"name":"Rössli","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Traube":{"tags":{"name":"Traube","amenity":"restaurant"},"name":"Traube","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Adria":{"tags":{"name":"Adria","amenity":"restaurant"},"name":"Adria","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Red Robin":{"tags":{"name":"Red Robin","amenity":"restaurant"},"name":"Red Robin","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Roma":{"tags":{"name":"Roma","amenity":"restaurant"},"name":"Roma","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/San Marco":{"tags":{"name":"San Marco","amenity":"restaurant"},"name":"San Marco","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hellas":{"tags":{"name":"Hellas","amenity":"restaurant"},"name":"Hellas","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Perla":{"tags":{"name":"La Perla","amenity":"restaurant"},"name":"La Perla","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Vips":{"tags":{"name":"Vips","amenity":"restaurant"},"name":"Vips","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Panera Bread":{"tags":{"name":"Panera Bread","amenity":"restaurant"},"name":"Panera Bread","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Da Vinci":{"tags":{"name":"Da Vinci","amenity":"restaurant"},"name":"Da Vinci","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hippopotamus":{"tags":{"name":"Hippopotamus","amenity":"restaurant"},"name":"Hippopotamus","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Prezzo":{"tags":{"name":"Prezzo","amenity":"restaurant"},"name":"Prezzo","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Courtepaille":{"tags":{"name":"Courtepaille","amenity":"restaurant"},"name":"Courtepaille","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Hard Rock Cafe":{"tags":{"name":"Hard Rock Cafe","amenity":"restaurant"},"name":"Hard Rock Cafe","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Panorama":{"tags":{"name":"Panorama","amenity":"restaurant"},"name":"Panorama","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/デニーズ":{"tags":{"name":"デニーズ","amenity":"restaurant"},"name":"デニーズ","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sportheim":{"tags":{"name":"Sportheim","amenity":"restaurant"},"name":"Sportheim","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/餃子の王将":{"tags":{"name":"餃子の王将","amenity":"restaurant"},"name":"餃子の王将","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bären":{"tags":{"name":"Bären","amenity":"restaurant"},"name":"Bären","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Alte Post":{"tags":{"name":"Alte Post","amenity":"restaurant"},"name":"Alte Post","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Pizzeria Roma":{"tags":{"name":"Pizzeria Roma","amenity":"restaurant"},"name":"Pizzeria Roma","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/China Garden":{"tags":{"name":"China Garden","amenity":"restaurant"},"name":"China Garden","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Vapiano":{"tags":{"name":"Vapiano","amenity":"restaurant"},"name":"Vapiano","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mamma Mia":{"tags":{"name":"Mamma Mia","amenity":"restaurant"},"name":"Mamma Mia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Schwarzer Adler":{"tags":{"name":"Schwarzer Adler","amenity":"restaurant"},"name":"Schwarzer Adler","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/IHOP":{"tags":{"name":"IHOP","amenity":"restaurant"},"name":"IHOP","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Chili's":{"tags":{"name":"Chili's","amenity":"restaurant"},"name":"Chili's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Asia":{"tags":{"name":"Asia","amenity":"restaurant"},"name":"Asia","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Olive Garden":{"tags":{"name":"Olive Garden","amenity":"restaurant"},"name":"Olive Garden","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/TGI Friday's":{"tags":{"name":"TGI Friday's","amenity":"restaurant"},"name":"TGI Friday's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Friendly's":{"tags":{"name":"Friendly's","amenity":"restaurant"},"name":"Friendly's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Buffalo Grill":{"tags":{"name":"Buffalo Grill","amenity":"restaurant"},"name":"Buffalo Grill","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Texas Roadhouse":{"tags":{"name":"Texas Roadhouse","amenity":"restaurant"},"name":"Texas Roadhouse","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ガスト":{"tags":{"name":"ガスト","name:en":"Gusto","amenity":"restaurant"},"name":"ガスト","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Sakura":{"tags":{"name":"Sakura","amenity":"restaurant"},"name":"Sakura","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mensa":{"tags":{"name":"Mensa","amenity":"restaurant"},"name":"Mensa","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/The Keg":{"tags":{"name":"The Keg","amenity":"restaurant"},"name":"The Keg","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/サイゼリヤ":{"tags":{"name":"サイゼリヤ","amenity":"restaurant"},"name":"サイゼリヤ","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/La Strada":{"tags":{"name":"La Strada","amenity":"restaurant"},"name":"La Strada","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Village Inn":{"tags":{"name":"Village Inn","amenity":"restaurant"},"name":"Village Inn","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Buffalo Wild Wings":{"tags":{"name":"Buffalo Wild Wings","amenity":"restaurant"},"name":"Buffalo Wild Wings","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Peking":{"tags":{"name":"Peking","amenity":"restaurant"},"name":"Peking","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Round Table Pizza":{"tags":{"name":"Round Table Pizza","amenity":"restaurant"},"name":"Round Table Pizza","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/California Pizza Kitchen":{"tags":{"name":"California Pizza Kitchen","amenity":"restaurant"},"name":"California Pizza Kitchen","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Якитория":{"tags":{"name":"Якитория","amenity":"restaurant"},"name":"Якитория","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Golden Corral":{"tags":{"name":"Golden Corral","amenity":"restaurant"},"name":"Golden Corral","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Perkins":{"tags":{"name":"Perkins","amenity":"restaurant"},"name":"Perkins","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Ruby Tuesday":{"tags":{"name":"Ruby Tuesday","amenity":"restaurant"},"name":"Ruby Tuesday","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Shari's":{"tags":{"name":"Shari's","amenity":"restaurant"},"name":"Shari's","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Bob Evans":{"tags":{"name":"Bob Evans","amenity":"restaurant"},"name":"Bob Evans","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/바다횟집 (Bada Fish Restaurant)":{"tags":{"name":"바다횟집 (Bada Fish Restaurant)","amenity":"restaurant"},"name":"바다횟집 (Bada Fish Restaurant)","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Mang Inasal":{"tags":{"name":"Mang Inasal","amenity":"restaurant"},"name":"Mang Inasal","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Евразия":{"tags":{"name":"Евразия","amenity":"restaurant"},"name":"Евразия","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/ジョナサン":{"tags":{"name":"ジョナサン","amenity":"restaurant"},"name":"ジョナサン","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/restaurant/Longhorn Steakhouse":{"tags":{"name":"Longhorn Steakhouse","amenity":"restaurant"},"name":"Longhorn Steakhouse","icon":"restaurant","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","capacity","takeaway","delivery","smoking","outdoor_seating"],"suggestion":true},"amenity/bank/Chase":{"tags":{"name":"Chase","amenity":"bank"},"name":"Chase","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commonwealth Bank":{"tags":{"name":"Commonwealth Bank","amenity":"bank"},"name":"Commonwealth Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Citibank":{"tags":{"name":"Citibank","amenity":"bank"},"name":"Citibank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HSBC":{"tags":{"name":"HSBC","amenity":"bank"},"name":"HSBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Barclays":{"tags":{"name":"Barclays","amenity":"bank"},"name":"Barclays","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Westpac":{"tags":{"name":"Westpac","amenity":"bank"},"name":"Westpac","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/NAB":{"tags":{"name":"NAB","amenity":"bank"},"name":"NAB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ANZ":{"tags":{"name":"ANZ","amenity":"bank"},"name":"ANZ","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Lloyds Bank":{"tags":{"name":"Lloyds Bank","amenity":"bank"},"name":"Lloyds Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Landbank":{"tags":{"name":"Landbank","amenity":"bank"},"name":"Landbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparkasse":{"tags":{"name":"Sparkasse","amenity":"bank"},"name":"Sparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UCPB":{"tags":{"name":"UCPB","amenity":"bank"},"name":"UCPB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PNB":{"tags":{"name":"PNB","amenity":"bank"},"name":"PNB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Metrobank":{"tags":{"name":"Metrobank","amenity":"bank"},"name":"Metrobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BDO":{"tags":{"name":"BDO","amenity":"bank"},"name":"BDO","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Volksbank":{"tags":{"name":"Volksbank","amenity":"bank"},"name":"Volksbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BPI":{"tags":{"name":"BPI","amenity":"bank"},"name":"BPI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Postbank":{"tags":{"name":"Postbank","amenity":"bank"},"name":"Postbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/NatWest":{"tags":{"name":"NatWest","amenity":"bank"},"name":"NatWest","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Raiffeisenbank":{"tags":{"name":"Raiffeisenbank","amenity":"bank"},"name":"Raiffeisenbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Yorkshire Bank":{"tags":{"name":"Yorkshire Bank","amenity":"bank"},"name":"Yorkshire Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ABSA":{"tags":{"name":"ABSA","amenity":"bank"},"name":"ABSA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Standard Bank":{"tags":{"name":"Standard Bank","amenity":"bank"},"name":"Standard Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/FNB":{"tags":{"name":"FNB","amenity":"bank"},"name":"FNB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Deutsche Bank":{"tags":{"name":"Deutsche Bank","amenity":"bank"},"name":"Deutsche Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SEB":{"tags":{"name":"SEB","amenity":"bank"},"name":"SEB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commerzbank":{"tags":{"name":"Commerzbank","amenity":"bank"},"name":"Commerzbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Targobank":{"tags":{"name":"Targobank","amenity":"bank"},"name":"Targobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ABN AMRO":{"tags":{"name":"ABN AMRO","amenity":"bank"},"name":"ABN AMRO","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Handelsbanken":{"tags":{"name":"Handelsbanken","amenity":"bank"},"name":"Handelsbanken","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Swedbank":{"tags":{"name":"Swedbank","amenity":"bank"},"name":"Swedbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kreissparkasse":{"tags":{"name":"Kreissparkasse","amenity":"bank"},"name":"Kreissparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UniCredit Bank":{"tags":{"name":"UniCredit Bank","amenity":"bank"},"name":"UniCredit Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Monte dei Paschi di Siena":{"tags":{"name":"Monte dei Paschi di Siena","amenity":"bank"},"name":"Monte dei Paschi di Siena","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Rural":{"tags":{"name":"Caja Rural","amenity":"bank"},"name":"Caja Rural","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Dresdner Bank":{"tags":{"name":"Dresdner Bank","amenity":"bank"},"name":"Dresdner Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparda-Bank":{"tags":{"name":"Sparda-Bank","amenity":"bank"},"name":"Sparda-Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/VÚB":{"tags":{"name":"VÚB","amenity":"bank"},"name":"VÚB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Slovenská sporiteľňa":{"tags":{"name":"Slovenská sporiteľňa","amenity":"bank"},"name":"Slovenská sporiteľňa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Montreal":{"tags":{"name":"Bank of Montreal","amenity":"bank"},"name":"Bank of Montreal","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/KBC":{"tags":{"name":"KBC","amenity":"bank"},"name":"KBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Royal Bank of Scotland":{"tags":{"name":"Royal Bank of Scotland","amenity":"bank"},"name":"Royal Bank of Scotland","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TSB":{"tags":{"name":"TSB","amenity":"bank"},"name":"TSB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/US Bank":{"tags":{"name":"US Bank","amenity":"bank"},"name":"US Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HypoVereinsbank":{"tags":{"name":"HypoVereinsbank","amenity":"bank"},"name":"HypoVereinsbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Austria":{"tags":{"name":"Bank Austria","amenity":"bank"},"name":"Bank Austria","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ING":{"tags":{"name":"ING","amenity":"bank"},"name":"ING","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Erste Bank":{"tags":{"name":"Erste Bank","amenity":"bank"},"name":"Erste Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIBC":{"tags":{"name":"CIBC","amenity":"bank"},"name":"CIBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Scotiabank":{"tags":{"name":"Scotiabank","amenity":"bank"},"name":"Scotiabank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caisse d'Épargne":{"tags":{"name":"Caisse d'Épargne","amenity":"bank"},"name":"Caisse d'Épargne","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander":{"tags":{"name":"Santander","amenity":"bank"},"name":"Santander","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Scotland":{"tags":{"name":"Bank of Scotland","amenity":"bank"},"name":"Bank of Scotland","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TD Canada Trust":{"tags":{"name":"TD Canada Trust","amenity":"bank"},"name":"TD Canada Trust","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BMO":{"tags":{"name":"BMO","amenity":"bank"},"name":"BMO","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Danske Bank":{"tags":{"name":"Danske Bank","amenity":"bank"},"name":"Danske Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/OTP":{"tags":{"name":"OTP","amenity":"bank"},"name":"OTP","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit Agricole":{"tags":{"name":"Crédit Agricole","amenity":"bank"},"name":"Crédit Agricole","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/LCL":{"tags":{"name":"LCL","amenity":"bank"},"name":"LCL","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/VR-Bank":{"tags":{"name":"VR-Bank","amenity":"bank"},"name":"VR-Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ČSOB":{"tags":{"name":"ČSOB","amenity":"bank"},"name":"ČSOB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Česká spořitelna":{"tags":{"name":"Česká spořitelna","amenity":"bank"},"name":"Česká spořitelna","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNP":{"tags":{"name":"BNP","amenity":"bank"},"name":"BNP","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Royal Bank":{"tags":{"name":"Royal Bank","amenity":"bank"},"name":"Royal Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Nationwide":{"tags":{"name":"Nationwide","amenity":"bank"},"name":"Nationwide","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Halifax":{"tags":{"name":"Halifax","amenity":"bank"},"name":"Halifax","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BAWAG PSK":{"tags":{"name":"BAWAG PSK","amenity":"bank"},"name":"BAWAG PSK","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/National Bank":{"tags":{"name":"National Bank","amenity":"bank"},"name":"National Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Nedbank":{"tags":{"name":"Nedbank","amenity":"bank"},"name":"Nedbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/First National Bank":{"tags":{"name":"First National Bank","amenity":"bank"},"name":"First National Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Nordea":{"tags":{"name":"Nordea","amenity":"bank"},"name":"Nordea","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Rabobank":{"tags":{"name":"Rabobank","amenity":"bank"},"name":"Rabobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparkasse KölnBonn":{"tags":{"name":"Sparkasse KölnBonn","amenity":"bank"},"name":"Sparkasse KölnBonn","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Tatra banka":{"tags":{"name":"Tatra banka","amenity":"bank"},"name":"Tatra banka","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Berliner Sparkasse":{"tags":{"name":"Berliner Sparkasse","amenity":"bank"},"name":"Berliner Sparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Berliner Volksbank":{"tags":{"name":"Berliner Volksbank","amenity":"bank"},"name":"Berliner Volksbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Wells Fargo":{"tags":{"name":"Wells Fargo","amenity":"bank"},"name":"Wells Fargo","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credit Suisse":{"tags":{"name":"Credit Suisse","amenity":"bank"},"name":"Credit Suisse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Société Générale":{"tags":{"name":"Société Générale","amenity":"bank"},"name":"Société Générale","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Osuuspankki":{"tags":{"name":"Osuuspankki","amenity":"bank"},"name":"Osuuspankki","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sparkasse Aachen":{"tags":{"name":"Sparkasse Aachen","amenity":"bank"},"name":"Sparkasse Aachen","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Hamburger Sparkasse":{"tags":{"name":"Hamburger Sparkasse","amenity":"bank"},"name":"Hamburger Sparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cassa di Risparmio del Veneto":{"tags":{"name":"Cassa di Risparmio del Veneto","amenity":"bank"},"name":"Cassa di Risparmio del Veneto","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNP Paribas":{"tags":{"name":"BNP Paribas","amenity":"bank"},"name":"BNP Paribas","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banque Populaire":{"tags":{"name":"Banque Populaire","amenity":"bank"},"name":"Banque Populaire","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNP Paribas Fortis":{"tags":{"name":"BNP Paribas Fortis","amenity":"bank"},"name":"BNP Paribas Fortis","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Popular":{"tags":{"name":"Banco Popular","amenity":"bank"},"name":"Banco Popular","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancaja":{"tags":{"name":"Bancaja","amenity":"bank"},"name":"Bancaja","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banesto":{"tags":{"name":"Banesto","amenity":"bank"},"name":"Banesto","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/La Caixa":{"tags":{"name":"La Caixa","amenity":"bank"},"name":"La Caixa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander Consumer Bank":{"tags":{"name":"Santander Consumer Bank","amenity":"bank"},"name":"Santander Consumer Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BRD":{"tags":{"name":"BRD","amenity":"bank"},"name":"BRD","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCR":{"tags":{"name":"BCR","amenity":"bank"},"name":"BCR","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Transilvania":{"tags":{"name":"Banca Transilvania","amenity":"bank"},"name":"Banca Transilvania","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BW-Bank":{"tags":{"name":"BW-Bank","amenity":"bank"},"name":"BW-Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Komerční banka":{"tags":{"name":"Komerční banka","amenity":"bank"},"name":"Komerční banka","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Pastor":{"tags":{"name":"Banco Pastor","amenity":"bank"},"name":"Banco Pastor","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Stadtsparkasse":{"tags":{"name":"Stadtsparkasse","amenity":"bank"},"name":"Stadtsparkasse","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ulster Bank":{"tags":{"name":"Ulster Bank","amenity":"bank"},"name":"Ulster Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Sberbank":{"tags":{"name":"Sberbank","amenity":"bank"},"name":"Sberbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CIC":{"tags":{"name":"CIC","amenity":"bank"},"name":"CIC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancpost":{"tags":{"name":"Bancpost","amenity":"bank"},"name":"Bancpost","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Madrid":{"tags":{"name":"Caja Madrid","amenity":"bank"},"name":"Caja Madrid","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Maybank":{"tags":{"name":"Maybank","amenity":"bank"},"name":"Maybank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国银行":{"tags":{"name":"中国银行","amenity":"bank"},"name":"中国银行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Unicredit Banca":{"tags":{"name":"Unicredit Banca","amenity":"bank"},"name":"Unicredit Banca","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit Mutuel":{"tags":{"name":"Crédit Mutuel","amenity":"bank"},"name":"Crédit Mutuel","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBVA":{"tags":{"name":"BBVA","amenity":"bank"},"name":"BBVA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Intesa San Paolo":{"tags":{"name":"Intesa San Paolo","amenity":"bank"},"name":"Intesa San Paolo","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/TD Bank":{"tags":{"name":"TD Bank","amenity":"bank"},"name":"TD Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Belfius":{"tags":{"name":"Belfius","amenity":"bank"},"name":"Belfius","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of America":{"tags":{"name":"Bank of America","amenity":"bank"},"name":"Bank of America","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RBC":{"tags":{"name":"RBC","amenity":"bank"},"name":"RBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Alpha Bank":{"tags":{"name":"Alpha Bank","amenity":"bank"},"name":"Alpha Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Сбербанк":{"tags":{"name":"Сбербанк","amenity":"bank"},"name":"Сбербанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Россельхозбанк":{"tags":{"name":"Россельхозбанк","amenity":"bank"},"name":"Россельхозбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit du Nord":{"tags":{"name":"Crédit du Nord","amenity":"bank"},"name":"Crédit du Nord","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BancoEstado":{"tags":{"name":"BancoEstado","amenity":"bank"},"name":"BancoEstado","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Millennium Bank":{"tags":{"name":"Millennium Bank","amenity":"bank"},"name":"Millennium Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/State Bank of India":{"tags":{"name":"State Bank of India","amenity":"bank"},"name":"State Bank of India","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Беларусбанк":{"tags":{"name":"Беларусбанк","amenity":"bank"},"name":"Беларусбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ING Bank Śląski":{"tags":{"name":"ING Bank Śląski","amenity":"bank"},"name":"ING Bank Śląski","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caixa Geral de Depósitos":{"tags":{"name":"Caixa Geral de Depósitos","amenity":"bank"},"name":"Caixa Geral de Depósitos","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Kreissparkasse Köln":{"tags":{"name":"Kreissparkasse Köln","amenity":"bank"},"name":"Kreissparkasse Köln","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco BCI":{"tags":{"name":"Banco BCI","amenity":"bank"},"name":"Banco BCI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Chile":{"tags":{"name":"Banco de Chile","amenity":"bank"},"name":"Banco de Chile","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ВТБ24":{"tags":{"name":"ВТБ24","amenity":"bank"},"name":"ВТБ24","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/UBS":{"tags":{"name":"UBS","amenity":"bank"},"name":"UBS","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PKO BP":{"tags":{"name":"PKO BP","amenity":"bank"},"name":"PKO BP","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Chinabank":{"tags":{"name":"Chinabank","amenity":"bank"},"name":"Chinabank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PSBank":{"tags":{"name":"PSBank","amenity":"bank"},"name":"PSBank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Union Bank":{"tags":{"name":"Union Bank","amenity":"bank"},"name":"Union Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/China Bank":{"tags":{"name":"China Bank","amenity":"bank"},"name":"China Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RCBC":{"tags":{"name":"RCBC","amenity":"bank"},"name":"RCBC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Unicaja":{"tags":{"name":"Unicaja","amenity":"bank"},"name":"Unicaja","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BBK":{"tags":{"name":"BBK","amenity":"bank"},"name":"BBK","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ibercaja":{"tags":{"name":"Ibercaja","amenity":"bank"},"name":"Ibercaja","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/RBS":{"tags":{"name":"RBS","amenity":"bank"},"name":"RBS","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Commercial Bank of Ceylon PLC":{"tags":{"name":"Commercial Bank of Ceylon PLC","amenity":"bank"},"name":"Commercial Bank of Ceylon PLC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of Ireland":{"tags":{"name":"Bank of Ireland","amenity":"bank"},"name":"Bank of Ireland","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BNL":{"tags":{"name":"BNL","amenity":"bank"},"name":"BNL","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Santander":{"tags":{"name":"Banco Santander","amenity":"bank"},"name":"Banco Santander","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Itaú":{"tags":{"name":"Banco Itaú","amenity":"bank"},"name":"Banco Itaú","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/AIB":{"tags":{"name":"AIB","amenity":"bank"},"name":"AIB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BZ WBK":{"tags":{"name":"BZ WBK","amenity":"bank"},"name":"BZ WBK","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco do Brasil":{"tags":{"name":"Banco do Brasil","amenity":"bank"},"name":"Banco do Brasil","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caixa Econômica Federal":{"tags":{"name":"Caixa Econômica Federal","amenity":"bank"},"name":"Caixa Econômica Federal","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Fifth Third Bank":{"tags":{"name":"Fifth Third Bank","amenity":"bank"},"name":"Fifth Third Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Popolare di Vicenza":{"tags":{"name":"Banca Popolare di Vicenza","amenity":"bank"},"name":"Banca Popolare di Vicenza","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Wachovia":{"tags":{"name":"Wachovia","amenity":"bank"},"name":"Wachovia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/OLB":{"tags":{"name":"OLB","amenity":"bank"},"name":"OLB","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/みずほ銀行":{"tags":{"name":"みずほ銀行","amenity":"bank"},"name":"みずほ銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BES":{"tags":{"name":"BES","amenity":"bank"},"name":"BES","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ICICI Bank":{"tags":{"name":"ICICI Bank","amenity":"bank"},"name":"ICICI Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/HDFC Bank":{"tags":{"name":"HDFC Bank","amenity":"bank"},"name":"HDFC Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/La Banque Postale":{"tags":{"name":"La Banque Postale","amenity":"bank"},"name":"La Banque Postale","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Pekao SA":{"tags":{"name":"Pekao SA","amenity":"bank"},"name":"Pekao SA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Oberbank":{"tags":{"name":"Oberbank","amenity":"bank"},"name":"Oberbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bradesco":{"tags":{"name":"Bradesco","amenity":"bank"},"name":"Bradesco","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Oldenburgische Landesbank":{"tags":{"name":"Oldenburgische Landesbank","amenity":"bank"},"name":"Oldenburgische Landesbank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bendigo Bank":{"tags":{"name":"Bendigo Bank","amenity":"bank"},"name":"Bendigo Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Argenta":{"tags":{"name":"Argenta","amenity":"bank"},"name":"Argenta","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/AXA":{"tags":{"name":"AXA","amenity":"bank"},"name":"AXA","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Axis Bank":{"tags":{"name":"Axis Bank","amenity":"bank"},"name":"Axis Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Nación":{"tags":{"name":"Banco Nación","amenity":"bank"},"name":"Banco Nación","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/GE Money Bank":{"tags":{"name":"GE Money Bank","amenity":"bank"},"name":"GE Money Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Альфа-Банк":{"tags":{"name":"Альфа-Банк","amenity":"bank"},"name":"Альфа-Банк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Белагропромбанк":{"tags":{"name":"Белагропромбанк","amenity":"bank"},"name":"Белагропромбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Círculo":{"tags":{"name":"Caja Círculo","amenity":"bank"},"name":"Caja Círculo","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Galicia":{"tags":{"name":"Banco Galicia","amenity":"bank"},"name":"Banco Galicia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Eurobank":{"tags":{"name":"Eurobank","amenity":"bank"},"name":"Eurobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banca Intesa":{"tags":{"name":"Banca Intesa","amenity":"bank"},"name":"Banca Intesa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Canara Bank":{"tags":{"name":"Canara Bank","amenity":"bank"},"name":"Canara Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cajamar":{"tags":{"name":"Cajamar","amenity":"bank"},"name":"Cajamar","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banamex":{"tags":{"name":"Banamex","amenity":"bank"},"name":"Banamex","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Crédit Mutuel de Bretagne":{"tags":{"name":"Crédit Mutuel de Bretagne","amenity":"bank"},"name":"Crédit Mutuel de Bretagne","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Davivienda":{"tags":{"name":"Davivienda","amenity":"bank"},"name":"Davivienda","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Spółdzielczy":{"tags":{"name":"Bank Spółdzielczy","amenity":"bank"},"name":"Bank Spółdzielczy","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Credit Agricole":{"tags":{"name":"Credit Agricole","amenity":"bank"},"name":"Credit Agricole","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bankinter":{"tags":{"name":"Bankinter","amenity":"bank"},"name":"Bankinter","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banque Nationale":{"tags":{"name":"Banque Nationale","amenity":"bank"},"name":"Banque Nationale","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank of the West":{"tags":{"name":"Bank of the West","amenity":"bank"},"name":"Bank of the West","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Key Bank":{"tags":{"name":"Key Bank","amenity":"bank"},"name":"Key Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Western Union":{"tags":{"name":"Western Union","amenity":"bank"},"name":"Western Union","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Citizens Bank":{"tags":{"name":"Citizens Bank","amenity":"bank"},"name":"Citizens Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ПриватБанк":{"tags":{"name":"ПриватБанк","amenity":"bank"},"name":"ПриватБанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Security Bank":{"tags":{"name":"Security Bank","amenity":"bank"},"name":"Security Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Millenium":{"tags":{"name":"Millenium","amenity":"bank"},"name":"Millenium","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bankia":{"tags":{"name":"Bankia","amenity":"bank"},"name":"Bankia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/三菱東京UFJ銀行":{"tags":{"name":"三菱東京UFJ銀行","amenity":"bank"},"name":"三菱東京UFJ銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caixa":{"tags":{"name":"Caixa","amenity":"bank"},"name":"Caixa","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Costa Rica":{"tags":{"name":"Banco de Costa Rica","amenity":"bank"},"name":"Banco de Costa Rica","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SunTrust Bank":{"tags":{"name":"SunTrust Bank","amenity":"bank"},"name":"SunTrust Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Itaú":{"tags":{"name":"Itaú","amenity":"bank"},"name":"Itaú","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PBZ":{"tags":{"name":"PBZ","amenity":"bank"},"name":"PBZ","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/中国工商银行":{"tags":{"name":"中国工商银行","amenity":"bank"},"name":"中国工商银行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancolombia":{"tags":{"name":"Bancolombia","amenity":"bank"},"name":"Bancolombia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Райффайзен Банк Аваль":{"tags":{"name":"Райффайзен Банк Аваль","amenity":"bank"},"name":"Райффайзен Банк Аваль","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bancomer":{"tags":{"name":"Bancomer","amenity":"bank"},"name":"Bancomer","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banorte":{"tags":{"name":"Banorte","amenity":"bank"},"name":"Banorte","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Alior Bank":{"tags":{"name":"Alior Bank","amenity":"bank"},"name":"Alior Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BOC":{"tags":{"name":"BOC","amenity":"bank"},"name":"BOC","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Банк Москвы":{"tags":{"name":"Банк Москвы","amenity":"bank"},"name":"Банк Москвы","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ВТБ":{"tags":{"name":"ВТБ","amenity":"bank"},"name":"ВТБ","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Getin Bank":{"tags":{"name":"Getin Bank","amenity":"bank"},"name":"Getin Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja Duero":{"tags":{"name":"Caja Duero","amenity":"bank"},"name":"Caja Duero","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Regions Bank":{"tags":{"name":"Regions Bank","amenity":"bank"},"name":"Regions Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Росбанк":{"tags":{"name":"Росбанк","amenity":"bank"},"name":"Росбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Estado":{"tags":{"name":"Banco Estado","amenity":"bank"},"name":"Banco Estado","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BCI":{"tags":{"name":"BCI","amenity":"bank"},"name":"BCI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/SunTrust":{"tags":{"name":"SunTrust","amenity":"bank"},"name":"SunTrust","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/PNC Bank":{"tags":{"name":"PNC Bank","amenity":"bank"},"name":"PNC Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/신한은행":{"tags":{"name":"신한은행","name:en":"Sinhan Bank","amenity":"bank"},"name":"신한은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/우리은행":{"tags":{"name":"우리은행","name:en":"Uri Bank","amenity":"bank"},"name":"우리은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/국민은행":{"tags":{"name":"국민은행","name:en":"Gungmin Bank","amenity":"bank"},"name":"국민은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/중소기업은행":{"tags":{"name":"중소기업은행","name:en":"Industrial Bank of Korea","amenity":"bank"},"name":"중소기업은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/광주은행":{"tags":{"name":"광주은행","name:en":"Gwangju Bank","amenity":"bank"},"name":"광주은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Газпромбанк":{"tags":{"name":"Газпромбанк","amenity":"bank"},"name":"Газпромбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/M&T Bank":{"tags":{"name":"M&T Bank","amenity":"bank"},"name":"M&T Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Caja de Burgos":{"tags":{"name":"Caja de Burgos","amenity":"bank"},"name":"Caja de Burgos","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Santander Totta":{"tags":{"name":"Santander Totta","amenity":"bank"},"name":"Santander Totta","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/УкрСиббанк":{"tags":{"name":"УкрСиббанк","amenity":"bank"},"name":"УкрСиббанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ощадбанк":{"tags":{"name":"Ощадбанк","amenity":"bank"},"name":"Ощадбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Уралсиб":{"tags":{"name":"Уралсиб","amenity":"bank"},"name":"Уралсиб","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/りそな銀行":{"tags":{"name":"りそな銀行","name:en":"Mizuho Bank","amenity":"bank"},"name":"りそな銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Ecobank":{"tags":{"name":"Ecobank","amenity":"bank"},"name":"Ecobank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Cajero Automatico Bancared":{"tags":{"name":"Cajero Automatico Bancared","amenity":"bank"},"name":"Cajero Automatico Bancared","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Промсвязьбанк":{"tags":{"name":"Промсвязьбанк","amenity":"bank"},"name":"Промсвязьбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/三井住友銀行":{"tags":{"name":"三井住友銀行","amenity":"bank"},"name":"三井住友銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Provincia":{"tags":{"name":"Banco Provincia","amenity":"bank"},"name":"Banco Provincia","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/BB&T":{"tags":{"name":"BB&T","amenity":"bank"},"name":"BB&T","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Возрождение":{"tags":{"name":"Возрождение","amenity":"bank"},"name":"Возрождение","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Capital One":{"tags":{"name":"Capital One","amenity":"bank"},"name":"Capital One","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/横浜銀行":{"tags":{"name":"横浜銀行","amenity":"bank"},"name":"横浜銀行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank Mandiri":{"tags":{"name":"Bank Mandiri","amenity":"bank"},"name":"Bank Mandiri","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de la Nación":{"tags":{"name":"Banco de la Nación","amenity":"bank"},"name":"Banco de la Nación","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco G&T Continental":{"tags":{"name":"Banco G&T Continental","amenity":"bank"},"name":"Banco G&T Continental","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Peoples Bank":{"tags":{"name":"Peoples Bank","amenity":"bank"},"name":"Peoples Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/工商银行":{"tags":{"name":"工商银行","amenity":"bank"},"name":"工商银行","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Совкомбанк":{"tags":{"name":"Совкомбанк","amenity":"bank"},"name":"Совкомбанк","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Provincial":{"tags":{"name":"Provincial","amenity":"bank"},"name":"Provincial","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco de Desarrollo Banrural":{"tags":{"name":"Banco de Desarrollo Banrural","amenity":"bank"},"name":"Banco de Desarrollo Banrural","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banco Bradesco":{"tags":{"name":"Banco Bradesco","amenity":"bank"},"name":"Banco Bradesco","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bicentenario":{"tags":{"name":"Bicentenario","amenity":"bank"},"name":"Bicentenario","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/ლიბერთი ბანკი":{"tags":{"name":"ლიბერთი ბანკი","name:en":"Liberty Bank","amenity":"bank"},"name":"ლიბერთი ბანკი","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Banesco":{"tags":{"name":"Banesco","amenity":"bank"},"name":"Banesco","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Mercantil":{"tags":{"name":"Mercantil","amenity":"bank"},"name":"Mercantil","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Bank BRI":{"tags":{"name":"Bank BRI","amenity":"bank"},"name":"Bank BRI","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/Del Tesoro":{"tags":{"name":"Del Tesoro","amenity":"bank"},"name":"Del Tesoro","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/하나은행":{"tags":{"name":"하나은행","amenity":"bank"},"name":"하나은행","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/CityCommerce Bank":{"tags":{"name":"CityCommerce Bank","amenity":"bank"},"name":"CityCommerce Bank","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/bank/De Venezuela":{"tags":{"name":"De Venezuela","amenity":"bank"},"name":"De Venezuela","icon":"bank","geometry":["point","area"],"fields":["atm","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/car_rental/Europcar":{"tags":{"name":"Europcar","amenity":"car_rental"},"name":"Europcar","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Budget":{"tags":{"name":"Budget","amenity":"car_rental"},"name":"Budget","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Sixt":{"tags":{"name":"Sixt","amenity":"car_rental"},"name":"Sixt","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Avis":{"tags":{"name":"Avis","amenity":"car_rental"},"name":"Avis","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Hertz":{"tags":{"name":"Hertz","amenity":"car_rental"},"name":"Hertz","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/Enterprise":{"tags":{"name":"Enterprise","amenity":"car_rental"},"name":"Enterprise","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/car_rental/stadtmobil CarSharing-Station":{"tags":{"name":"stadtmobil CarSharing-Station","amenity":"car_rental"},"name":"stadtmobil CarSharing-Station","icon":"car","geometry":["point","area"],"fields":["operator"],"suggestion":true},"amenity/pharmacy/Rowlands Pharmacy":{"tags":{"name":"Rowlands Pharmacy","amenity":"pharmacy"},"name":"Rowlands Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Boots":{"tags":{"name":"Boots","amenity":"pharmacy"},"name":"Boots","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Marien-Apotheke":{"tags":{"name":"Marien-Apotheke","amenity":"pharmacy"},"name":"Marien-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Mercury Drug":{"tags":{"name":"Mercury Drug","amenity":"pharmacy"},"name":"Mercury Drug","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Löwen-Apotheke":{"tags":{"name":"Löwen-Apotheke","amenity":"pharmacy"},"name":"Löwen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Superdrug":{"tags":{"name":"Superdrug","amenity":"pharmacy"},"name":"Superdrug","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Sonnen-Apotheke":{"tags":{"name":"Sonnen-Apotheke","amenity":"pharmacy"},"name":"Sonnen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rathaus-Apotheke":{"tags":{"name":"Rathaus-Apotheke","amenity":"pharmacy"},"name":"Rathaus-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Engel-Apotheke":{"tags":{"name":"Engel-Apotheke","amenity":"pharmacy"},"name":"Engel-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Hirsch-Apotheke":{"tags":{"name":"Hirsch-Apotheke","amenity":"pharmacy"},"name":"Hirsch-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Stern-Apotheke":{"tags":{"name":"Stern-Apotheke","amenity":"pharmacy"},"name":"Stern-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Lloyds Pharmacy":{"tags":{"name":"Lloyds Pharmacy","amenity":"pharmacy"},"name":"Lloyds Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rosen-Apotheke":{"tags":{"name":"Rosen-Apotheke","amenity":"pharmacy"},"name":"Rosen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Stadt-Apotheke":{"tags":{"name":"Stadt-Apotheke","amenity":"pharmacy"},"name":"Stadt-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Markt-Apotheke":{"tags":{"name":"Markt-Apotheke","amenity":"pharmacy"},"name":"Markt-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека":{"tags":{"name":"Аптека","amenity":"pharmacy"},"name":"Аптека","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmasave":{"tags":{"name":"Pharmasave","amenity":"pharmacy"},"name":"Pharmasave","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Brunnen-Apotheke":{"tags":{"name":"Brunnen-Apotheke","amenity":"pharmacy"},"name":"Brunnen-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Shoppers Drug Mart":{"tags":{"name":"Shoppers Drug Mart","amenity":"pharmacy"},"name":"Shoppers Drug Mart","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apotheke am Markt":{"tags":{"name":"Apotheke am Markt","amenity":"pharmacy"},"name":"Apotheke am Markt","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Alte Apotheke":{"tags":{"name":"Alte Apotheke","amenity":"pharmacy"},"name":"Alte Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Neue Apotheke":{"tags":{"name":"Neue Apotheke","amenity":"pharmacy"},"name":"Neue Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Gintarinė vaistinė":{"tags":{"name":"Gintarinė vaistinė","amenity":"pharmacy"},"name":"Gintarinė vaistinė","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rats-Apotheke":{"tags":{"name":"Rats-Apotheke","amenity":"pharmacy"},"name":"Rats-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Adler Apotheke":{"tags":{"name":"Adler Apotheke","amenity":"pharmacy"},"name":"Adler Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmacie Centrale":{"tags":{"name":"Pharmacie Centrale","amenity":"pharmacy"},"name":"Pharmacie Centrale","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Walgreens":{"tags":{"name":"Walgreens","amenity":"pharmacy"},"name":"Walgreens","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Rite Aid":{"tags":{"name":"Rite Aid","amenity":"pharmacy"},"name":"Rite Aid","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apotheke":{"tags":{"name":"Apotheke","amenity":"pharmacy"},"name":"Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Linden-Apotheke":{"tags":{"name":"Linden-Apotheke","amenity":"pharmacy"},"name":"Linden-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Bahnhof-Apotheke":{"tags":{"name":"Bahnhof-Apotheke","amenity":"pharmacy"},"name":"Bahnhof-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Burg-Apotheke":{"tags":{"name":"Burg-Apotheke","amenity":"pharmacy"},"name":"Burg-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Jean Coutu":{"tags":{"name":"Jean Coutu","amenity":"pharmacy"},"name":"Jean Coutu","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Pharmaprix":{"tags":{"name":"Pharmaprix","amenity":"pharmacy"},"name":"Pharmaprix","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Ahumada":{"tags":{"name":"Farmacias Ahumada","amenity":"pharmacy"},"name":"Farmacias Ahumada","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacia Comunale":{"tags":{"name":"Farmacia Comunale","amenity":"pharmacy"},"name":"Farmacia Comunale","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias Cruz Verde":{"tags":{"name":"Farmacias Cruz Verde","amenity":"pharmacy"},"name":"Farmacias Cruz Verde","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Cruz Verde":{"tags":{"name":"Cruz Verde","amenity":"pharmacy"},"name":"Cruz Verde","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Hubertus Apotheke":{"tags":{"name":"Hubertus Apotheke","amenity":"pharmacy"},"name":"Hubertus Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/CVS":{"tags":{"name":"CVS","amenity":"pharmacy"},"name":"CVS","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacias SalcoBrand":{"tags":{"name":"Farmacias SalcoBrand","amenity":"pharmacy"},"name":"Farmacias SalcoBrand","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармация":{"tags":{"name":"Фармация","amenity":"pharmacy"},"name":"Фармация","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Bären-Apotheke":{"tags":{"name":"Bären-Apotheke","amenity":"pharmacy"},"name":"Bären-Apotheke","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Clicks":{"tags":{"name":"Clicks","amenity":"pharmacy"},"name":"Clicks","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/セイジョー":{"tags":{"name":"セイジョー","amenity":"pharmacy"},"name":"セイジョー","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/マツモトキヨシ":{"tags":{"name":"マツモトキヨシ","amenity":"pharmacy"},"name":"マツモトキヨシ","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Dr. Max":{"tags":{"name":"Dr. Max","amenity":"pharmacy"},"name":"Dr. Max","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Вита":{"tags":{"name":"Вита","amenity":"pharmacy"},"name":"Вита","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/サンドラッグ":{"tags":{"name":"サンドラッグ","amenity":"pharmacy"},"name":"サンドラッグ","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Apteka":{"tags":{"name":"Apteka","amenity":"pharmacy"},"name":"Apteka","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Первая помощь":{"tags":{"name":"Первая помощь","amenity":"pharmacy"},"name":"Первая помощь","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ригла":{"tags":{"name":"Ригла","amenity":"pharmacy"},"name":"Ригла","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Имплозия":{"tags":{"name":"Имплозия","amenity":"pharmacy"},"name":"Имплозия","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Kinney Drugs":{"tags":{"name":"Kinney Drugs","amenity":"pharmacy"},"name":"Kinney Drugs","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Классика":{"tags":{"name":"Классика","amenity":"pharmacy"},"name":"Классика","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ljekarna":{"tags":{"name":"Ljekarna","amenity":"pharmacy"},"name":"Ljekarna","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/SalcoBrand":{"tags":{"name":"SalcoBrand","amenity":"pharmacy"},"name":"SalcoBrand","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека 36,6":{"tags":{"name":"Аптека 36,6","amenity":"pharmacy"},"name":"Аптека 36,6","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармакор":{"tags":{"name":"Фармакор","amenity":"pharmacy"},"name":"Фармакор","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/スギ薬局":{"tags":{"name":"スギ薬局","amenity":"pharmacy"},"name":"スギ薬局","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптечный пункт":{"tags":{"name":"Аптечный пункт","amenity":"pharmacy"},"name":"Аптечный пункт","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Невис":{"tags":{"name":"Невис","amenity":"pharmacy"},"name":"Невис","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/トモズ (Tomod's)":{"tags":{"name":"トモズ (Tomod's)","amenity":"pharmacy"},"name":"トモズ (Tomod's)","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Eurovaistinė":{"tags":{"name":"Eurovaistinė","amenity":"pharmacy"},"name":"Eurovaistinė","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmacity":{"tags":{"name":"Farmacity","amenity":"pharmacy"},"name":"Farmacity","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/аптека":{"tags":{"name":"аптека","amenity":"pharmacy"},"name":"аптека","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/The Generics Pharmacy":{"tags":{"name":"The Generics Pharmacy","amenity":"pharmacy"},"name":"The Generics Pharmacy","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmatodo":{"tags":{"name":"Farmatodo","amenity":"pharmacy"},"name":"Farmatodo","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Duane Reade":{"tags":{"name":"Duane Reade","amenity":"pharmacy"},"name":"Duane Reade","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармленд":{"tags":{"name":"Фармленд","amenity":"pharmacy"},"name":"Фармленд","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ドラッグてらしま (Drug Terashima)":{"tags":{"name":"ドラッグてらしま (Drug Terashima)","amenity":"pharmacy"},"name":"ドラッグてらしま (Drug Terashima)","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Арніка":{"tags":{"name":"Арніка","amenity":"pharmacy"},"name":"Арніка","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ავერსი (Aversi)":{"tags":{"name":"ავერსი (Aversi)","amenity":"pharmacy"},"name":"ავერსი (Aversi)","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Farmahorro":{"tags":{"name":"Farmahorro","amenity":"pharmacy"},"name":"Farmahorro","icon":"pharmacy","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/cafe/Starbucks":{"tags":{"name":"Starbucks","cuisine":"coffee_shop","amenity":"cafe"},"name":"Starbucks","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafeteria":{"tags":{"name":"Cafeteria","amenity":"cafe"},"name":"Cafeteria","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Costa":{"tags":{"name":"Costa","amenity":"cafe"},"name":"Costa","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Caffè Nero":{"tags":{"name":"Caffè Nero","amenity":"cafe"},"name":"Caffè Nero","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Кафе":{"tags":{"name":"Кафе","amenity":"cafe"},"name":"Кафе","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Café Central":{"tags":{"name":"Café Central","amenity":"cafe"},"name":"Café Central","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Second Cup":{"tags":{"name":"Second Cup","amenity":"cafe"},"name":"Second Cup","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Dunkin Donuts":{"tags":{"name":"Dunkin Donuts","cuisine":"donut","amenity":"cafe"},"name":"Dunkin Donuts","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Espresso House":{"tags":{"name":"Espresso House","amenity":"cafe"},"name":"Espresso House","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Segafredo":{"tags":{"name":"Segafredo","amenity":"cafe"},"name":"Segafredo","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Coffee Time":{"tags":{"name":"Coffee Time","amenity":"cafe"},"name":"Coffee Time","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafe Coffee Day":{"tags":{"name":"Cafe Coffee Day","amenity":"cafe"},"name":"Cafe Coffee Day","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Eiscafe Venezia":{"tags":{"name":"Eiscafe Venezia","amenity":"cafe"},"name":"Eiscafe Venezia","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/スターバックス":{"tags":{"name":"スターバックス","name:en":"Starbucks","amenity":"cafe"},"name":"スターバックス","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Шоколадница":{"tags":{"name":"Шоколадница","amenity":"cafe"},"name":"Шоколадница","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Pret A Manger":{"tags":{"name":"Pret A Manger","amenity":"cafe"},"name":"Pret A Manger","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Столовая":{"tags":{"name":"Столовая","amenity":"cafe"},"name":"Столовая","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/ドトール":{"tags":{"name":"ドトール","name:en":"DOUTOR","amenity":"cafe"},"name":"ドトール","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Tchibo":{"tags":{"name":"Tchibo","amenity":"cafe"},"name":"Tchibo","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Кофе Хауз":{"tags":{"name":"Кофе Хауз","amenity":"cafe"},"name":"Кофе Хауз","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Caribou Coffee":{"tags":{"name":"Caribou Coffee","amenity":"cafe"},"name":"Caribou Coffee","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Уют":{"tags":{"name":"Уют","amenity":"cafe"},"name":"Уют","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Шашлычная":{"tags":{"name":"Шашлычная","amenity":"cafe"},"name":"Шашлычная","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/คาเฟ่ อเมซอน":{"tags":{"name":"คาเฟ่ อเมซอน","amenity":"cafe"},"name":"คาเฟ่ อเมซอน","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Traveler's Coffee":{"tags":{"name":"Traveler's Coffee","amenity":"cafe"},"name":"Traveler's Coffee","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/カフェ・ド・クリエ":{"tags":{"name":"カフェ・ド・クリエ","name:en":"Cafe de CRIE","amenity":"cafe"},"name":"カフェ・ド・クリエ","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"amenity/cafe/Cafe Amazon":{"tags":{"name":"Cafe Amazon","amenity":"cafe"},"name":"Cafe Amazon","icon":"cafe","geometry":["point","area"],"fields":["cuisine","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid","smoking","outdoor_seating"],"suggestion":true},"shop/supermarket/Budgens":{"tags":{"name":"Budgens","shop":"supermarket"},"name":"Budgens","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Morrisons":{"tags":{"name":"Morrisons","shop":"supermarket"},"name":"Morrisons","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Interspar":{"tags":{"name":"Interspar","shop":"supermarket"},"name":"Interspar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Merkur":{"tags":{"name":"Merkur","shop":"supermarket"},"name":"Merkur","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sainsbury's":{"tags":{"name":"Sainsbury's","shop":"supermarket"},"name":"Sainsbury's","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Lidl":{"tags":{"name":"Lidl","shop":"supermarket"},"name":"Lidl","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Edeka":{"tags":{"name":"Edeka","shop":"supermarket"},"name":"Edeka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coles":{"tags":{"name":"Coles","shop":"supermarket"},"name":"Coles","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Iceland":{"tags":{"name":"Iceland","shop":"supermarket"},"name":"Iceland","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop":{"tags":{"name":"Coop","shop":"supermarket"},"name":"Coop","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco":{"tags":{"name":"Tesco","shop":"supermarket"},"name":"Tesco","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Woolworths":{"tags":{"name":"Woolworths","shop":"supermarket"},"name":"Woolworths","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Zielpunkt":{"tags":{"name":"Zielpunkt","shop":"supermarket"},"name":"Zielpunkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Nahkauf":{"tags":{"name":"Nahkauf","shop":"supermarket"},"name":"Nahkauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Billa":{"tags":{"name":"Billa","shop":"supermarket"},"name":"Billa","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kaufland":{"tags":{"name":"Kaufland","shop":"supermarket"},"name":"Kaufland","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Plus":{"tags":{"name":"Plus","shop":"supermarket"},"name":"Plus","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ALDI":{"tags":{"name":"ALDI","shop":"supermarket"},"name":"ALDI","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Checkers":{"tags":{"name":"Checkers","shop":"supermarket"},"name":"Checkers","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco Metro":{"tags":{"name":"Tesco Metro","shop":"supermarket"},"name":"Tesco Metro","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/NP":{"tags":{"name":"NP","shop":"supermarket"},"name":"NP","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Penny":{"tags":{"name":"Penny","shop":"supermarket"},"name":"Penny","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Norma":{"tags":{"name":"Norma","shop":"supermarket"},"name":"Norma","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Asda":{"tags":{"name":"Asda","shop":"supermarket"},"name":"Asda","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Netto":{"tags":{"name":"Netto","shop":"supermarket"},"name":"Netto","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rewe":{"tags":{"name":"Rewe","shop":"supermarket"},"name":"Rewe","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Aldi Süd":{"tags":{"name":"Aldi Süd","shop":"supermarket"},"name":"Aldi Süd","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Real":{"tags":{"name":"Real","shop":"supermarket"},"name":"Real","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/King Soopers":{"tags":{"name":"King Soopers","shop":"supermarket"},"name":"King Soopers","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kiwi":{"tags":{"name":"Kiwi","shop":"supermarket"},"name":"Kiwi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pick n Pay":{"tags":{"name":"Pick n Pay","shop":"supermarket"},"name":"Pick n Pay","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ICA":{"tags":{"name":"ICA","shop":"supermarket"},"name":"ICA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tengelmann":{"tags":{"name":"Tengelmann","shop":"supermarket"},"name":"Tengelmann","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour":{"tags":{"name":"Carrefour","shop":"supermarket"},"name":"Carrefour","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Waitrose":{"tags":{"name":"Waitrose","shop":"supermarket"},"name":"Waitrose","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Spar":{"tags":{"name":"Spar","shop":"supermarket"},"name":"Spar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hofer":{"tags":{"name":"Hofer","shop":"supermarket"},"name":"Hofer","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/M-Preis":{"tags":{"name":"M-Preis","shop":"supermarket"},"name":"M-Preis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/tegut":{"tags":{"name":"tegut","shop":"supermarket"},"name":"tegut","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sainsbury's Local":{"tags":{"name":"Sainsbury's Local","shop":"supermarket"},"name":"Sainsbury's Local","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/E-Center":{"tags":{"name":"E-Center","shop":"supermarket"},"name":"E-Center","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Aldi Nord":{"tags":{"name":"Aldi Nord","shop":"supermarket"},"name":"Aldi Nord","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/nahkauf":{"tags":{"name":"nahkauf","shop":"supermarket"},"name":"nahkauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Meijer":{"tags":{"name":"Meijer","shop":"supermarket"},"name":"Meijer","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Safeway":{"tags":{"name":"Safeway","shop":"supermarket"},"name":"Safeway","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Costco":{"tags":{"name":"Costco","shop":"supermarket"},"name":"Costco","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albert":{"tags":{"name":"Albert","shop":"supermarket"},"name":"Albert","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Jumbo":{"tags":{"name":"Jumbo","shop":"supermarket"},"name":"Jumbo","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Shoprite":{"tags":{"name":"Shoprite","shop":"supermarket"},"name":"Shoprite","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/MPreis":{"tags":{"name":"MPreis","shop":"supermarket"},"name":"MPreis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Penny Market":{"tags":{"name":"Penny Market","shop":"supermarket"},"name":"Penny Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco Extra":{"tags":{"name":"Tesco Extra","shop":"supermarket"},"name":"Tesco Extra","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albert Heijn":{"tags":{"name":"Albert Heijn","shop":"supermarket"},"name":"Albert Heijn","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/IGA":{"tags":{"name":"IGA","shop":"supermarket"},"name":"IGA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Super U":{"tags":{"name":"Super U","shop":"supermarket"},"name":"Super U","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Metro":{"tags":{"name":"Metro","shop":"supermarket"},"name":"Metro","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Neukauf":{"tags":{"name":"Neukauf","shop":"supermarket"},"name":"Neukauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Migros":{"tags":{"name":"Migros","shop":"supermarket"},"name":"Migros","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Marktkauf":{"tags":{"name":"Marktkauf","shop":"supermarket"},"name":"Marktkauf","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Delikatesy Centrum":{"tags":{"name":"Delikatesy Centrum","shop":"supermarket"},"name":"Delikatesy Centrum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/C1000":{"tags":{"name":"C1000","shop":"supermarket"},"name":"C1000","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hoogvliet":{"tags":{"name":"Hoogvliet","shop":"supermarket"},"name":"Hoogvliet","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Food Basics":{"tags":{"name":"Food Basics","shop":"supermarket"},"name":"Food Basics","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Casino":{"tags":{"name":"Casino","shop":"supermarket"},"name":"Casino","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Penny Markt":{"tags":{"name":"Penny Markt","shop":"supermarket"},"name":"Penny Markt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Giant":{"tags":{"name":"Giant","shop":"supermarket"},"name":"Giant","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rema 1000":{"tags":{"name":"Rema 1000","shop":"supermarket"},"name":"Rema 1000","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kaufpark":{"tags":{"name":"Kaufpark","shop":"supermarket"},"name":"Kaufpark","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ALDI SÜD":{"tags":{"name":"ALDI SÜD","shop":"supermarket"},"name":"ALDI SÜD","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Simply Market":{"tags":{"name":"Simply Market","shop":"supermarket"},"name":"Simply Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Konzum":{"tags":{"name":"Konzum","shop":"supermarket"},"name":"Konzum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour Express":{"tags":{"name":"Carrefour Express","shop":"supermarket"},"name":"Carrefour Express","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eurospar":{"tags":{"name":"Eurospar","shop":"supermarket"},"name":"Eurospar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercator":{"tags":{"name":"Mercator","shop":"supermarket"},"name":"Mercator","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Famila":{"tags":{"name":"Famila","shop":"supermarket"},"name":"Famila","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hemköp":{"tags":{"name":"Hemköp","shop":"supermarket"},"name":"Hemköp","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/real,-":{"tags":{"name":"real,-","shop":"supermarket"},"name":"real,-","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Markant":{"tags":{"name":"Markant","shop":"supermarket"},"name":"Markant","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Volg":{"tags":{"name":"Volg","shop":"supermarket"},"name":"Volg","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Leader Price":{"tags":{"name":"Leader Price","shop":"supermarket"},"name":"Leader Price","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Treff 3000":{"tags":{"name":"Treff 3000","shop":"supermarket"},"name":"Treff 3000","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/SuperBrugsen":{"tags":{"name":"SuperBrugsen","shop":"supermarket"},"name":"SuperBrugsen","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kaiser's":{"tags":{"name":"Kaiser's","shop":"supermarket"},"name":"Kaiser's","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/K+K":{"tags":{"name":"K+K","shop":"supermarket"},"name":"K+K","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Unimarkt":{"tags":{"name":"Unimarkt","shop":"supermarket"},"name":"Unimarkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour City":{"tags":{"name":"Carrefour City","shop":"supermarket"},"name":"Carrefour City","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sobeys":{"tags":{"name":"Sobeys","shop":"supermarket"},"name":"Sobeys","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/S-Market":{"tags":{"name":"S-Market","shop":"supermarket"},"name":"S-Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Combi":{"tags":{"name":"Combi","shop":"supermarket"},"name":"Combi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Denner":{"tags":{"name":"Denner","shop":"supermarket"},"name":"Denner","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Konsum":{"tags":{"name":"Konsum","shop":"supermarket"},"name":"Konsum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Franprix":{"tags":{"name":"Franprix","shop":"supermarket"},"name":"Franprix","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Monoprix":{"tags":{"name":"Monoprix","shop":"supermarket"},"name":"Monoprix","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Diska":{"tags":{"name":"Diska","shop":"supermarket"},"name":"Diska","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/PENNY":{"tags":{"name":"PENNY","shop":"supermarket"},"name":"PENNY","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dia":{"tags":{"name":"Dia","shop":"supermarket"},"name":"Dia","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Giant Eagle":{"tags":{"name":"Giant Eagle","shop":"supermarket"},"name":"Giant Eagle","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/NORMA":{"tags":{"name":"NORMA","shop":"supermarket"},"name":"NORMA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/AD Delhaize":{"tags":{"name":"AD Delhaize","shop":"supermarket"},"name":"AD Delhaize","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Auchan":{"tags":{"name":"Auchan","shop":"supermarket"},"name":"Auchan","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Mercadona":{"tags":{"name":"Mercadona","shop":"supermarket"},"name":"Mercadona","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Consum":{"tags":{"name":"Consum","shop":"supermarket"},"name":"Consum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour Market":{"tags":{"name":"Carrefour Market","shop":"supermarket"},"name":"Carrefour Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Whole Foods":{"tags":{"name":"Whole Foods","shop":"supermarket"},"name":"Whole Foods","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pam":{"tags":{"name":"Pam","shop":"supermarket"},"name":"Pam","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/sky":{"tags":{"name":"sky","shop":"supermarket"},"name":"sky","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Despar":{"tags":{"name":"Despar","shop":"supermarket"},"name":"Despar","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eroski":{"tags":{"name":"Eroski","shop":"supermarket"},"name":"Eroski","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxi":{"tags":{"name":"Maxi","shop":"supermarket"},"name":"Maxi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Colruyt":{"tags":{"name":"Colruyt","shop":"supermarket"},"name":"Colruyt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/The Co-operative":{"tags":{"name":"The Co-operative","shop":"supermarket"},"name":"The Co-operative","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Intermarché":{"tags":{"name":"Intermarché","shop":"supermarket"},"name":"Intermarché","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Delhaize":{"tags":{"name":"Delhaize","shop":"supermarket"},"name":"Delhaize","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/CBA":{"tags":{"name":"CBA","shop":"supermarket"},"name":"CBA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Shopi":{"tags":{"name":"Shopi","shop":"supermarket"},"name":"Shopi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Walmart":{"tags":{"name":"Walmart","shop":"supermarket"},"name":"Walmart","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kroger":{"tags":{"name":"Kroger","shop":"supermarket"},"name":"Kroger","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Albertsons":{"tags":{"name":"Albertsons","shop":"supermarket"},"name":"Albertsons","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Trader Joe's":{"tags":{"name":"Trader Joe's","shop":"supermarket"},"name":"Trader Joe's","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Feneberg":{"tags":{"name":"Feneberg","shop":"supermarket"},"name":"Feneberg","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/denn's Biomarkt":{"tags":{"name":"denn's Biomarkt","shop":"supermarket"},"name":"denn's Biomarkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Kvickly":{"tags":{"name":"Kvickly","shop":"supermarket"},"name":"Kvickly","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Makro":{"tags":{"name":"Makro","shop":"supermarket"},"name":"Makro","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dico":{"tags":{"name":"Dico","shop":"supermarket"},"name":"Dico","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Nah & Frisch":{"tags":{"name":"Nah & Frisch","shop":"supermarket"},"name":"Nah & Frisch","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Champion":{"tags":{"name":"Champion","shop":"supermarket"},"name":"Champion","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ICA Supermarket":{"tags":{"name":"ICA Supermarket","shop":"supermarket"},"name":"ICA Supermarket","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Fakta":{"tags":{"name":"Fakta","shop":"supermarket"},"name":"Fakta","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Магнит":{"tags":{"name":"Магнит","shop":"supermarket"},"name":"Магнит","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Caprabo":{"tags":{"name":"Caprabo","shop":"supermarket"},"name":"Caprabo","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Famiglia Cooperativa":{"tags":{"name":"Famiglia Cooperativa","shop":"supermarket"},"name":"Famiglia Cooperativa","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Народная 7Я семьЯ":{"tags":{"name":"Народная 7Я семьЯ","shop":"supermarket"},"name":"Народная 7Я семьЯ","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Esselunga":{"tags":{"name":"Esselunga","shop":"supermarket"},"name":"Esselunga","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxima":{"tags":{"name":"Maxima","shop":"supermarket"},"name":"Maxima","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Wasgau":{"tags":{"name":"Wasgau","shop":"supermarket"},"name":"Wasgau","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Pingo Doce":{"tags":{"name":"Pingo Doce","shop":"supermarket"},"name":"Pingo Doce","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Match":{"tags":{"name":"Match","shop":"supermarket"},"name":"Match","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Profi":{"tags":{"name":"Profi","shop":"supermarket"},"name":"Profi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Lider":{"tags":{"name":"Lider","shop":"supermarket"},"name":"Lider","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Unimarc":{"tags":{"name":"Unimarc","shop":"supermarket"},"name":"Unimarc","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/The Co-operative Food":{"tags":{"name":"The Co-operative Food","shop":"supermarket"},"name":"The Co-operative Food","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Santa Isabel":{"tags":{"name":"Santa Isabel","shop":"supermarket"},"name":"Santa Isabel","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Седьмой континент":{"tags":{"name":"Седьмой континент","shop":"supermarket"},"name":"Седьмой континент","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/HIT":{"tags":{"name":"HIT","shop":"supermarket"},"name":"HIT","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Rimi":{"tags":{"name":"Rimi","shop":"supermarket"},"name":"Rimi","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Conad":{"tags":{"name":"Conad","shop":"supermarket"},"name":"Conad","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Фуршет":{"tags":{"name":"Фуршет","shop":"supermarket"},"name":"Фуршет","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Willys":{"tags":{"name":"Willys","shop":"supermarket"},"name":"Willys","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Farmfoods":{"tags":{"name":"Farmfoods","shop":"supermarket"},"name":"Farmfoods","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/U Express":{"tags":{"name":"U Express","shop":"supermarket"},"name":"U Express","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Фора":{"tags":{"name":"Фора","shop":"supermarket"},"name":"Фора","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Dunnes Stores":{"tags":{"name":"Dunnes Stores","shop":"supermarket"},"name":"Dunnes Stores","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Сільпо":{"tags":{"name":"Сільпо","shop":"supermarket"},"name":"Сільпо","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/マルエツ":{"tags":{"name":"マルエツ","shop":"supermarket"},"name":"マルエツ","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Piggly Wiggly":{"tags":{"name":"Piggly Wiggly","shop":"supermarket"},"name":"Piggly Wiggly","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Crai":{"tags":{"name":"Crai","shop":"supermarket"},"name":"Crai","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/El Árbol":{"tags":{"name":"El Árbol","shop":"supermarket"},"name":"El Árbol","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Centre Commercial E. Leclerc":{"tags":{"name":"Centre Commercial E. Leclerc","shop":"supermarket"},"name":"Centre Commercial E. Leclerc","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Foodland":{"tags":{"name":"Foodland","shop":"supermarket"},"name":"Foodland","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Super Brugsen":{"tags":{"name":"Super Brugsen","shop":"supermarket"},"name":"Super Brugsen","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Дикси":{"tags":{"name":"Дикси","shop":"supermarket"},"name":"Дикси","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Пятёрочка":{"tags":{"name":"Пятёрочка","shop":"supermarket"},"name":"Пятёрочка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Publix":{"tags":{"name":"Publix","shop":"supermarket"},"name":"Publix","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Føtex":{"tags":{"name":"Føtex","shop":"supermarket"},"name":"Føtex","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/coop":{"tags":{"name":"coop","shop":"supermarket"},"name":"coop","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop Konsum":{"tags":{"name":"Coop Konsum","shop":"supermarket"},"name":"Coop Konsum","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Carrefour Contact":{"tags":{"name":"Carrefour Contact","shop":"supermarket"},"name":"Carrefour Contact","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/No Frills":{"tags":{"name":"No Frills","shop":"supermarket"},"name":"No Frills","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Plodine":{"tags":{"name":"Plodine","shop":"supermarket"},"name":"Plodine","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ADEG":{"tags":{"name":"ADEG","shop":"supermarket"},"name":"ADEG","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Minipreço":{"tags":{"name":"Minipreço","shop":"supermarket"},"name":"Minipreço","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Biedronka":{"tags":{"name":"Biedronka","shop":"supermarket"},"name":"Biedronka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Eurospin":{"tags":{"name":"Eurospin","shop":"supermarket"},"name":"Eurospin","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Семья":{"tags":{"name":"Семья","shop":"supermarket"},"name":"Семья","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Gadis":{"tags":{"name":"Gadis","shop":"supermarket"},"name":"Gadis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Евроопт":{"tags":{"name":"Евроопт","shop":"supermarket"},"name":"Евроопт","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Квартал":{"tags":{"name":"Квартал","shop":"supermarket"},"name":"Квартал","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/New World":{"tags":{"name":"New World","shop":"supermarket"},"name":"New World","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Countdown":{"tags":{"name":"Countdown","shop":"supermarket"},"name":"Countdown","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Reliance Fresh":{"tags":{"name":"Reliance Fresh","shop":"supermarket"},"name":"Reliance Fresh","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Stokrotka":{"tags":{"name":"Stokrotka","shop":"supermarket"},"name":"Stokrotka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Coop Jednota":{"tags":{"name":"Coop Jednota","shop":"supermarket"},"name":"Coop Jednota","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Fred Meyer":{"tags":{"name":"Fred Meyer","shop":"supermarket"},"name":"Fred Meyer","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Irma":{"tags":{"name":"Irma","shop":"supermarket"},"name":"Irma","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Continente":{"tags":{"name":"Continente","shop":"supermarket"},"name":"Continente","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Price Chopper":{"tags":{"name":"Price Chopper","shop":"supermarket"},"name":"Price Chopper","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Game":{"tags":{"name":"Game","shop":"supermarket"},"name":"Game","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Soriana":{"tags":{"name":"Soriana","shop":"supermarket"},"name":"Soriana","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Alimerka":{"tags":{"name":"Alimerka","shop":"supermarket"},"name":"Alimerka","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Piotr i Paweł":{"tags":{"name":"Piotr i Paweł","shop":"supermarket"},"name":"Piotr i Paweł","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Перекресток":{"tags":{"name":"Перекресток","shop":"supermarket"},"name":"Перекресток","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Maxima X":{"tags":{"name":"Maxima X","shop":"supermarket"},"name":"Maxima X","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Карусель":{"tags":{"name":"Карусель","shop":"supermarket"},"name":"Карусель","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ALDI Nord":{"tags":{"name":"ALDI Nord","shop":"supermarket"},"name":"ALDI Nord","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Condis":{"tags":{"name":"Condis","shop":"supermarket"},"name":"Condis","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sam's Club":{"tags":{"name":"Sam's Club","shop":"supermarket"},"name":"Sam's Club","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Копейка":{"tags":{"name":"Копейка","shop":"supermarket"},"name":"Копейка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Géant Casino":{"tags":{"name":"Géant Casino","shop":"supermarket"},"name":"Géant Casino","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ASDA":{"tags":{"name":"ASDA","shop":"supermarket"},"name":"ASDA","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Intermarche":{"tags":{"name":"Intermarche","shop":"supermarket"},"name":"Intermarche","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Stop & Shop":{"tags":{"name":"Stop & Shop","shop":"supermarket"},"name":"Stop & Shop","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Food Lion":{"tags":{"name":"Food Lion","shop":"supermarket"},"name":"Food Lion","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Harris Teeter":{"tags":{"name":"Harris Teeter","shop":"supermarket"},"name":"Harris Teeter","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Foodworks":{"tags":{"name":"Foodworks","shop":"supermarket"},"name":"Foodworks","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Polo Market":{"tags":{"name":"Polo Market","shop":"supermarket"},"name":"Polo Market","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Лента":{"tags":{"name":"Лента","shop":"supermarket"},"name":"Лента","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/西友 (SEIYU)":{"tags":{"name":"西友 (SEIYU)","shop":"supermarket"},"name":"西友 (SEIYU)","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/H-E-B":{"tags":{"name":"H-E-B","shop":"supermarket"},"name":"H-E-B","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Атак":{"tags":{"name":"Атак","shop":"supermarket"},"name":"Атак","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Полушка":{"tags":{"name":"Полушка","shop":"supermarket"},"name":"Полушка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Extra":{"tags":{"name":"Extra","shop":"supermarket"},"name":"Extra","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Sigma":{"tags":{"name":"Sigma","shop":"supermarket"},"name":"Sigma","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/АТБ":{"tags":{"name":"АТБ","shop":"supermarket"},"name":"АТБ","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Bodega Aurrera":{"tags":{"name":"Bodega Aurrera","shop":"supermarket"},"name":"Bodega Aurrera","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Tesco Lotus":{"tags":{"name":"Tesco Lotus","shop":"supermarket"},"name":"Tesco Lotus","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Мария-Ра":{"tags":{"name":"Мария-Ра","shop":"supermarket"},"name":"Мария-Ра","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Магнолия":{"tags":{"name":"Магнолия","shop":"supermarket"},"name":"Магнолия","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Монетка":{"tags":{"name":"Монетка","shop":"supermarket"},"name":"Монетка","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hy-Vee":{"tags":{"name":"Hy-Vee","shop":"supermarket"},"name":"Hy-Vee","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Walmart Supercenter":{"tags":{"name":"Walmart Supercenter","shop":"supermarket"},"name":"Walmart Supercenter","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Hannaford":{"tags":{"name":"Hannaford","shop":"supermarket"},"name":"Hannaford","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Wegmans":{"tags":{"name":"Wegmans","shop":"supermarket"},"name":"Wegmans","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/業務スーパー":{"tags":{"name":"業務スーパー","shop":"supermarket"},"name":"業務スーパー","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Norfa XL":{"tags":{"name":"Norfa XL","shop":"supermarket"},"name":"Norfa XL","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/ヨークマート (YorkMart)":{"tags":{"name":"ヨークマート (YorkMart)","shop":"supermarket"},"name":"ヨークマート (YorkMart)","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/supermarket/Leclerc Drive":{"tags":{"name":"Leclerc Drive","shop":"supermarket"},"name":"Leclerc Drive","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Media Markt":{"tags":{"name":"Media Markt","shop":"electronics"},"name":"Media Markt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Maplin":{"tags":{"name":"Maplin","shop":"electronics"},"name":"Maplin","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Best Buy":{"tags":{"name":"Best Buy","shop":"electronics"},"name":"Best Buy","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Future Shop":{"tags":{"name":"Future Shop","shop":"electronics"},"name":"Future Shop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Saturn":{"tags":{"name":"Saturn","shop":"electronics"},"name":"Saturn","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Currys":{"tags":{"name":"Currys","shop":"electronics"},"name":"Currys","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Radio Shack":{"tags":{"name":"Radio Shack","shop":"electronics"},"name":"Radio Shack","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Euronics":{"tags":{"name":"Euronics","shop":"electronics"},"name":"Euronics","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Expert":{"tags":{"name":"Expert","shop":"electronics"},"name":"Expert","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Эльдорадо":{"tags":{"name":"Эльдорадо","shop":"electronics"},"name":"Эльдорадо","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/Darty":{"tags":{"name":"Darty","shop":"electronics"},"name":"Darty","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/М.Видео":{"tags":{"name":"М.Видео","shop":"electronics"},"name":"М.Видео","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/electronics/ヤマダ電機":{"tags":{"name":"ヤマダ電機","shop":"electronics"},"name":"ヤマダ電機","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/McColl's":{"tags":{"name":"McColl's","shop":"convenience"},"name":"McColl's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Tesco Express":{"tags":{"name":"Tesco Express","shop":"convenience"},"name":"Tesco Express","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/One Stop":{"tags":{"name":"One Stop","shop":"convenience"},"name":"One Stop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Londis":{"tags":{"name":"Londis","shop":"convenience"},"name":"Londis","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/7-Eleven":{"tags":{"name":"7-Eleven","shop":"convenience"},"name":"7-Eleven","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sale":{"tags":{"name":"Sale","shop":"convenience"},"name":"Sale","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Siwa":{"tags":{"name":"Siwa","shop":"convenience"},"name":"Siwa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/COOP Jednota":{"tags":{"name":"COOP Jednota","shop":"convenience"},"name":"COOP Jednota","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mac's":{"tags":{"name":"Mac's","shop":"convenience"},"name":"Mac's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Alepa":{"tags":{"name":"Alepa","shop":"convenience"},"name":"Alepa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Hasty Market":{"tags":{"name":"Hasty Market","shop":"convenience"},"name":"Hasty Market","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/K-Market":{"tags":{"name":"K-Market","shop":"convenience"},"name":"K-Market","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Costcutter":{"tags":{"name":"Costcutter","shop":"convenience"},"name":"Costcutter","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Valintatalo":{"tags":{"name":"Valintatalo","shop":"convenience"},"name":"Valintatalo","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Circle K":{"tags":{"name":"Circle K","shop":"convenience"},"name":"Circle K","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セブンイレブン":{"tags":{"name":"セブンイレブン","name:en":"7-Eleven","shop":"convenience"},"name":"セブンイレブン","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソン":{"tags":{"name":"ローソン","name:en":"LAWSON","shop":"convenience"},"name":"ローソン","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Petit Casino":{"tags":{"name":"Petit Casino","shop":"convenience"},"name":"Petit Casino","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mace":{"tags":{"name":"Mace","shop":"convenience"},"name":"Mace","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini Market":{"tags":{"name":"Mini Market","shop":"convenience"},"name":"Mini Market","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Nisa Local":{"tags":{"name":"Nisa Local","shop":"convenience"},"name":"Nisa Local","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Dorfladen":{"tags":{"name":"Dorfladen","shop":"convenience"},"name":"Dorfladen","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продукты":{"tags":{"name":"Продукты","shop":"convenience"},"name":"Продукты","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini Stop":{"tags":{"name":"Mini Stop","shop":"convenience"},"name":"Mini Stop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/LAWSON":{"tags":{"name":"LAWSON","shop":"convenience"},"name":"LAWSON","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/デイリーヤマザキ":{"tags":{"name":"デイリーヤマザキ","shop":"convenience"},"name":"デイリーヤマザキ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Надежда":{"tags":{"name":"Надежда","shop":"convenience"},"name":"Надежда","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Nisa":{"tags":{"name":"Nisa","shop":"convenience"},"name":"Nisa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Premier":{"tags":{"name":"Premier","shop":"convenience"},"name":"Premier","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ABC":{"tags":{"name":"ABC","shop":"convenience"},"name":"ABC","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ミニストップ":{"tags":{"name":"ミニストップ","name:en":"MINISTOP","shop":"convenience"},"name":"ミニストップ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/サンクス":{"tags":{"name":"サンクス","name:en":"sunkus","shop":"convenience"},"name":"サンクス","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/スリーエフ":{"tags":{"name":"スリーエフ","shop":"convenience"},"name":"スリーエフ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/8 à Huit":{"tags":{"name":"8 à Huit","shop":"convenience"},"name":"8 à Huit","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Żabka":{"tags":{"name":"Żabka","shop":"convenience"},"name":"Żabka","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Almacen":{"tags":{"name":"Almacen","shop":"convenience"},"name":"Almacen","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Vival":{"tags":{"name":"Vival","shop":"convenience"},"name":"Vival","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/FamilyMart":{"tags":{"name":"FamilyMart","shop":"convenience"},"name":"FamilyMart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ファミリーマート":{"tags":{"name":"ファミリーマート","name:en":"FamilyMart","shop":"convenience"},"name":"ファミリーマート","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sunkus":{"tags":{"name":"Sunkus","shop":"convenience"},"name":"Sunkus","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セブンイレブン(Seven-Eleven)":{"tags":{"name":"セブンイレブン(Seven-Eleven)","shop":"convenience"},"name":"セブンイレブン(Seven-Eleven)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Jednota":{"tags":{"name":"Jednota","shop":"convenience"},"name":"Jednota","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Магазин":{"tags":{"name":"Магазин","shop":"convenience"},"name":"Магазин","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Гастроном":{"tags":{"name":"Гастроном","shop":"convenience"},"name":"Гастроном","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Centra":{"tags":{"name":"Centra","shop":"convenience"},"name":"Centra","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/サークルK":{"tags":{"name":"サークルK","name:en":"Circle K","shop":"convenience"},"name":"サークルK","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Wawa":{"tags":{"name":"Wawa","shop":"convenience"},"name":"Wawa","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Proxi":{"tags":{"name":"Proxi","shop":"convenience"},"name":"Proxi","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Универсам":{"tags":{"name":"Универсам","shop":"convenience"},"name":"Универсам","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Groszek":{"tags":{"name":"Groszek","shop":"convenience"},"name":"Groszek","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Select":{"tags":{"name":"Select","shop":"convenience"},"name":"Select","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Večerka":{"tags":{"name":"Večerka","shop":"convenience"},"name":"Večerka","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Potraviny":{"tags":{"name":"Potraviny","shop":"convenience"},"name":"Potraviny","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Смак":{"tags":{"name":"Смак","shop":"convenience"},"name":"Смак","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Эконом":{"tags":{"name":"Эконом","shop":"convenience"},"name":"Эконом","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Березка":{"tags":{"name":"Березка","shop":"convenience"},"name":"Березка","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Społem":{"tags":{"name":"Społem","shop":"convenience"},"name":"Społem","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Cumberland Farms":{"tags":{"name":"Cumberland Farms","shop":"convenience"},"name":"Cumberland Farms","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Tesco Lotus Express":{"tags":{"name":"Tesco Lotus Express","shop":"convenience"},"name":"Tesco Lotus Express","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Kiosk":{"tags":{"name":"Kiosk","shop":"convenience"},"name":"Kiosk","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Sklep spożywczy":{"tags":{"name":"Sklep spożywczy","shop":"convenience"},"name":"Sklep spożywczy","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/24 часа":{"tags":{"name":"24 часа","shop":"convenience"},"name":"24 часа","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Минимаркет":{"tags":{"name":"Минимаркет","shop":"convenience"},"name":"Минимаркет","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Oxxo":{"tags":{"name":"Oxxo","shop":"convenience"},"name":"Oxxo","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/abc":{"tags":{"name":"abc","shop":"convenience"},"name":"abc","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/7/11":{"tags":{"name":"7/11","shop":"convenience"},"name":"7/11","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Stewart's":{"tags":{"name":"Stewart's","shop":"convenience"},"name":"Stewart's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продукти":{"tags":{"name":"Продукти","shop":"convenience"},"name":"Продукти","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソンストア100 (LAWSON STORE 100)":{"tags":{"name":"ローソンストア100 (LAWSON STORE 100)","shop":"convenience"},"name":"ローソンストア100 (LAWSON STORE 100)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Радуга":{"tags":{"name":"Радуга","shop":"convenience"},"name":"Радуга","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ローソンストア100":{"tags":{"name":"ローソンストア100","shop":"convenience"},"name":"ローソンストア100","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/เซเว่นอีเลฟเว่น":{"tags":{"name":"เซเว่นอีเลฟเว่น","shop":"convenience"},"name":"เซเว่นอีเลฟเว่น","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Фортуна":{"tags":{"name":"Фортуна","shop":"convenience"},"name":"Фортуна","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Picard":{"tags":{"name":"Picard","shop":"convenience"},"name":"Picard","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Four Square":{"tags":{"name":"Four Square","shop":"convenience"},"name":"Four Square","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Визит":{"tags":{"name":"Визит","shop":"convenience"},"name":"Визит","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Авоська":{"tags":{"name":"Авоська","shop":"convenience"},"name":"Авоська","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Dollar General":{"tags":{"name":"Dollar General","shop":"convenience"},"name":"Dollar General","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Studenac":{"tags":{"name":"Studenac","shop":"convenience"},"name":"Studenac","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Central Convenience Store":{"tags":{"name":"Central Convenience Store","shop":"convenience"},"name":"Central Convenience Store","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/продукты":{"tags":{"name":"продукты","shop":"convenience"},"name":"продукты","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Кулинария":{"tags":{"name":"Кулинария","shop":"convenience"},"name":"Кулинария","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/全家":{"tags":{"name":"全家","shop":"convenience"},"name":"全家","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Мечта":{"tags":{"name":"Мечта","shop":"convenience"},"name":"Мечта","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Epicerie":{"tags":{"name":"Epicerie","shop":"convenience"},"name":"Epicerie","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Кировский":{"tags":{"name":"Кировский","shop":"convenience"},"name":"Кировский","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Food Mart":{"tags":{"name":"Food Mart","shop":"convenience"},"name":"Food Mart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Delikatesy":{"tags":{"name":"Delikatesy","shop":"convenience"},"name":"Delikatesy","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/ポプラ":{"tags":{"name":"ポプラ","shop":"convenience"},"name":"ポプラ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Lewiatan":{"tags":{"name":"Lewiatan","shop":"convenience"},"name":"Lewiatan","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продуктовый магазин":{"tags":{"name":"Продуктовый магазин","shop":"convenience"},"name":"Продуктовый магазин","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Продуктовый":{"tags":{"name":"Продуктовый","shop":"convenience"},"name":"Продуктовый","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/セイコーマート (Seicomart)":{"tags":{"name":"セイコーマート (Seicomart)","shop":"convenience"},"name":"セイコーマート (Seicomart)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Виктория":{"tags":{"name":"Виктория","shop":"convenience"},"name":"Виктория","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Весна":{"tags":{"name":"Весна","shop":"convenience"},"name":"Весна","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Mini Market Non-Stop":{"tags":{"name":"Mini Market Non-Stop","shop":"convenience"},"name":"Mini Market Non-Stop","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Копеечка":{"tags":{"name":"Копеечка","shop":"convenience"},"name":"Копеечка","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Royal Farms":{"tags":{"name":"Royal Farms","shop":"convenience"},"name":"Royal Farms","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Alfamart":{"tags":{"name":"Alfamart","shop":"convenience"},"name":"Alfamart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Indomaret":{"tags":{"name":"Indomaret","shop":"convenience"},"name":"Indomaret","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/магазин":{"tags":{"name":"магазин","shop":"convenience"},"name":"магазин","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/全家便利商店":{"tags":{"name":"全家便利商店","shop":"convenience"},"name":"全家便利商店","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Boutique":{"tags":{"name":"Boutique","shop":"convenience"},"name":"Boutique","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/მარკეტი (Market)":{"tags":{"name":"მარკეტი (Market)","shop":"convenience"},"name":"მარკეტი (Market)","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/convenience/Stores":{"tags":{"name":"Stores","shop":"convenience"},"name":"Stores","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/dm":{"tags":{"name":"dm","shop":"chemist"},"name":"dm","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Müller":{"tags":{"name":"Müller","shop":"chemist"},"name":"Müller","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Schlecker":{"tags":{"name":"Schlecker","shop":"chemist"},"name":"Schlecker","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Etos":{"tags":{"name":"Etos","shop":"chemist"},"name":"Etos","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Bipa":{"tags":{"name":"Bipa","shop":"chemist"},"name":"Bipa","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Rossmann":{"tags":{"name":"Rossmann","shop":"chemist"},"name":"Rossmann","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/DM Drogeriemarkt":{"tags":{"name":"DM Drogeriemarkt","shop":"chemist"},"name":"DM Drogeriemarkt","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Ihr Platz":{"tags":{"name":"Ihr Platz","shop":"chemist"},"name":"Ihr Platz","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Douglas":{"tags":{"name":"Douglas","shop":"chemist"},"name":"Douglas","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/chemist/Kruidvat":{"tags":{"name":"Kruidvat","shop":"chemist"},"name":"Kruidvat","icon":"grocery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Kwik Fit":{"tags":{"name":"Kwik Fit","shop":"car_repair"},"name":"Kwik Fit","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/ATU":{"tags":{"name":"ATU","shop":"car_repair"},"name":"ATU","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Midas":{"tags":{"name":"Midas","shop":"car_repair"},"name":"Midas","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Feu Vert":{"tags":{"name":"Feu Vert","shop":"car_repair"},"name":"Feu Vert","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Norauto":{"tags":{"name":"Norauto","shop":"car_repair"},"name":"Norauto","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Speedy":{"tags":{"name":"Speedy","shop":"car_repair"},"name":"Speedy","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Pit Stop":{"tags":{"name":"Pit Stop","shop":"car_repair"},"name":"Pit Stop","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Jiffy Lube":{"tags":{"name":"Jiffy Lube","shop":"car_repair"},"name":"Jiffy Lube","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Шиномонтаж":{"tags":{"name":"Шиномонтаж","shop":"car_repair"},"name":"Шиномонтаж","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/СТО":{"tags":{"name":"СТО","shop":"car_repair"},"name":"СТО","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/O'Reilly Auto Parts":{"tags":{"name":"O'Reilly Auto Parts","shop":"car_repair"},"name":"O'Reilly Auto Parts","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Carglass":{"tags":{"name":"Carglass","shop":"car_repair"},"name":"Carglass","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/шиномонтаж":{"tags":{"name":"шиномонтаж","shop":"car_repair"},"name":"шиномонтаж","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Euromaster":{"tags":{"name":"Euromaster","shop":"car_repair"},"name":"Euromaster","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Firestone":{"tags":{"name":"Firestone","shop":"car_repair"},"name":"Firestone","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Автосервис":{"tags":{"name":"Автосервис","shop":"car_repair"},"name":"Автосервис","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Advance Auto Parts":{"tags":{"name":"Advance Auto Parts","shop":"car_repair"},"name":"Advance Auto Parts","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car_repair/Roady":{"tags":{"name":"Roady","shop":"car_repair"},"name":"Roady","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/IKEA":{"tags":{"name":"IKEA","shop":"furniture"},"name":"IKEA","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Jysk":{"tags":{"name":"Jysk","shop":"furniture"},"name":"Jysk","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Roller":{"tags":{"name":"Roller","shop":"furniture"},"name":"Roller","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Dänisches Bettenlager":{"tags":{"name":"Dänisches Bettenlager","shop":"furniture"},"name":"Dänisches Bettenlager","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Conforama":{"tags":{"name":"Conforama","shop":"furniture"},"name":"Conforama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Matratzen Concord":{"tags":{"name":"Matratzen Concord","shop":"furniture"},"name":"Matratzen Concord","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/Мебель":{"tags":{"name":"Мебель","shop":"furniture"},"name":"Мебель","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/furniture/But":{"tags":{"name":"But","shop":"furniture"},"name":"But","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hornbach":{"tags":{"name":"Hornbach","shop":"doityourself"},"name":"Hornbach","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/B&Q":{"tags":{"name":"B&Q","shop":"doityourself"},"name":"B&Q","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hubo":{"tags":{"name":"Hubo","shop":"doityourself"},"name":"Hubo","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Mr Bricolage":{"tags":{"name":"Mr Bricolage","shop":"doityourself"},"name":"Mr Bricolage","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Gamma":{"tags":{"name":"Gamma","shop":"doityourself"},"name":"Gamma","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/OBI":{"tags":{"name":"OBI","shop":"doityourself"},"name":"OBI","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Lowes":{"tags":{"name":"Lowes","shop":"doityourself"},"name":"Lowes","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Wickes":{"tags":{"name":"Wickes","shop":"doityourself"},"name":"Wickes","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hagebau":{"tags":{"name":"Hagebau","shop":"doityourself"},"name":"Hagebau","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Max Bahr":{"tags":{"name":"Max Bahr","shop":"doityourself"},"name":"Max Bahr","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Castorama":{"tags":{"name":"Castorama","shop":"doityourself"},"name":"Castorama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Rona":{"tags":{"name":"Rona","shop":"doityourself"},"name":"Rona","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Home Depot":{"tags":{"name":"Home Depot","shop":"doityourself"},"name":"Home Depot","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Toom Baumarkt":{"tags":{"name":"Toom Baumarkt","shop":"doityourself"},"name":"Toom Baumarkt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Homebase":{"tags":{"name":"Homebase","shop":"doityourself"},"name":"Homebase","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Baumax":{"tags":{"name":"Baumax","shop":"doityourself"},"name":"Baumax","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Lagerhaus":{"tags":{"name":"Lagerhaus","shop":"doityourself"},"name":"Lagerhaus","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bauhaus":{"tags":{"name":"Bauhaus","shop":"doityourself"},"name":"Bauhaus","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Canadian Tire":{"tags":{"name":"Canadian Tire","shop":"doityourself"},"name":"Canadian Tire","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Leroy Merlin":{"tags":{"name":"Leroy Merlin","shop":"doityourself"},"name":"Leroy Merlin","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hellweg":{"tags":{"name":"Hellweg","shop":"doityourself"},"name":"Hellweg","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Brico":{"tags":{"name":"Brico","shop":"doityourself"},"name":"Brico","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bricomarché":{"tags":{"name":"Bricomarché","shop":"doityourself"},"name":"Bricomarché","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Toom":{"tags":{"name":"Toom","shop":"doityourself"},"name":"Toom","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Hagebaumarkt":{"tags":{"name":"Hagebaumarkt","shop":"doityourself"},"name":"Hagebaumarkt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Praktiker":{"tags":{"name":"Praktiker","shop":"doityourself"},"name":"Praktiker","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Menards":{"tags":{"name":"Menards","shop":"doityourself"},"name":"Menards","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Weldom":{"tags":{"name":"Weldom","shop":"doityourself"},"name":"Weldom","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bunnings Warehouse":{"tags":{"name":"Bunnings Warehouse","shop":"doityourself"},"name":"Bunnings Warehouse","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Ace Hardware":{"tags":{"name":"Ace Hardware","shop":"doityourself"},"name":"Ace Hardware","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Home Hardware":{"tags":{"name":"Home Hardware","shop":"doityourself"},"name":"Home Hardware","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Стройматериалы":{"tags":{"name":"Стройматериалы","shop":"doityourself"},"name":"Стройматериалы","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Bricorama":{"tags":{"name":"Bricorama","shop":"doityourself"},"name":"Bricorama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/doityourself/Point P":{"tags":{"name":"Point P","shop":"doityourself"},"name":"Point P","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Staples":{"tags":{"name":"Staples","shop":"stationery"},"name":"Staples","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/McPaper":{"tags":{"name":"McPaper","shop":"stationery"},"name":"McPaper","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Office Depot":{"tags":{"name":"Office Depot","shop":"stationery"},"name":"Office Depot","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/stationery/Канцтовары":{"tags":{"name":"Канцтовары","shop":"stationery"},"name":"Канцтовары","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/car/Skoda":{"tags":{"name":"Skoda","shop":"car"},"name":"Skoda","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/BMW":{"tags":{"name":"BMW","shop":"car"},"name":"BMW","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Citroen":{"tags":{"name":"Citroen","shop":"car"},"name":"Citroen","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Renault":{"tags":{"name":"Renault","shop":"car"},"name":"Renault","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Mercedes-Benz":{"tags":{"name":"Mercedes-Benz","shop":"car"},"name":"Mercedes-Benz","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Volvo":{"tags":{"name":"Volvo","shop":"car"},"name":"Volvo","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Ford":{"tags":{"name":"Ford","shop":"car"},"name":"Ford","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Volkswagen":{"tags":{"name":"Volkswagen","shop":"car"},"name":"Volkswagen","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Mazda":{"tags":{"name":"Mazda","shop":"car"},"name":"Mazda","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Mitsubishi":{"tags":{"name":"Mitsubishi","shop":"car"},"name":"Mitsubishi","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Fiat":{"tags":{"name":"Fiat","shop":"car"},"name":"Fiat","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Автозапчасти":{"tags":{"name":"Автозапчасти","shop":"car"},"name":"Автозапчасти","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Opel":{"tags":{"name":"Opel","shop":"car"},"name":"Opel","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Audi":{"tags":{"name":"Audi","shop":"car"},"name":"Audi","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Toyota":{"tags":{"name":"Toyota","shop":"car"},"name":"Toyota","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Nissan":{"tags":{"name":"Nissan","shop":"car"},"name":"Nissan","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Suzuki":{"tags":{"name":"Suzuki","shop":"car"},"name":"Suzuki","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Honda":{"tags":{"name":"Honda","shop":"car"},"name":"Honda","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Peugeot":{"tags":{"name":"Peugeot","shop":"car"},"name":"Peugeot","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Hyundai":{"tags":{"name":"Hyundai","shop":"car"},"name":"Hyundai","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Subaru":{"tags":{"name":"Subaru","shop":"car"},"name":"Subaru","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Chevrolet":{"tags":{"name":"Chevrolet","shop":"car"},"name":"Chevrolet","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/car/Автомагазин":{"tags":{"name":"Автомагазин","shop":"car"},"name":"Автомагазин","icon":"car","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","second_hand"],"suggestion":true},"shop/clothes/Matalan":{"tags":{"name":"Matalan","shop":"clothes"},"name":"Matalan","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/KiK":{"tags":{"name":"KiK","shop":"clothes"},"name":"KiK","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/H&M":{"tags":{"name":"H&M","shop":"clothes"},"name":"H&M","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Urban Outfitters":{"tags":{"name":"Urban Outfitters","shop":"clothes"},"name":"Urban Outfitters","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Vögele":{"tags":{"name":"Vögele","shop":"clothes"},"name":"Vögele","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Zeeman":{"tags":{"name":"Zeeman","shop":"clothes"},"name":"Zeeman","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Takko":{"tags":{"name":"Takko","shop":"clothes"},"name":"Takko","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/C&A":{"tags":{"name":"C&A","shop":"clothes"},"name":"C&A","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Zara":{"tags":{"name":"Zara","shop":"clothes"},"name":"Zara","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Vero Moda":{"tags":{"name":"Vero Moda","shop":"clothes"},"name":"Vero Moda","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/NKD":{"tags":{"name":"NKD","shop":"clothes"},"name":"NKD","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ernsting's family":{"tags":{"name":"Ernsting's family","shop":"clothes"},"name":"Ernsting's family","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Winners":{"tags":{"name":"Winners","shop":"clothes"},"name":"Winners","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/River Island":{"tags":{"name":"River Island","shop":"clothes"},"name":"River Island","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Next":{"tags":{"name":"Next","shop":"clothes"},"name":"Next","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gap":{"tags":{"name":"Gap","shop":"clothes"},"name":"Gap","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Adidas":{"tags":{"name":"Adidas","shop":"clothes"},"name":"Adidas","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mr Price":{"tags":{"name":"Mr Price","shop":"clothes"},"name":"Mr Price","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Pep":{"tags":{"name":"Pep","shop":"clothes"},"name":"Pep","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Edgars":{"tags":{"name":"Edgars","shop":"clothes"},"name":"Edgars","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ackermans":{"tags":{"name":"Ackermans","shop":"clothes"},"name":"Ackermans","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Truworths":{"tags":{"name":"Truworths","shop":"clothes"},"name":"Truworths","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ross":{"tags":{"name":"Ross","shop":"clothes"},"name":"Ross","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Burton":{"tags":{"name":"Burton","shop":"clothes"},"name":"Burton","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Dorothy Perkins":{"tags":{"name":"Dorothy Perkins","shop":"clothes"},"name":"Dorothy Perkins","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Lindex":{"tags":{"name":"Lindex","shop":"clothes"},"name":"Lindex","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/s.Oliver":{"tags":{"name":"s.Oliver","shop":"clothes"},"name":"s.Oliver","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Cecil":{"tags":{"name":"Cecil","shop":"clothes"},"name":"Cecil","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Dress Barn":{"tags":{"name":"Dress Barn","shop":"clothes"},"name":"Dress Barn","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Old Navy":{"tags":{"name":"Old Navy","shop":"clothes"},"name":"Old Navy","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jack & Jones":{"tags":{"name":"Jack & Jones","shop":"clothes"},"name":"Jack & Jones","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Pimkie":{"tags":{"name":"Pimkie","shop":"clothes"},"name":"Pimkie","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Esprit":{"tags":{"name":"Esprit","shop":"clothes"},"name":"Esprit","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Primark":{"tags":{"name":"Primark","shop":"clothes"},"name":"Primark","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Bonita":{"tags":{"name":"Bonita","shop":"clothes"},"name":"Bonita","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mexx":{"tags":{"name":"Mexx","shop":"clothes"},"name":"Mexx","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Gerry Weber":{"tags":{"name":"Gerry Weber","shop":"clothes"},"name":"Gerry Weber","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tally Weijl":{"tags":{"name":"Tally Weijl","shop":"clothes"},"name":"Tally Weijl","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Mango":{"tags":{"name":"Mango","shop":"clothes"},"name":"Mango","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/TK Maxx":{"tags":{"name":"TK Maxx","shop":"clothes"},"name":"TK Maxx","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Benetton":{"tags":{"name":"Benetton","shop":"clothes"},"name":"Benetton","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Ulla Popken":{"tags":{"name":"Ulla Popken","shop":"clothes"},"name":"Ulla Popken","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/AWG":{"tags":{"name":"AWG","shop":"clothes"},"name":"AWG","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Tommy Hilfiger":{"tags":{"name":"Tommy Hilfiger","shop":"clothes"},"name":"Tommy Hilfiger","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/New Yorker":{"tags":{"name":"New Yorker","shop":"clothes"},"name":"New Yorker","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Orsay":{"tags":{"name":"Orsay","shop":"clothes"},"name":"Orsay","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jeans Fritz":{"tags":{"name":"Jeans Fritz","shop":"clothes"},"name":"Jeans Fritz","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Charles Vögele":{"tags":{"name":"Charles Vögele","shop":"clothes"},"name":"Charles Vögele","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/New Look":{"tags":{"name":"New Look","shop":"clothes"},"name":"New Look","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Lacoste":{"tags":{"name":"Lacoste","shop":"clothes"},"name":"Lacoste","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Etam":{"tags":{"name":"Etam","shop":"clothes"},"name":"Etam","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Kiabi":{"tags":{"name":"Kiabi","shop":"clothes"},"name":"Kiabi","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jack Wolfskin":{"tags":{"name":"Jack Wolfskin","shop":"clothes"},"name":"Jack Wolfskin","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/American Apparel":{"tags":{"name":"American Apparel","shop":"clothes"},"name":"American Apparel","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Men's Wearhouse":{"tags":{"name":"Men's Wearhouse","shop":"clothes"},"name":"Men's Wearhouse","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Intimissimi":{"tags":{"name":"Intimissimi","shop":"clothes"},"name":"Intimissimi","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/United Colors of Benetton":{"tags":{"name":"United Colors of Benetton","shop":"clothes"},"name":"United Colors of Benetton","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Jules":{"tags":{"name":"Jules","shop":"clothes"},"name":"Jules","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Second Hand":{"tags":{"name":"Second Hand","shop":"clothes"},"name":"Second Hand","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/AOKI":{"tags":{"name":"AOKI","shop":"clothes"},"name":"AOKI","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Calzedonia":{"tags":{"name":"Calzedonia","shop":"clothes"},"name":"Calzedonia","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/洋服の青山":{"tags":{"name":"洋服の青山","shop":"clothes"},"name":"洋服の青山","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Levi's":{"tags":{"name":"Levi's","shop":"clothes"},"name":"Levi's","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Celio":{"tags":{"name":"Celio","shop":"clothes"},"name":"Celio","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/TJ Maxx":{"tags":{"name":"TJ Maxx","shop":"clothes"},"name":"TJ Maxx","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Promod":{"tags":{"name":"Promod","shop":"clothes"},"name":"Promod","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Street One":{"tags":{"name":"Street One","shop":"clothes"},"name":"Street One","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/ユニクロ":{"tags":{"name":"ユニクロ","shop":"clothes"},"name":"ユニクロ","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Banana Republic":{"tags":{"name":"Banana Republic","shop":"clothes"},"name":"Banana Republic","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Одежда":{"tags":{"name":"Одежда","shop":"clothes"},"name":"Одежда","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Marshalls":{"tags":{"name":"Marshalls","shop":"clothes"},"name":"Marshalls","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/La Halle":{"tags":{"name":"La Halle","shop":"clothes"},"name":"La Halle","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/Peacocks":{"tags":{"name":"Peacocks","shop":"clothes"},"name":"Peacocks","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/clothes/しまむら":{"tags":{"name":"しまむら","shop":"clothes"},"name":"しまむら","icon":"clothing-store","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/books/Bruna":{"tags":{"name":"Bruna","shop":"books"},"name":"Bruna","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"shop/books/Waterstones":{"tags":{"name":"Waterstones","shop":"books"},"name":"Waterstones","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"shop/books/Libro":{"tags":{"name":"Libro","shop":"books"},"name":"Libro","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"shop/books/Barnes & Noble":{"tags":{"name":"Barnes & Noble","shop":"books"},"name":"Barnes & Noble","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"shop/books/Weltbild":{"tags":{"name":"Weltbild","shop":"books"},"name":"Weltbild","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"shop/books/Thalia":{"tags":{"name":"Thalia","shop":"books"},"name":"Thalia","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"shop/books/Книги":{"tags":{"name":"Книги","shop":"books"},"name":"Книги","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"suggestion":true},"shop/department_store/Debenhams":{"tags":{"name":"Debenhams","shop":"department_store"},"name":"Debenhams","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Karstadt":{"tags":{"name":"Karstadt","shop":"department_store"},"name":"Karstadt","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Kmart":{"tags":{"name":"Kmart","shop":"department_store"},"name":"Kmart","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Target":{"tags":{"name":"Target","shop":"department_store"},"name":"Target","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Galeria Kaufhof":{"tags":{"name":"Galeria Kaufhof","shop":"department_store"},"name":"Galeria Kaufhof","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Marks & Spencer":{"tags":{"name":"Marks & Spencer","shop":"department_store"},"name":"Marks & Spencer","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Big W":{"tags":{"name":"Big W","shop":"department_store"},"name":"Big W","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Woolworth":{"tags":{"name":"Woolworth","shop":"department_store"},"name":"Woolworth","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Универмаг":{"tags":{"name":"Универмаг","shop":"department_store"},"name":"Универмаг","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Sears":{"tags":{"name":"Sears","shop":"department_store"},"name":"Sears","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Kohl's":{"tags":{"name":"Kohl's","shop":"department_store"},"name":"Kohl's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/Macy's":{"tags":{"name":"Macy's","shop":"department_store"},"name":"Macy's","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/department_store/JCPenney":{"tags":{"name":"JCPenney","shop":"department_store"},"name":"JCPenney","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/alcohol/Alko":{"tags":{"name":"Alko","shop":"alcohol"},"name":"Alko","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/The Beer Store":{"tags":{"name":"The Beer Store","shop":"alcohol"},"name":"The Beer Store","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Systembolaget":{"tags":{"name":"Systembolaget","shop":"alcohol"},"name":"Systembolaget","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/LCBO":{"tags":{"name":"LCBO","shop":"alcohol"},"name":"LCBO","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Ароматный мир":{"tags":{"name":"Ароматный мир","shop":"alcohol"},"name":"Ароматный мир","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Bargain Booze":{"tags":{"name":"Bargain Booze","shop":"alcohol"},"name":"Bargain Booze","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Nicolas":{"tags":{"name":"Nicolas","shop":"alcohol"},"name":"Nicolas","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/BWS":{"tags":{"name":"BWS","shop":"alcohol"},"name":"BWS","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Botilleria":{"tags":{"name":"Botilleria","shop":"alcohol"},"name":"Botilleria","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/SAQ":{"tags":{"name":"SAQ","shop":"alcohol"},"name":"SAQ","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Gall & Gall":{"tags":{"name":"Gall & Gall","shop":"alcohol"},"name":"Gall & Gall","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/alcohol/Живое пиво":{"tags":{"name":"Живое пиво","shop":"alcohol"},"name":"Живое пиво","icon":"alcohol-shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"shop/bakery/Kamps":{"tags":{"name":"Kamps","shop":"bakery"},"name":"Kamps","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Banette":{"tags":{"name":"Banette","shop":"bakery"},"name":"Banette","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Bäckerei Schmidt":{"tags":{"name":"Bäckerei Schmidt","shop":"bakery"},"name":"Bäckerei Schmidt","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Anker":{"tags":{"name":"Anker","shop":"bakery"},"name":"Anker","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Hofpfisterei":{"tags":{"name":"Hofpfisterei","shop":"bakery"},"name":"Hofpfisterei","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Greggs":{"tags":{"name":"Greggs","shop":"bakery"},"name":"Greggs","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Oebel":{"tags":{"name":"Oebel","shop":"bakery"},"name":"Oebel","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Boulangerie":{"tags":{"name":"Boulangerie","shop":"bakery"},"name":"Boulangerie","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Stadtbäckerei":{"tags":{"name":"Stadtbäckerei","shop":"bakery"},"name":"Stadtbäckerei","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Steinecke":{"tags":{"name":"Steinecke","shop":"bakery"},"name":"Steinecke","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Ihle":{"tags":{"name":"Ihle","shop":"bakery"},"name":"Ihle","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Goldilocks":{"tags":{"name":"Goldilocks","shop":"bakery"},"name":"Goldilocks","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Dat Backhus":{"tags":{"name":"Dat Backhus","shop":"bakery"},"name":"Dat Backhus","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/K&U":{"tags":{"name":"K&U","shop":"bakery"},"name":"K&U","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Der Beck":{"tags":{"name":"Der Beck","shop":"bakery"},"name":"Der Beck","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Thürmann":{"tags":{"name":"Thürmann","shop":"bakery"},"name":"Thürmann","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Backwerk":{"tags":{"name":"Backwerk","shop":"bakery"},"name":"Backwerk","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Schäfer's":{"tags":{"name":"Schäfer's","shop":"bakery"},"name":"Schäfer's","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Panaderia":{"tags":{"name":"Panaderia","shop":"bakery"},"name":"Panaderia","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Goeken backen":{"tags":{"name":"Goeken backen","shop":"bakery"},"name":"Goeken backen","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Stadtbäckerei Junge":{"tags":{"name":"Stadtbäckerei Junge","shop":"bakery"},"name":"Stadtbäckerei Junge","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Boulangerie Patisserie":{"tags":{"name":"Boulangerie Patisserie","shop":"bakery"},"name":"Boulangerie Patisserie","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Paul":{"tags":{"name":"Paul","shop":"bakery"},"name":"Paul","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Хлеб":{"tags":{"name":"Хлеб","shop":"bakery"},"name":"Хлеб","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Пекарня":{"tags":{"name":"Пекарня","shop":"bakery"},"name":"Пекарня","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/bakery/Кулиничи":{"tags":{"name":"Кулиничи","shop":"bakery"},"name":"Кулиничи","icon":"bakery","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Sports Direct":{"tags":{"name":"Sports Direct","shop":"sports"},"name":"Sports Direct","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Decathlon":{"tags":{"name":"Decathlon","shop":"sports"},"name":"Decathlon","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Intersport":{"tags":{"name":"Intersport","shop":"sports"},"name":"Intersport","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Sports Authority":{"tags":{"name":"Sports Authority","shop":"sports"},"name":"Sports Authority","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Спортмастер":{"tags":{"name":"Спортмастер","shop":"sports"},"name":"Спортмастер","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Sport 2000":{"tags":{"name":"Sport 2000","shop":"sports"},"name":"Sport 2000","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/sports/Dick's Sporting Goods":{"tags":{"name":"Dick's Sporting Goods","shop":"sports"},"name":"Dick's Sporting Goods","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Tedi":{"tags":{"name":"Tedi","shop":"variety_store"},"name":"Tedi","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Dollarama":{"tags":{"name":"Dollarama","shop":"variety_store"},"name":"Dollarama","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Family Dollar":{"tags":{"name":"Family Dollar","shop":"variety_store"},"name":"Family Dollar","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/variety_store/Dollar Tree":{"tags":{"name":"Dollar Tree","shop":"variety_store"},"name":"Dollar Tree","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Fressnapf":{"tags":{"name":"Fressnapf","shop":"pet"},"name":"Fressnapf","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/PetSmart":{"tags":{"name":"PetSmart","shop":"pet"},"name":"PetSmart","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Das Futterhaus":{"tags":{"name":"Das Futterhaus","shop":"pet"},"name":"Das Futterhaus","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Pets at Home":{"tags":{"name":"Pets at Home","shop":"pet"},"name":"Pets at Home","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Petco":{"tags":{"name":"Petco","shop":"pet"},"name":"Petco","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/pet/Зоомагазин":{"tags":{"name":"Зоомагазин","shop":"pet"},"name":"Зоомагазин","icon":"dog-park","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Deichmann":{"tags":{"name":"Deichmann","shop":"shoes"},"name":"Deichmann","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Reno":{"tags":{"name":"Reno","shop":"shoes"},"name":"Reno","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Ecco":{"tags":{"name":"Ecco","shop":"shoes"},"name":"Ecco","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Clarks":{"tags":{"name":"Clarks","shop":"shoes"},"name":"Clarks","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/La Halle aux Chaussures":{"tags":{"name":"La Halle aux Chaussures","shop":"shoes"},"name":"La Halle aux Chaussures","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Brantano":{"tags":{"name":"Brantano","shop":"shoes"},"name":"Brantano","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Geox":{"tags":{"name":"Geox","shop":"shoes"},"name":"Geox","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Salamander":{"tags":{"name":"Salamander","shop":"shoes"},"name":"Salamander","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Обувь":{"tags":{"name":"Обувь","shop":"shoes"},"name":"Обувь","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Payless Shoe Source":{"tags":{"name":"Payless Shoe Source","shop":"shoes"},"name":"Payless Shoe Source","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Famous Footwear":{"tags":{"name":"Famous Footwear","shop":"shoes"},"name":"Famous Footwear","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Quick Schuh":{"tags":{"name":"Quick Schuh","shop":"shoes"},"name":"Quick Schuh","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Shoe Zone":{"tags":{"name":"Shoe Zone","shop":"shoes"},"name":"Shoe Zone","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Foot Locker":{"tags":{"name":"Foot Locker","shop":"shoes"},"name":"Foot Locker","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/Bata":{"tags":{"name":"Bata","shop":"shoes"},"name":"Bata","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/shoes/ЦентрОбувь":{"tags":{"name":"ЦентрОбувь","shop":"shoes"},"name":"ЦентрОбувь","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/La Grande Récré":{"tags":{"name":"La Grande Récré","shop":"toys"},"name":"La Grande Récré","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Toys R Us":{"tags":{"name":"Toys R Us","shop":"toys"},"name":"Toys R Us","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Intertoys":{"tags":{"name":"Intertoys","shop":"toys"},"name":"Intertoys","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Детский мир":{"tags":{"name":"Детский мир","shop":"toys"},"name":"Детский мир","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/toys/Игрушки":{"tags":{"name":"Игрушки","shop":"toys"},"name":"Игрушки","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/Flight Centre":{"tags":{"name":"Flight Centre","shop":"travel_agency"},"name":"Flight Centre","icon":"suitcase","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/travel_agency/Thomas Cook":{"tags":{"name":"Thomas Cook","shop":"travel_agency"},"name":"Thomas Cook","icon":"suitcase","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Bijou Brigitte":{"tags":{"name":"Bijou Brigitte","shop":"jewelry"},"name":"Bijou Brigitte","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Christ":{"tags":{"name":"Christ","shop":"jewelry"},"name":"Christ","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/jewelry/Swarovski":{"tags":{"name":"Swarovski","shop":"jewelry"},"name":"Swarovski","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Fielmann":{"tags":{"name":"Fielmann","shop":"optician"},"name":"Fielmann","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Apollo Optik":{"tags":{"name":"Apollo Optik","shop":"optician"},"name":"Apollo Optik","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Vision Express":{"tags":{"name":"Vision Express","shop":"optician"},"name":"Vision Express","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Оптика":{"tags":{"name":"Оптика","shop":"optician"},"name":"Оптика","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Optic 2000":{"tags":{"name":"Optic 2000","shop":"optician"},"name":"Optic 2000","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Alain Afflelou":{"tags":{"name":"Alain Afflelou","shop":"optician"},"name":"Alain Afflelou","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Specsavers":{"tags":{"name":"Specsavers","shop":"optician"},"name":"Specsavers","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Krys":{"tags":{"name":"Krys","shop":"optician"},"name":"Krys","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/optician/Atol":{"tags":{"name":"Atol","shop":"optician"},"name":"Atol","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/Blockbuster":{"tags":{"name":"Blockbuster","shop":"video"},"name":"Blockbuster","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/video/World of Video":{"tags":{"name":"World of Video","shop":"video"},"name":"World of Video","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Билайн":{"tags":{"name":"Билайн","shop":"mobile_phone"},"name":"Билайн","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/ソフトバンクショップ (SoftBank shop)":{"tags":{"name":"ソフトバンクショップ (SoftBank shop)","shop":"mobile_phone"},"name":"ソフトバンクショップ (SoftBank shop)","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Vodafone":{"tags":{"name":"Vodafone","shop":"mobile_phone"},"name":"Vodafone","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/O2":{"tags":{"name":"O2","shop":"mobile_phone"},"name":"O2","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Carphone Warehouse":{"tags":{"name":"Carphone Warehouse","shop":"mobile_phone"},"name":"Carphone Warehouse","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Orange":{"tags":{"name":"Orange","shop":"mobile_phone"},"name":"Orange","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Verizon Wireless":{"tags":{"name":"Verizon Wireless","shop":"mobile_phone"},"name":"Verizon Wireless","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Sprint":{"tags":{"name":"Sprint","shop":"mobile_phone"},"name":"Sprint","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/T-Mobile":{"tags":{"name":"T-Mobile","shop":"mobile_phone"},"name":"T-Mobile","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/МТС":{"tags":{"name":"МТС","shop":"mobile_phone"},"name":"МТС","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Евросеть":{"tags":{"name":"Евросеть","shop":"mobile_phone"},"name":"Евросеть","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Bell":{"tags":{"name":"Bell","shop":"mobile_phone"},"name":"Bell","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/The Phone House":{"tags":{"name":"The Phone House","shop":"mobile_phone"},"name":"The Phone House","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/SFR":{"tags":{"name":"SFR","shop":"mobile_phone"},"name":"SFR","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Связной":{"tags":{"name":"Связной","shop":"mobile_phone"},"name":"Связной","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Мегафон":{"tags":{"name":"Мегафон","shop":"mobile_phone"},"name":"Мегафон","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/AT&T":{"tags":{"name":"AT&T","shop":"mobile_phone"},"name":"AT&T","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/ドコモショップ (docomo shop)":{"tags":{"name":"ドコモショップ (docomo shop)","shop":"mobile_phone"},"name":"ドコモショップ (docomo shop)","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/au":{"tags":{"name":"au","shop":"mobile_phone"},"name":"au","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Movistar":{"tags":{"name":"Movistar","shop":"mobile_phone"},"name":"Movistar","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Bitė":{"tags":{"name":"Bitė","shop":"mobile_phone"},"name":"Bitė","icon":"mobilephone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/computer/PC World":{"tags":{"name":"PC World","shop":"computer"},"name":"PC World","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/computer/DNS":{"tags":{"name":"DNS","shop":"computer"},"name":"DNS","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Klier":{"tags":{"name":"Klier","shop":"hairdresser"},"name":"Klier","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Supercuts":{"tags":{"name":"Supercuts","shop":"hairdresser"},"name":"Supercuts","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Hairkiller":{"tags":{"name":"Hairkiller","shop":"hairdresser"},"name":"Hairkiller","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Great Clips":{"tags":{"name":"Great Clips","shop":"hairdresser"},"name":"Great Clips","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Парикмахерская":{"tags":{"name":"Парикмахерская","shop":"hairdresser"},"name":"Парикмахерская","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Стиль":{"tags":{"name":"Стиль","shop":"hairdresser"},"name":"Стиль","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Franck Provost":{"tags":{"name":"Franck Provost","shop":"hairdresser"},"name":"Franck Provost","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hairdresser/Салон красоты":{"tags":{"name":"Салон красоты","shop":"hairdresser"},"name":"Салон красоты","icon":"hairdresser","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/1000 мелочей":{"tags":{"name":"1000 мелочей","shop":"hardware"},"name":"1000 мелочей","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/hardware/Хозтовары":{"tags":{"name":"Хозтовары","shop":"hardware"},"name":"Хозтовары","icon":"shop","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/motorcycle/Yamaha":{"tags":{"name":"Yamaha","shop":"motorcycle"},"name":"Yamaha","icon":"scooter","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true}};
18953 var defaults = {"area":["category-landuse","category-building","category-water-area","leisure/park","amenity/hospital","amenity/place_of_worship","amenity/cafe","amenity/restaurant","area"],"line":["category-road","category-rail","category-path","category-water-line","category-barrier","power/line","line"],"point":["leisure/park","amenity/hospital","amenity/place_of_worship","amenity/cafe","amenity/restaurant","amenity/fast_food","amenity/bar","amenity/bank","shop/supermarket","point"],"vertex":["highway/crosswalk","highway/crossing","railway/level_crossing","highway/traffic_signals","highway/turning_circle","traffic_calming","highway/mini_roundabout","highway/motorway_junction","vertex"],"relation":["category-route","category-restriction","type/boundary","type/multipolygon","type/site","relation"]};
18955 var categories = {"category-barrier":{"geometry":"line","name":"Barrier Features","icon":"roadblock","members":["barrier/fence","barrier/wall","barrier/ditch","barrier/gate","barrier"]},"category-building":{"geometry":"area","name":"Building Features","icon":"building","members":["building","building/house","building/apartments","building/commercial","building/industrial","building/residential"]},"category-golf":{"geometry":"area","name":"Golf Features","icon":"golf","members":["golf/fairway","golf/green","golf/lateral_water_hazard_area","golf/rough","golf/bunker","golf/tee","golf/water_hazard_area"]},"category-landuse":{"geometry":"area","name":"Land Use Features","icon":"land-use","members":["landuse/residential","landuse/industrial","landuse/commercial","landuse/retail","landuse/farmland","landuse/farmyard","landuse/forest","landuse/meadow","landuse/cemetery","landuse/military"]},"category-path":{"geometry":"line","name":"Path Features","icon":"category-path","members":["highway/pedestrian","footway/crosswalk","footway/sidewalk","highway/steps","highway/path","highway/footway","highway/cycleway","highway/bridleway"]},"category-rail":{"geometry":"line","name":"Rail Features","icon":"category-rail","members":["railway/rail","railway/subway","railway/tram","railway/monorail","railway/disused","railway/abandoned"]},"category-restriction":{"geometry":"relation","name":"Restriction Features","icon":"restriction","members":["type/restriction/no_left_turn","type/restriction/no_right_turn","type/restriction/no_straight_on","type/restriction/no_u_turn","type/restriction/only_left_turn","type/restriction/only_right_turn","type/restriction/only_straight_on","type/restriction"]},"category-road":{"geometry":"line","name":"Road Features","icon":"category-roads","members":["highway/residential","highway/motorway","highway/trunk","highway/primary","highway/secondary","highway/tertiary","highway/unclassified","highway/service","highway/track","highway/motorway_link","highway/trunk_link","highway/primary_link","highway/secondary_link","highway/tertiary_link","highway/road"]},"category-route":{"geometry":"relation","name":"Route Features","icon":"route","members":["type/route/road","type/route/bicycle","type/route/foot","type/route/hiking","type/route/horse","type/route/bus","type/route/train","type/route/tram","type/route/ferry","type/route/power","type/route/pipeline","type/route/detour","type/route_master","type/route"]},"category-water-area":{"geometry":"area","name":"Water Features","icon":"water","members":["natural/water/lake","natural/water/pond","natural/water/reservoir","natural/water"]},"category-water-line":{"geometry":"line","name":"Water Features","icon":"category-water","members":["waterway/river","waterway/stream","waterway/canal","waterway/ditch","waterway/drain"]}};
18957 var fields = {"access_simple":{"key":"access","type":"combo","label":"Allowed Access","options":["permissive","private","customers","no"]},"access_toilets":{"key":"access","type":"combo","label":"Access","options":["yes","permissive","private","customers"]},"access":{"keys":["access","foot","motor_vehicle","bicycle","horse"],"reference":{"key":"access"},"type":"access","label":"Allowed Access","placeholder":"Not Specified","strings":{"types":{"access":"All","foot":"Foot","motor_vehicle":"Motor Vehicles","bicycle":"Bicycles","horse":"Horses"},"options":{"yes":{"title":"Allowed","description":"Access permitted by law; a right of way"},"no":{"title":"Prohibited","description":"Access not permitted to the general public"},"permissive":{"title":"Permissive","description":"Access permitted until such time as the owner revokes the permission"},"private":{"title":"Private","description":"Access permitted only with permission of the owner on an individual basis"},"designated":{"title":"Designated","description":"Access permitted according to signs or specific local laws"},"destination":{"title":"Destination","description":"Access permitted only to reach a destination"},"dismount":{"title":"Dismount","description":"Access permitted but rider must dismount"}}}},"address":{"type":"address","keys":["addr:city","addr:conscriptionnumber","addr:country","addr:district","addr:floor","addr:hamlet","addr:housename","addr:housenumber","addr:place","addr:postcode","addr:province","addr:state","addr:street","addr:subdistrict","addr:suburb"],"reference":{"key":"addr"},"icon":"address","universal":true,"label":"Address","strings":{"placeholders":{"city":"City","conscriptionnumber":"123","country":"Country","district":"District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","place":"Place","postcode":"Postcode","province":"Province","state":"State","street":"Street","subdistrict":"Subdistrict","suburb":"Suburb"}}},"admin_level":{"key":"admin_level","type":"number","label":"Admin Level"},"aerialway":{"key":"aerialway","type":"typeCombo","label":"Type"},"aerialway/access":{"key":"aerialway:access","type":"combo","label":"Access","strings":{"options":{"entry":"Entry","exit":"Exit","both":"Both"}}},"aerialway/bubble":{"key":"aerialway:bubble","type":"check","label":"Bubble"},"aerialway/capacity":{"key":"aerialway:capacity","type":"number","label":"Capacity (per hour)","placeholder":"500, 2500, 5000..."},"aerialway/duration":{"key":"aerialway:duration","type":"number","label":"Duration (minutes)","placeholder":"1, 2, 3..."},"aerialway/heating":{"key":"aerialway:heating","type":"check","label":"Heated"},"aerialway/occupancy":{"key":"aerialway:occupancy","type":"number","label":"Occupancy","placeholder":"2, 4, 8..."},"aerialway/summer/access":{"key":"aerialway:summer:access","type":"combo","label":"Access (summer)","strings":{"options":{"entry":"Entry","exit":"Exit","both":"Both"}}},"aeroway":{"key":"aeroway","type":"typeCombo","label":"Type"},"amenity":{"key":"amenity","type":"typeCombo","label":"Type"},"area/highway":{"key":"area:highway","type":"typeCombo","label":"Type"},"artist":{"key":"artist_name","type":"text","label":"Artist"},"artwork_type":{"key":"artwork_type","type":"combo","label":"Type"},"atm":{"key":"atm","type":"check","label":"ATM"},"backrest":{"key":"backrest","type":"check","label":"Backrest"},"barrier":{"key":"barrier","type":"typeCombo","label":"Type"},"bath/open_air":{"key":"bath:open_air","label":"Open Air","type":"check"},"bath/sand_bath":{"key":"bath:sand_bath","label":"Sand Bath","type":"check"},"bath/type":{"key":"bath:type","type":"combo","label":"Specialty","strings":{"options":{"onsen":"Japanese Onsen","foot_bath":"Foot Bath","hot_spring":"Hot Spring"}}},"beauty":{"key":"beauty","type":"combo","label":"Shop Type"},"bench":{"key":"bench","type":"check","label":"Bench"},"bicycle_parking":{"key":"bicycle_parking","type":"combo","label":"Type"},"bin":{"key":"bin","type":"check","label":"Waste Bin"},"blood_components":{"key":"blood:","type":"multiCombo","label":"Blood Components","strings":{"options":{"whole":"whole blood","plasma":"plasma","platelets":"platelets","stemcells":"stem cell samples"}}},"board_type":{"key":"board_type","type":"typeCombo","label":"Type"},"boundary":{"key":"boundary","type":"combo","label":"Type"},"brand":{"key":"brand","type":"text","label":"Brand"},"building_area":{"key":"building","type":"combo","default":"yes","geometry":"area","label":"Building"},"building":{"key":"building","type":"combo","label":"Building"},"camera/direction":{"key":"camera:direction","type":"number","label":"Direction (Degrees Clockwise)","placeholder":"45, 90, 180, 270"},"camera/mount":{"key":"camera:mount","type":"combo","label":"Camera Mount"},"camera/type":{"key":"camera:type","type":"combo","label":"Camera Type","strings":{"options":{"fixed":"Fixed","panning":"Panning","dome":"Dome"}}},"capacity":{"key":"capacity","type":"number","label":"Capacity","placeholder":"50, 100, 200..."},"cardinal_direction":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"N":"North","E":"East","S":"South","W":"West","NE":"Northeast","SE":"Southeast","SW":"Southwest","NW":"Northwest","NNE":"North-northeast","ENE":"East-northeast","ESE":"East-southeast","SSE":"South-southeast","SSW":"South-southwest","WSW":"West-southwest","WNW":"West-northwest","NNW":"North-northwest"}}},"clock_direction":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"clockwise":"Clockwise","anticlockwise":"Counterclockwise"}}},"collection_times":{"key":"collection_times","type":"text","label":"Collection Times"},"construction":{"key":"construction","type":"combo","label":"Type"},"contact/webcam":{"key":"contact:webcam","type":"url","icon":"website","label":"Webcam URL","placeholder":"http://example.com/"},"content":{"key":"content","type":"combo","label":"Contents"},"country":{"key":"country","type":"combo","label":"Country"},"covered":{"key":"covered","type":"check","label":"Covered"},"craft":{"key":"craft","type":"typeCombo","label":"Type"},"crop":{"key":"crop","type":"combo","label":"Crop"},"crossing":{"key":"crossing","type":"combo","label":"Type"},"cuisine":{"key":"cuisine","type":"combo","label":"Cuisine"},"currency_multi":{"key":"currency:","type":"multiCombo","label":"Currency Types"},"cycle_network":{"key":"cycle_network","type":"networkCombo","label":"Network"},"cycleway":{"keys":["cycleway:left","cycleway:right"],"reference":{"key":"cycleway"},"type":"cycleway","label":"Bike Lanes","placeholder":"none","strings":{"types":{"cycleway:left":"Left side","cycleway:right":"Right side"},"options":{"none":{"title":"None","description":"No bike lane"},"lane":{"title":"Standard bike lane","description":"A bike lane separated from auto traffic by a painted line"},"shared_lane":{"title":"Shared bike lane","description":"A bike lane with no separation from auto traffic"},"track":{"title":"Bike track","description":"A bike lane separated from traffic by a physical barrier"},"share_busway":{"title":"Bike lane shared with bus","description":"A bike lane shared with a bus lane"},"opposite_lane":{"title":"Opposite bike lane","description":"A bike lane that travels in the opposite direction of traffic"},"opposite":{"title":"Contraflow bike lane","description":"A bike lane that travels in both directions on a one-way street"}}}},"date":{"key":"date","type":"check","label":"Date"},"delivery":{"key":"delivery","type":"check","label":"Delivery"},"denomination":{"key":"denomination","type":"combo","label":"Denomination"},"denotation":{"key":"denotation","type":"combo","label":"Denotation"},"description":{"key":"description","type":"textarea","label":"Description","universal":true},"diaper":{"key":"diaper","type":"combo","label":"Diaper Changing Available","options":["yes","no","room","1","2","3","4","5"]},"display":{"key":"display","type":"combo","label":"Display","options":["analog","digital","sundial","unorthodox"]},"dock":{"key":"dock","type":"combo","label":"Type"},"drive_through":{"key":"drive_through","type":"check","label":"Drive-Through"},"electrified":{"key":"electrified","type":"combo","label":"Electrification","placeholder":"Contact Line, Electrified Rail...","strings":{"options":{"contact_line":"Contact Line","rail":"Electrified Rail","yes":"Yes (unspecified)","no":"No"}}},"elevation":{"key":"ele","type":"number","icon":"elevation","universal":true,"label":"Elevation"},"emergency":{"key":"emergency","type":"check","label":"Emergency"},"entrance":{"key":"entrance","type":"typeCombo","label":"Type"},"except":{"key":"except","type":"combo","label":"Exceptions"},"fax":{"key":"fax","type":"tel","label":"Fax","placeholder":"+31 42 123 4567"},"fee":{"key":"fee","type":"check","label":"Fee"},"fence_type":{"key":"fence_type","type":"combo","label":"Type"},"fire_hydrant/type":{"key":"fire_hydrant:type","type":"combo","label":"Type","strings":{"options":{"pillar":"Pillar/Aboveground","underground":"Underground","wall":"Wall","pond":"Pond"}}},"fixme":{"key":"fixme","type":"textarea","label":"Fix Me","universal":true},"fuel_multi":{"key":"fuel:","type":"multiCombo","label":"Fuel Types"},"fuel":{"key":"fuel","type":"combo","label":"Fuel"},"gauge":{"key":"gauge","type":"combo","label":"Gauge"},"gender":{"type":"radio","keys":["male","female","unisex"],"label":"Gender","placeholder":"Unknown","strings":{"options":{"male":"Male","female":"Female","unisex":"Unisex"}}},"generator/method":{"key":"generator:method","type":"combo","label":"Method"},"generator/source":{"key":"generator:source","type":"combo","label":"Source"},"generator/type":{"key":"generator:type","type":"combo","label":"Type"},"golf_hole":{"key":"ref","type":"text","label":"Reference","placeholder":"Hole number (1-18)"},"handicap":{"key":"handicap","type":"number","label":"Handicap","placeholder":"1-18"},"handrail":{"key":"handrail","type":"check","label":"Handrail"},"height":{"key":"height","type":"number","label":"Height (Meters)"},"highway":{"key":"highway","type":"typeCombo","label":"Type"},"historic":{"key":"historic","type":"typeCombo","label":"Type"},"hoops":{"key":"hoops","type":"number","label":"Hoops","placeholder":"1, 2, 4..."},"iata":{"key":"iata","type":"text","label":"IATA"},"icao":{"key":"icao","type":"text","label":"ICAO"},"incline_steps":{"key":"incline","type":"combo","label":"Incline","strings":{"options":{"up":"Up","down":"Down"}}},"incline":{"key":"incline","type":"combo","label":"Incline"},"indoor":{"key":"indoor","type":"check","label":"Indoor"},"information":{"key":"information","type":"typeCombo","label":"Type"},"internet_access":{"key":"internet_access","type":"combo","label":"Internet Access","strings":{"options":{"yes":"Yes","no":"No","wlan":"Wifi","wired":"Wired","terminal":"Terminal"}}},"internet_access/fee":{"key":"internet_access:fee","type":"check","label":"Internet Access Fee"},"internet_access/ssid":{"key":"internet_access:ssid","type":"text","label":"SSID (Network Name)"},"kerb":{"key":"kerb","type":"combo","label":"Curb Ramp"},"lamp_type":{"key":"lamp_type","type":"combo","label":"Type"},"landuse":{"key":"landuse","type":"typeCombo","label":"Type"},"lanes":{"key":"lanes","type":"number","label":"Lanes","placeholder":"1, 2, 3..."},"layer":{"key":"layer","type":"combo","label":"Layer"},"leaf_cycle_singular":{"key":"leaf_cycle","type":"combo","label":"Leaf Cycle","strings":{"options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous"}}},"leaf_cycle":{"key":"leaf_cycle","type":"combo","label":"Leaf Cycle","strings":{"options":{"evergreen":"Evergreen","deciduous":"Deciduous","semi_evergreen":"Semi-Evergreen","semi_deciduous":"Semi-Deciduous","mixed":"Mixed"}}},"leaf_type_singular":{"key":"leaf_type","type":"combo","label":"Leaf Type","strings":{"options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","leafless":"Leafless"}}},"leaf_type":{"key":"leaf_type","type":"combo","label":"Leaf Type","strings":{"options":{"broadleaved":"Broadleaved","needleleaved":"Needleleaved","mixed":"Mixed","leafless":"Leafless"}}},"leisure":{"key":"leisure","type":"typeCombo","label":"Type"},"length":{"key":"length","type":"number","label":"Length (Meters)"},"level":{"key":"level","type":"combo","label":"Level","universal":true},"levels":{"key":"building:levels","type":"number","label":"Levels","placeholder":"2, 4, 6..."},"lit":{"key":"lit","type":"check","label":"Lit"},"location":{"key":"location","type":"combo","label":"Location"},"man_made":{"key":"man_made","type":"typeCombo","label":"Type"},"map_size":{"key":"map_size","type":"typeCombo","label":"Coverage"},"map_type":{"key":"map_type","type":"typeCombo","label":"Type"},"maxheight":{"key":"maxheight","type":"combo","label":"Max Height","placeholder":"4, 4.5, 5, 14'0\", 14'6\", 15'0\"","snake_case":false},"maxspeed":{"key":"maxspeed","type":"maxspeed","label":"Speed Limit","placeholder":"40, 50, 60..."},"maxstay":{"key":"maxstay","type":"combo","label":"Max Stay","options":["15 min","30 min","45 min","1 hr","1.5 hr","2 hr","2.5 hr","3 hr","4 hr","1 day","2 day"],"snake_case":false},"mtb/scale":{"key":"mtb:scale","type":"combo","label":"Mountain Biking Difficulty","placeholder":"0, 1, 2, 3...","strings":{"options":{"0":"0: Solid gravel/packed earth, no obstacles, wide curves","1":"1: Some loose surface, small obstacles, wide curves","2":"2: Much loose surface, large obstacles, easy hairpins","3":"3: Slippery surface, large obstacles, tight hairpins","4":"4: Loose surface or boulders, dangerous hairpins","5":"5: Maximum difficulty, boulder fields, landslides","6":"6: Not rideable except by the very best mountain bikers"}}},"mtb/scale/imba":{"key":"mtb:scale:imba","type":"combo","label":"IMBA Trail Difficulty","placeholder":"Easy, Medium, Difficult...","strings":{"options":{"0":"Easiest (white circle)","1":"Easy (green circle)","2":"Medium (blue square)","3":"Difficult (black diamond)","4":"Extremely Difficult (double black diamond)"}}},"mtb/scale/uphill":{"key":"mtb:scale:uphill","type":"combo","label":"Mountain Biking Uphill Difficulty","placeholder":"0, 1, 2, 3...","strings":{"options":{"0":"0: Avg. incline <10%, gravel/packed earth, no obstacles","1":"1: Avg. incline <15%, gravel/packed earth, few small objects","2":"2: Avg. incline <20%, stable surface, fistsize rocks/roots","3":"3: Avg. incline <25%, variable surface, fistsize rocks/branches","4":"4: Avg. incline <30%, poor condition, big rocks/branches","5":"5: Very steep, bike generally needs to be pushed or carried"}}},"name":{"key":"name","type":"localized","label":"Name","placeholder":"Common name (if any)"},"natural":{"key":"natural","type":"typeCombo","label":"Natural"},"network_bicycle":{"key":"network","type":"combo","label":"Network Type","placeholder":"Local, Regional, National, International","strings":{"options":{"lcn":"Local","rcn":"Regional","ncn":"National","icn":"International"}}},"network_foot":{"key":"network","type":"combo","label":"Network Type","placeholder":"Local, Regional, National, International","strings":{"options":{"lwn":"Local","rwn":"Regional","nwn":"National","iwn":"International"}}},"network_horse":{"key":"network","type":"combo","label":"Network Type","placeholder":"Local, Regional, National, International","strings":{"options":{"lhn":"Local","rhn":"Regional","nhn":"National","ihn":"International"}}},"network_road":{"key":"network","type":"networkCombo","label":"Network"},"network":{"key":"network","type":"text","label":"Network"},"note":{"key":"note","type":"textarea","universal":true,"icon":"note","label":"Note"},"office":{"key":"office","type":"typeCombo","label":"Type"},"oneway_yes":{"key":"oneway","type":"check","label":"One Way","strings":{"options":{"undefined":"Assumed to be Yes","yes":"Yes","no":"No"}}},"oneway":{"key":"oneway","type":"check","label":"One Way","strings":{"options":{"undefined":"Assumed to be No","yes":"Yes","no":"No"}}},"opening_hours":{"key":"opening_hours","type":"text","label":"Hours"},"operator":{"key":"operator","type":"text","label":"Operator"},"outdoor_seating":{"key":"outdoor_seating","type":"combo","label":"Outdoor Seating"},"par":{"key":"par","type":"number","label":"Par","placeholder":"3, 4, 5..."},"parallel_direction":{"key":"direction","type":"combo","label":"Direction","strings":{"options":{"forward":"Forward","backward":"Backward"}}},"park_ride":{"key":"park_ride","type":"check","label":"Park and Ride"},"parking":{"key":"parking","type":"combo","label":"Type","strings":{"options":{"surface":"Surface","multi-storey":"Multilevel","underground":"Underground","sheds":"Sheds","carports":"Carports","garage_boxes":"Garage Boxes","lane":"Roadside Lane"}}},"payment_multi":{"key":"payment:","type":"multiCombo","label":"Payment Types"},"phone":{"key":"phone","type":"tel","icon":"telephone","universal":true,"label":"Phone","placeholder":"+31 42 123 4567"},"piste/difficulty":{"key":"piste:difficulty","type":"combo","label":"Difficulty","placeholder":"Easy, Intermediate, Advanced...","strings":{"options":{"novice":"Novice (instructional)","easy":"Easy (green circle)","intermediate":"Intermediate (blue square)","advanced":"Advanced (black diamond)","expert":"Expert (double black diamond)","freeride":"Freeride (off-piste)","extreme":"Extreme (climbing equipment required)"}}},"piste/grooming":{"key":"piste:grooming","type":"combo","label":"Grooming","strings":{"options":{"classic":"Classic","mogul":"Mogul","backcountry":"Backcountry","classic+skating":"Classic and Skating","scooter":"Scooter/Snowmobile","skating":"Skating"}}},"piste/type":{"key":"piste:type","type":"typeCombo","label":"Type","strings":{"options":{"downhill":"Downhill","nordic":"Nordic","skitour":"Skitour","sled":"Sled","hike":"Hike","sleigh":"Sleigh","ice_skate":"Ice Skate","snow_park":"Snow Park","playground":"Playground"}}},"place":{"key":"place","type":"typeCombo","label":"Type"},"population":{"key":"population","type":"text","label":"Population"},"power_supply":{"key":"power_supply","type":"check","label":"Power Supply"},"power":{"key":"power","type":"typeCombo","label":"Type"},"railway":{"key":"railway","type":"typeCombo","label":"Type"},"recycling_accepts":{"key":"recycling:","type":"multiCombo","label":"Accepts"},"recycling_type":{"key":"recycling_type","default":"container","type":"combo","label":"Recycling Type","strings":{"options":{"container":"Container","centre":"Recycling Center"}}},"ref":{"key":"ref","type":"text","label":"Reference"},"relation":{"key":"type","type":"combo","label":"Type"},"religion":{"key":"religion","type":"combo","label":"Religion"},"restriction":{"key":"restriction","type":"combo","label":"Type"},"restrictions":{"type":"restrictions","geometry":"vertex","icon":"restrictions","reference":{"rtype":"restriction"},"label":"Turn Restrictions"},"rooms":{"key":"rooms","type":"number","label":"Rooms"},"route_master":{"key":"route_master","type":"combo","label":"Type"},"route":{"key":"route","type":"combo","label":"Type"},"sac_scale":{"key":"sac_scale","type":"combo","label":"Hiking Difficulty","placeholder":"Mountain Hiking, Alpine Hiking...","strings":{"options":{"hiking":"T1: Hiking","mountain_hiking":"T2: Mountain Hiking","demanding_mountain_hiking":"T3: Demanding Mountain Hiking","alpine_hiking":"T4: Alpine Hiking","demanding_alpine_hiking":"T5: Demanding Alpine Hiking","difficult_alpine_hiking":"T6: Difficult Alpine Hiking"}}},"sanitary_dump_station":{"key":"sanitary_dump_station","type":"check","label":"Toilet Disposal"},"seasonal":{"key":"seasonal","type":"check","label":"Seasonal"},"second_hand":{"key":"second_hand","type":"combo","label":"Sells Used","placeholder":"Yes, No, Only","strings":{"options":{"yes":"Yes","no":"No","only":"Only"}}},"service_rail":{"key":"service","type":"combo","label":"Service Type","strings":{"options":{"spur":"Spur","yard":"Yard","siding":"Siding","crossover":"Crossover"}}},"service":{"key":"service","type":"combo","label":"Type","options":["parking_aisle","driveway","alley","emergency_access","drive-through"]},"service/bicycle":{"key":"service:bicycle:","type":"multiCombo","label":"Services"},"shelter_type":{"key":"shelter_type","type":"combo","label":"Type"},"shelter":{"key":"shelter","type":"check","label":"Shelter"},"shop":{"key":"shop","type":"typeCombo","label":"Type"},"site":{"key":"site","type":"combo","label":"Type"},"smoking":{"key":"smoking","type":"combo","label":"Smoking","placeholder":"No, Separated, Yes...","strings":{"options":{"no":"No smoking anywhere","separated":"In smoking areas, not physically isolated","isolated":"In smoking areas, physically isolated","outside":"Allowed outside","yes":"Allowed everywhere","dedicated":"Dedicated to smokers (e.g. smokers' club)"}}},"smoothness":{"key":"smoothness","type":"combo","label":"Smoothness","placeholder":"Thin Rollers, Wheels, Off-Road...","strings":{"options":{"excellent":"Thin Rollers: rollerblade, skateboard","good":"Thin Wheels: racing bike","intermediate":"Wheels: city bike, wheelchair, scooter","bad":"Robust Wheels: trekking bike, car, rickshaw","very_bad":"High Clearance: light duty off-road vehicle","horrible":"Off-Road: heavy duty off-road vehicle","very_horrible":"Specialized off-road: tractor, ATV","impassable":"Impassable / No wheeled vehicle"}}},"social_facility_for":{"key":"social_facility:for","type":"radio","label":"People served","placeholder":"Homeless, Disabled, Child, etc","options":["abused","child","disabled","diseased","drug_addicted","homeless","juvenile","mental_health","migrant","orphan","senior","underprivileged","unemployed","victim"]},"source":{"key":"source","type":"text","icon":"source","universal":true,"label":"Source"},"sport_ice":{"key":"sport","type":"combo","label":"Sport","options":["skating","hockey","multi","curling","ice_stock"]},"sport_racing":{"key":"sport","type":"combo","label":"Sport","options":["cycling","dog_racing","horse_racing","karting","motor","motocross","running"]},"sport":{"key":"sport","type":"combo","label":"Sport"},"stars":{"key":"stars","type":"number","label":"Stars"},"stop":{"key":"stop","type":"combo","label":"Stop Type","strings":{"options":{"all":"All Ways","minor":"Minor Road"}}},"structure":{"type":"radio","keys":["bridge","tunnel","embankment","cutting","ford"],"label":"Structure","placeholder":"Unknown","strings":{"options":{"bridge":"Bridge","tunnel":"Tunnel","embankment":"Embankment","cutting":"Cutting","ford":"Ford"}}},"studio":{"key":"studio","type":"combo","label":"Type"},"substation":{"key":"substation","type":"typeCombo","label":"Type"},"supervised":{"key":"supervised","type":"check","label":"Supervised"},"support":{"key":"support","type":"combo","label":"Support"},"surface":{"key":"surface","type":"combo","label":"Surface"},"surveillance":{"key":"surveillance","type":"combo","label":"Surveillance Kind"},"surveillance/type":{"key":"surveillance:type","type":"combo","label":"Surveillance Type","strings":{"options":{"camera":"Camera","guard":"Guard","ALPR":"Automatic License Plate Reader"}}},"surveillance/zone":{"key":"surveillance:zone","type":"combo","label":"Surveillance Zone"},"tactile_paving":{"key":"tactile_paving","type":"check","label":"Tactile Paving"},"takeaway":{"key":"takeaway","type":"combo","label":"Takeaway","placeholder":"Yes, No, Takeaway Only...","strings":{"options":{"yes":"Yes","no":"No","only":"Takeaway Only"}}},"toilets/disposal":{"key":"toilets:disposal","type":"combo","label":"Disposal","strings":{"options":{"flush":"Flush","pitlatrine":"Pit/Latrine","chemical":"Chemical","bucket":"Bucket"}}},"tourism":{"key":"tourism","type":"typeCombo","label":"Type"},"tower/construction":{"key":"tower:construction","type":"combo","label":"Construction","placeholder":"Guyed, Lattice, Concealed, ..."},"tower/type":{"key":"tower:type","type":"combo","label":"Type"},"tracktype":{"key":"tracktype","type":"combo","label":"Track Type","placeholder":"Solid, Mostly Solid, Soft...","strings":{"options":{"grade1":"Solid: paved or heavily compacted hardcore surface","grade2":"Mostly Solid: gravel/rock with some soft material mixed in","grade3":"Even mixture of hard and soft materials","grade4":"Mostly Soft: soil/sand/grass with some hard material mixed in","grade5":"Soft: soil/sand/grass"}}},"traffic_calming":{"key":"traffic_calming","type":"typeCombo","label":"Type"},"traffic_signals":{"key":"traffic_signals","type":"combo","label":"Type","default":"signal"},"trail_visibility":{"key":"trail_visibility","type":"combo","label":"Trail Visibility","placeholder":"Excellent, Good, Bad...","strings":{"options":{"excellent":"Excellent: unambiguous path or markers everywhere","good":"Good: markers visible, sometimes require searching","intermediate":"Intermediate: few markers, path mostly visible","bad":"Bad: no markers, path sometimes invisible/pathless","horrible":"Horrible: often pathless, some orientation skills required","no":"No: pathless, excellent orientation skills required"}}},"trees":{"key":"trees","type":"combo","label":"Trees"},"tunnel":{"key":"tunnel","type":"combo","label":"Tunnel"},"vending":{"key":"vending","type":"combo","label":"Type of Goods"},"visibility":{"key":"visibility","type":"combo","label":"Visibility","strings":{"options":{"house":"Up to 5m (16ft)","street":"5 to 20m (16 to 65ft)","area":"Over 20m (65ft)"}}},"wall":{"key":"wall","type":"combo","label":"Type"},"water_point":{"key":"water_point","type":"check","label":"Water Point"},"water":{"key":"water","type":"combo","label":"Type"},"waterway":{"key":"waterway","type":"typeCombo","label":"Type"},"website":{"key":"website","type":"url","icon":"website","placeholder":"http://example.com/","universal":true,"label":"Website"},"wetland":{"key":"wetland","type":"combo","label":"Type"},"wheelchair":{"key":"wheelchair","type":"radio","options":["yes","limited","no"],"icon":"wheelchair","universal":true,"label":"Wheelchair Access"},"width":{"key":"width","type":"number","label":"Width (Meters)"},"wikipedia":{"key":"wikipedia","keys":["wikipedia","wikidata"],"type":"wikipedia","icon":"wikipedia","universal":true,"label":"Wikipedia"}};
18960 imagery: dataImagery,
18963 defaults: defaults,
18964 categories: categories,
18969 function osmEntity$$1(attrs) {
18970 // For prototypal inheritance.
18971 if (this instanceof osmEntity$$1) return;
18973 // Create the appropriate subtype.
18974 if (attrs && attrs.type) {
18975 return osmEntity$$1[attrs.type].apply(this, arguments);
18976 } else if (attrs && attrs.id) {
18977 return osmEntity$$1[osmEntity$$1.id.type(attrs.id)].apply(this, arguments);
18980 // Initialize a generic Entity (used only in tests).
18981 return (new osmEntity$$1()).initialize(arguments);
18985 osmEntity$$1.id = function(type) {
18986 return osmEntity$$1.id.fromOSM(type, osmEntity$$1.id.next[type]--);
18990 osmEntity$$1.id.next = {
18991 node: -1, way: -1, relation: -1
18995 osmEntity$$1.id.fromOSM = function(type, id) {
18996 return type[0] + id;
19000 osmEntity$$1.id.toOSM = function(id) {
19001 return id.slice(1);
19005 osmEntity$$1.id.type = function(id) {
19006 return { 'n': 'node', 'w': 'way', 'r': 'relation' }[id[0]];
19010 // A function suitable for use as the second argument to d3.selection#data().
19011 osmEntity$$1.key = function(entity) {
19012 return entity.id + 'v' + (entity.v || 0);
19016 osmEntity$$1.prototype = {
19021 initialize: function(sources) {
19022 for (var i = 0; i < sources.length; ++i) {
19023 var source = sources[i];
19024 for (var prop in source) {
19025 if (Object.prototype.hasOwnProperty.call(source, prop)) {
19026 if (source[prop] === undefined) {
19029 this[prop] = source[prop];
19035 if (!this.id && this.type) {
19036 this.id = osmEntity$$1.id(this.type);
19038 if (!this.hasOwnProperty('visible')) {
19039 this.visible = true;
19043 Object.freeze(this);
19044 Object.freeze(this.tags);
19046 if (this.loc) Object.freeze(this.loc);
19047 if (this.nodes) Object.freeze(this.nodes);
19048 if (this.members) Object.freeze(this.members);
19055 copy: function(resolver, copies) {
19056 if (copies[this.id])
19057 return copies[this.id];
19059 var copy = osmEntity$$1(this, {id: undefined, user: undefined, version: undefined});
19060 copies[this.id] = copy;
19066 osmId: function() {
19067 return osmEntity$$1.id.toOSM(this.id);
19071 isNew: function() {
19072 return this.osmId() < 0;
19076 update: function(attrs) {
19077 return osmEntity$$1(this, attrs, {v: 1 + (this.v || 0)});
19081 mergeTags: function(tags) {
19082 var merged = lodash.clone(this.tags), changed = false;
19083 for (var k in tags) {
19084 var t1 = merged[k],
19089 } else if (t1 !== t2) {
19091 merged[k] = lodash.union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
19094 return changed ? this.update({tags: merged}) : this;
19098 intersects: function(extent, resolver) {
19099 return this.extent(resolver).intersects(extent);
19103 isUsed: function(resolver) {
19104 return lodash.without(Object.keys(this.tags), 'area').length > 0 ||
19105 resolver.parentRelations(this).length > 0;
19109 hasInterestingTags: function() {
19110 return lodash.keys(this.tags).some(osmIsInterestingTag);
19114 isHighwayIntersection: function() {
19119 deprecatedTags: function() {
19120 var tags = lodash.toPairs(this.tags);
19121 var deprecated = {};
19123 dataDeprecated.forEach(function(d) {
19124 var match = lodash.toPairs(d.old)[0];
19125 tags.forEach(function(t) {
19126 if (t[0] === match[0] &&
19127 (t[1] === match[1] || match[1] === '*')) {
19128 deprecated[t[0]] = t[1];
19137 function geoExtent$$1(min, max) {
19138 if (!(this instanceof geoExtent$$1)) return new geoExtent$$1(min, max);
19139 if (min instanceof geoExtent$$1) {
19141 } else if (min && min.length === 2 && min[0].length === 2 && min[1].length === 2) {
19145 this[0] = min || [ Infinity, Infinity];
19146 this[1] = max || min || [-Infinity, -Infinity];
19150 geoExtent$$1.prototype = new Array(2);
19152 lodash.extend(geoExtent$$1.prototype, {
19154 equals: function (obj) {
19155 return this[0][0] === obj[0][0] &&
19156 this[0][1] === obj[0][1] &&
19157 this[1][0] === obj[1][0] &&
19158 this[1][1] === obj[1][1];
19162 extend: function(obj) {
19163 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19164 return geoExtent$$1(
19165 [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
19166 [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
19171 _extend: function(extent) {
19172 this[0][0] = Math.min(extent[0][0], this[0][0]);
19173 this[0][1] = Math.min(extent[0][1], this[0][1]);
19174 this[1][0] = Math.max(extent[1][0], this[1][0]);
19175 this[1][1] = Math.max(extent[1][1], this[1][1]);
19180 return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
19184 center: function() {
19185 return [(this[0][0] + this[1][0]) / 2,
19186 (this[0][1] + this[1][1]) / 2];
19190 rectangle: function() {
19191 return [this[0][0], this[0][1], this[1][0], this[1][1]];
19196 return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
19200 polygon: function() {
19202 [this[0][0], this[0][1]],
19203 [this[0][0], this[1][1]],
19204 [this[1][0], this[1][1]],
19205 [this[1][0], this[0][1]],
19206 [this[0][0], this[0][1]]
19211 contains: function(obj) {
19212 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19213 return obj[0][0] >= this[0][0] &&
19214 obj[0][1] >= this[0][1] &&
19215 obj[1][0] <= this[1][0] &&
19216 obj[1][1] <= this[1][1];
19220 intersects: function(obj) {
19221 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19222 return obj[0][0] <= this[1][0] &&
19223 obj[0][1] <= this[1][1] &&
19224 obj[1][0] >= this[0][0] &&
19225 obj[1][1] >= this[0][1];
19229 intersection: function(obj) {
19230 if (!this.intersects(obj)) return new geoExtent$$1();
19231 return new geoExtent$$1(
19232 [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
19233 [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
19238 percentContainedIn: function(obj) {
19239 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19240 var a1 = this.intersection(obj).area(),
19243 if (a1 === Infinity || a2 === Infinity || a1 === 0 || a2 === 0) {
19251 padByMeters: function(meters) {
19252 var dLat = geoMetersToLat(meters),
19253 dLon = geoMetersToLon(meters, this.center()[1]);
19254 return geoExtent$$1(
19255 [this[0][0] - dLon, this[0][1] - dLat],
19256 [this[1][0] + dLon, this[1][1] + dLat]
19261 toParam: function() {
19262 return this.rectangle().join(',');
19267 var version = "4.4.0";
19269 var ascending = function(a, b) {
19270 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
19273 var bisector = function(compare) {
19274 if (compare.length === 1) compare = ascendingComparator(compare);
19276 left: function(a, x, lo, hi) {
19277 if (lo == null) lo = 0;
19278 if (hi == null) hi = a.length;
19280 var mid = lo + hi >>> 1;
19281 if (compare(a[mid], x) < 0) lo = mid + 1;
19286 right: function(a, x, lo, hi) {
19287 if (lo == null) lo = 0;
19288 if (hi == null) hi = a.length;
19290 var mid = lo + hi >>> 1;
19291 if (compare(a[mid], x) > 0) hi = mid;
19299 function ascendingComparator(f) {
19300 return function(d, x) {
19301 return ascending(f(d), x);
19305 var ascendingBisect = bisector(ascending);
19306 var bisectRight = ascendingBisect.right;
19307 var bisectLeft = ascendingBisect.left;
19309 var descending = function(a, b) {
19310 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
19313 var number = function(x) {
19314 return x === null ? NaN : +x;
19317 var variance = function(array, f) {
19318 var n = array.length,
19328 if (!isNaN(a = number(array[i]))) {
19338 if (!isNaN(a = number(f(array[i], i, array)))) {
19346 if (j > 1) return s / (j - 1);
19349 var deviation = function(array, f) {
19350 var v = variance(array, f);
19351 return v ? Math.sqrt(v) : v;
19354 var extent = function(array, f) {
19362 while (++i < n) if ((b = array[i]) != null && b >= b) { a = c = b; break; }
19363 while (++i < n) if ((b = array[i]) != null) {
19370 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; }
19371 while (++i < n) if ((b = f(array[i], i, array)) != null) {
19380 var array = Array.prototype;
19382 var slice = array.slice;
19383 var map = array.map;
19385 var constant$1 = function(x) {
19386 return function() {
19391 var identity = function(x) {
19395 var range = function(start, stop, step) {
19396 start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
19399 n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
19400 range = new Array(n);
19403 range[i] = start + i * step;
19409 var e10 = Math.sqrt(50);
19410 var e5 = Math.sqrt(10);
19411 var e2 = Math.sqrt(2);
19413 var ticks = function(start, stop, count) {
19414 var step = tickStep(start, stop, count);
19416 Math.ceil(start / step) * step,
19417 Math.floor(stop / step) * step + step / 2, // inclusive
19422 function tickStep(start, stop, count) {
19423 var step0 = Math.abs(stop - start) / Math.max(0, count),
19424 step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
19425 error = step0 / step1;
19426 if (error >= e10) step1 *= 10;
19427 else if (error >= e5) step1 *= 5;
19428 else if (error >= e2) step1 *= 2;
19429 return stop < start ? -step1 : step1;
19432 var sturges = function(values) {
19433 return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
19436 var histogram = function() {
19437 var value = identity,
19439 threshold = sturges;
19441 function histogram(data) {
19445 values = new Array(n);
19447 for (i = 0; i < n; ++i) {
19448 values[i] = value(data[i], i, data);
19451 var xz = domain(values),
19454 tz = threshold(values, x0, x1);
19456 // Convert number of thresholds into uniform thresholds.
19457 if (!Array.isArray(tz)) tz = ticks(x0, x1, tz);
19459 // Remove any thresholds outside the domain.
19461 while (tz[0] <= x0) tz.shift(), --m;
19462 while (tz[m - 1] >= x1) tz.pop(), --m;
19464 var bins = new Array(m + 1),
19467 // Initialize bins.
19468 for (i = 0; i <= m; ++i) {
19469 bin = bins[i] = [];
19470 bin.x0 = i > 0 ? tz[i - 1] : x0;
19471 bin.x1 = i < m ? tz[i] : x1;
19474 // Assign data to bins by value, ignoring any outside the domain.
19475 for (i = 0; i < n; ++i) {
19477 if (x0 <= x && x <= x1) {
19478 bins[bisectRight(tz, x, 0, m)].push(data[i]);
19485 histogram.value = function(_) {
19486 return arguments.length ? (value = typeof _ === "function" ? _ : constant$1(_), histogram) : value;
19489 histogram.domain = function(_) {
19490 return arguments.length ? (domain = typeof _ === "function" ? _ : constant$1([_[0], _[1]]), histogram) : domain;
19493 histogram.thresholds = function(_) {
19494 return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant$1(slice.call(_)) : constant$1(_), histogram) : threshold;
19500 var threshold = function(array, p, f) {
19501 if (f == null) f = number;
19502 if (!(n = array.length)) return;
19503 if ((p = +p) <= 0 || n < 2) return +f(array[0], 0, array);
19504 if (p >= 1) return +f(array[n - 1], n - 1, array);
19508 a = +f(array[i], i, array),
19509 b = +f(array[i + 1], i + 1, array);
19510 return a + (b - a) * (h - i);
19513 var freedmanDiaconis = function(values, min, max) {
19514 values = map.call(values, number).sort(ascending);
19515 return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));
19518 var scott = function(values, min, max) {
19519 return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
19522 var max = function(array, f) {
19529 while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
19530 while (++i < n) if ((b = array[i]) != null && b > a) a = b;
19534 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
19535 while (++i < n) if ((b = f(array[i], i, array)) != null && b > a) a = b;
19541 var mean = function(array, f) {
19549 while (++i < n) if (!isNaN(a = number(array[i]))) s += a; else --j;
19553 while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) s += a; else --j;
19556 if (j) return s / j;
19559 var median = function(array, f) {
19566 while (++i < n) if (!isNaN(a = number(array[i]))) numbers.push(a);
19570 while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) numbers.push(a);
19573 return threshold(numbers.sort(ascending), 0.5);
19576 var merge = function(arrays) {
19577 var n = arrays.length,
19584 while (++i < n) j += arrays[i].length;
19585 merged = new Array(j);
19591 merged[--j] = array[m];
19598 var min = function(array, f) {
19605 while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
19606 while (++i < n) if ((b = array[i]) != null && a > b) a = b;
19610 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
19611 while (++i < n) if ((b = f(array[i], i, array)) != null && a > b) a = b;
19617 var pairs = function(array) {
19618 var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
19619 while (i < n) pairs[i] = [p, p = array[++i]];
19623 var permute = function(array, indexes) {
19624 var i = indexes.length, permutes = new Array(i);
19625 while (i--) permutes[i] = array[indexes[i]];
19629 var scan = function(array, compare) {
19630 if (!(n = array.length)) return;
19637 if (!compare) compare = ascending;
19639 while (++i < n) if (compare(xi = array[i], xj) < 0 || compare(xj, xj) !== 0) xj = xi, j = i;
19641 if (compare(xj, xj) === 0) return j;
19644 var shuffle = function(array, i0, i1) {
19645 var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),
19650 i = Math.random() * m-- | 0;
19652 array[m + i0] = array[i + i0];
19659 var sum = function(array, f) {
19666 while (++i < n) if (a = +array[i]) s += a; // Note: zero and null are equivalent.
19670 while (++i < n) if (a = +f(array[i], i, array)) s += a;
19676 var transpose = function(matrix) {
19677 if (!(n = matrix.length)) return [];
19678 for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
19679 for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
19680 row[j] = matrix[j][i];
19686 function length(d) {
19690 var zip = function() {
19691 return transpose(arguments);
19698 Map.prototype = map$1.prototype = {
19700 has: function(key) {
19701 return (prefix + key) in this;
19703 get: function(key) {
19704 return this[prefix + key];
19706 set: function(key, value) {
19707 this[prefix + key] = value;
19710 remove: function(key) {
19711 var property = prefix + key;
19712 return property in this && delete this[property];
19714 clear: function() {
19715 for (var property in this) if (property[0] === prefix) delete this[property];
19719 for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
19722 values: function() {
19724 for (var property in this) if (property[0] === prefix) values.push(this[property]);
19727 entries: function() {
19729 for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
19734 for (var property in this) if (property[0] === prefix) ++size;
19737 empty: function() {
19738 for (var property in this) if (property[0] === prefix) return false;
19741 each: function(f) {
19742 for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
19746 function map$1(object, f) {
19749 // Copy constructor.
19750 if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
19752 // Index array by numeric index or specified key function.
19753 else if (Array.isArray(object)) {
19758 if (f == null) while (++i < n) map.set(i, object[i]);
19759 else while (++i < n) map.set(f(o = object[i], i, object), o);
19762 // Convert object to map.
19763 else if (object) for (var key in object) map.set(key, object[key]);
19768 var nest = function() {
19775 function apply(array, depth, createResult, setResult) {
19776 if (depth >= keys.length) return rollup != null
19777 ? rollup(array) : (sortValues != null
19778 ? array.sort(sortValues)
19783 key = keys[depth++],
19786 valuesByKey = map$1(),
19788 result = createResult();
19791 if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
19792 values.push(value);
19794 valuesByKey.set(keyValue, [value]);
19798 valuesByKey.each(function(values, key) {
19799 setResult(result, key, apply(values, depth, createResult, setResult));
19805 function entries(map, depth) {
19806 if (++depth > keys.length) return map;
19807 var array, sortKey = sortKeys[depth - 1];
19808 if (rollup != null && depth >= keys.length) array = map.entries();
19809 else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
19810 return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
19814 object: function(array) { return apply(array, 0, createObject, setObject); },
19815 map: function(array) { return apply(array, 0, createMap, setMap); },
19816 entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
19817 key: function(d) { keys.push(d); return nest; },
19818 sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
19819 sortValues: function(order) { sortValues = order; return nest; },
19820 rollup: function(f) { rollup = f; return nest; }
19824 function createObject() {
19828 function setObject(object, key, value) {
19829 object[key] = value;
19832 function createMap() {
19836 function setMap(map, key, value) {
19837 map.set(key, value);
19842 var proto = map$1.prototype;
19844 Set.prototype = set.prototype = {
19847 add: function(value) {
19849 this[prefix + value] = value;
19852 remove: proto.remove,
19853 clear: proto.clear,
19854 values: proto.keys,
19856 empty: proto.empty,
19860 function set(object, f) {
19863 // Copy constructor.
19864 if (object instanceof Set) object.each(function(value) { set.add(value); });
19866 // Otherwise, assume it’s an array.
19868 var i = -1, n = object.length;
19869 if (f == null) while (++i < n) set.add(object[i]);
19870 else while (++i < n) set.add(f(object[i], i, object));
19876 var keys = function(map) {
19878 for (var key in map) keys.push(key);
19882 var values = function(map) {
19884 for (var key in map) values.push(map[key]);
19888 var entries = function(map) {
19890 for (var key in map) entries.push({key: key, value: map[key]});
19894 var uniform = function(min, max) {
19895 min = min == null ? 0 : +min;
19896 max = max == null ? 1 : +max;
19897 if (arguments.length === 1) max = min, min = 0;
19899 return function() {
19900 return Math.random() * max + min;
19904 var normal = function(mu, sigma) {
19906 mu = mu == null ? 0 : +mu;
19907 sigma = sigma == null ? 1 : +sigma;
19908 return function() {
19911 // If available, use the second previously-generated uniform random.
19912 if (x != null) y = x, x = null;
19914 // Otherwise, generate a new x and y.
19916 x = Math.random() * 2 - 1;
19917 y = Math.random() * 2 - 1;
19919 } while (!r || r > 1);
19921 return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
19925 var logNormal = function() {
19926 var randomNormal = normal.apply(this, arguments);
19927 return function() {
19928 return Math.exp(randomNormal());
19932 var irwinHall = function(n) {
19933 return function() {
19934 for (var sum = 0, i = 0; i < n; ++i) sum += Math.random();
19939 var bates = function(n) {
19940 var randomIrwinHall = irwinHall(n);
19941 return function() {
19942 return randomIrwinHall() / n;
19946 var exponential = function(lambda) {
19947 return function() {
19948 return -Math.log(1 - Math.random()) / lambda;
19952 function linear(t) {
19956 function quadIn(t) {
19960 function quadOut(t) {
19961 return t * (2 - t);
19964 function quadInOut(t) {
19965 return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
19968 function cubicIn(t) {
19972 function cubicOut(t) {
19973 return --t * t * t + 1;
19976 function cubicInOut(t) {
19977 return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
19982 var polyIn = (function custom(e) {
19985 function polyIn(t) {
19986 return Math.pow(t, e);
19989 polyIn.exponent = custom;
19994 var polyOut = (function custom(e) {
19997 function polyOut(t) {
19998 return 1 - Math.pow(1 - t, e);
20001 polyOut.exponent = custom;
20006 var polyInOut = (function custom(e) {
20009 function polyInOut(t) {
20010 return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
20013 polyInOut.exponent = custom;
20019 var halfPi = pi / 2;
20021 function sinIn(t) {
20022 return 1 - Math.cos(t * halfPi);
20025 function sinOut(t) {
20026 return Math.sin(t * halfPi);
20029 function sinInOut(t) {
20030 return (1 - Math.cos(pi * t)) / 2;
20033 function expIn(t) {
20034 return Math.pow(2, 10 * t - 10);
20037 function expOut(t) {
20038 return 1 - Math.pow(2, -10 * t);
20041 function expInOut(t) {
20042 return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
20045 function circleIn(t) {
20046 return 1 - Math.sqrt(1 - t * t);
20049 function circleOut(t) {
20050 return Math.sqrt(1 - --t * t);
20053 function circleInOut(t) {
20054 return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
20066 var b0 = 1 / b1 / b1;
20068 function bounceIn(t) {
20069 return 1 - bounceOut(1 - t);
20072 function bounceOut(t) {
20073 return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;
20076 function bounceInOut(t) {
20077 return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
20080 var overshoot = 1.70158;
20082 var backIn = (function custom(s) {
20085 function backIn(t) {
20086 return t * t * ((s + 1) * t - s);
20089 backIn.overshoot = custom;
20094 var backOut = (function custom(s) {
20097 function backOut(t) {
20098 return --t * t * ((s + 1) * t + s) + 1;
20101 backOut.overshoot = custom;
20106 var backInOut = (function custom(s) {
20109 function backInOut(t) {
20110 return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
20113 backInOut.overshoot = custom;
20118 var tau = 2 * Math.PI;
20122 var elasticIn = (function custom(a, p) {
20123 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
20125 function elasticIn(t) {
20126 return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
20129 elasticIn.amplitude = function(a) { return custom(a, p * tau); };
20130 elasticIn.period = function(p) { return custom(a, p); };
20133 })(amplitude, period);
20135 var elasticOut = (function custom(a, p) {
20136 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
20138 function elasticOut(t) {
20139 return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
20142 elasticOut.amplitude = function(a) { return custom(a, p * tau); };
20143 elasticOut.period = function(p) { return custom(a, p); };
20146 })(amplitude, period);
20148 var elasticInOut = (function custom(a, p) {
20149 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
20151 function elasticInOut(t) {
20152 return ((t = t * 2 - 1) < 0
20153 ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
20154 : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
20157 elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
20158 elasticInOut.period = function(p) { return custom(a, p); };
20160 return elasticInOut;
20161 })(amplitude, period);
20163 var d3polygonArea = function(polygon) {
20165 n = polygon.length,
20167 b = polygon[n - 1],
20173 area += a[1] * b[0] - a[0] * b[1];
20179 var d3polygonCentroid = function(polygon) {
20181 n = polygon.length,
20185 b = polygon[n - 1],
20192 k += c = a[0] * b[1] - b[0] * a[1];
20193 x += (a[0] + b[0]) * c;
20194 y += (a[1] + b[1]) * c;
20197 return k *= 3, [x / k, y / k];
20200 // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
20201 // the 3D cross product in a quadrant I Cartesian coordinate system (+x is
20202 // right, +y is up). Returns a positive value if ABC is counter-clockwise,
20203 // negative if clockwise, and zero if the points are collinear.
20204 var cross = function(a, b, c) {
20205 return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
20208 function lexicographicOrder(a, b) {
20209 return a[0] - b[0] || a[1] - b[1];
20212 // Computes the upper convex hull per the monotone chain algorithm.
20213 // Assumes points.length >= 3, is sorted by x, unique in y.
20214 // Returns an array of indices into points in left-to-right order.
20215 function computeUpperHullIndexes(points) {
20216 var n = points.length,
20220 for (var i = 2; i < n; ++i) {
20221 while (size > 1 && cross(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
20222 indexes[size++] = i;
20225 return indexes.slice(0, size); // remove popped points
20228 var d3polygonHull = function(points) {
20229 if ((n = points.length) < 3) return null;
20233 sortedPoints = new Array(n),
20234 flippedPoints = new Array(n);
20236 for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
20237 sortedPoints.sort(lexicographicOrder);
20238 for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
20240 var upperIndexes = computeUpperHullIndexes(sortedPoints),
20241 lowerIndexes = computeUpperHullIndexes(flippedPoints);
20243 // Construct the hull polygon, removing possible duplicate endpoints.
20244 var skipLeft = lowerIndexes[0] === upperIndexes[0],
20245 skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
20248 // Add upper hull in right-to-l order.
20249 // Then add lower hull in left-to-right order.
20250 for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
20251 for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
20256 var contains = function(polygon, point) {
20257 var n = polygon.length,
20258 p = polygon[n - 1],
20259 x = point[0], y = point[1],
20260 x0 = p[0], y0 = p[1],
20264 for (var i = 0; i < n; ++i) {
20265 p = polygon[i], x1 = p[0], y1 = p[1];
20266 if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
20273 var length$1 = function(polygon) {
20275 n = polygon.length,
20276 b = polygon[n - 1],
20291 perimeter += Math.sqrt(xa * xa + ya * ya);
20297 var pi$1 = Math.PI;
20298 var tau$1 = 2 * pi$1;
20299 var epsilon = 1e-6;
20300 var tauEpsilon = tau$1 - epsilon;
20303 this._x0 = this._y0 = // start of current subpath
20304 this._x1 = this._y1 = null; // end of current subpath
20312 Path.prototype = path.prototype = {
20314 moveTo: function(x, y) {
20315 this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
20317 closePath: function() {
20318 if (this._x1 !== null) {
20319 this._x1 = this._x0, this._y1 = this._y0;
20323 lineTo: function(x, y) {
20324 this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
20326 quadraticCurveTo: function(x1, y1, x, y) {
20327 this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
20329 bezierCurveTo: function(x1, y1, x2, y2, x, y) {
20330 this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
20332 arcTo: function(x1, y1, x2, y2, r) {
20333 x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
20340 l01_2 = x01 * x01 + y01 * y01;
20342 // Is the radius negative? Error.
20343 if (r < 0) throw new Error("negative radius: " + r);
20345 // Is this path empty? Move to (x1,y1).
20346 if (this._x1 === null) {
20347 this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
20350 // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
20351 else if (!(l01_2 > epsilon)) {}
20353 // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
20354 // Equivalently, is (x1,y1) coincident with (x2,y2)?
20355 // Or, is the radius zero? Line to (x1,y1).
20356 else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
20357 this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
20360 // Otherwise, draw an arc!
20364 l21_2 = x21 * x21 + y21 * y21,
20365 l20_2 = x20 * x20 + y20 * y20,
20366 l21 = Math.sqrt(l21_2),
20367 l01 = Math.sqrt(l01_2),
20368 l = r * Math.tan((pi$1 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
20372 // If the start tangent is not coincident with (x0,y0), line to.
20373 if (Math.abs(t01 - 1) > epsilon) {
20374 this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
20377 this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
20380 arc: function(x, y, r, a0, a1, ccw) {
20381 x = +x, y = +y, r = +r;
20382 var dx = r * Math.cos(a0),
20383 dy = r * Math.sin(a0),
20387 da = ccw ? a0 - a1 : a1 - a0;
20389 // Is the radius negative? Error.
20390 if (r < 0) throw new Error("negative radius: " + r);
20392 // Is this path empty? Move to (x0,y0).
20393 if (this._x1 === null) {
20394 this._ += "M" + x0 + "," + y0;
20397 // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
20398 else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
20399 this._ += "L" + x0 + "," + y0;
20402 // Is this arc empty? We’re done.
20405 // Is this a complete circle? Draw two arcs to complete the circle.
20406 if (da > tauEpsilon) {
20407 this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
20410 // Otherwise, draw an arc!
20412 if (da < 0) da = da % tau$1 + tau$1;
20413 this._ += "A" + r + "," + r + ",0," + (+(da >= pi$1)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
20416 rect: function(x, y, w, h) {
20417 this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
20419 toString: function() {
20424 var tree_add = function(d) {
20425 var x = +this._x.call(null, d),
20426 y = +this._y.call(null, d);
20427 return add(this.cover(x, y), x, y, d);
20430 function add(tree, x, y, d) {
20431 if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
20449 // If the tree is empty, initialize the root as a leaf.
20450 if (!node) return tree._root = leaf, tree;
20452 // Find the existing leaf for the new point, or add it.
20453 while (node.length) {
20454 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
20455 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
20456 if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
20459 // Is the new point is exactly coincident with the existing point?
20460 xp = +tree._x.call(null, node.data);
20461 yp = +tree._y.call(null, node.data);
20462 if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
20464 // Otherwise, split the leaf node until the old and new point are separated.
20466 parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
20467 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
20468 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
20469 } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
20470 return parent[j] = node, parent[i] = leaf, tree;
20473 function addAll(data) {
20474 var d, i, n = data.length,
20484 // Compute the points and their extent.
20485 for (i = 0; i < n; ++i) {
20486 if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
20489 if (x < x0) x0 = x;
20490 if (x > x1) x1 = x;
20491 if (y < y0) y0 = y;
20492 if (y > y1) y1 = y;
20495 // If there were no (valid) points, inherit the existing extent.
20496 if (x1 < x0) x0 = this._x0, x1 = this._x1;
20497 if (y1 < y0) y0 = this._y0, y1 = this._y1;
20499 // Expand the tree to cover the new points.
20500 this.cover(x0, y0).cover(x1, y1);
20502 // Add the new points.
20503 for (i = 0; i < n; ++i) {
20504 add(this, xz[i], yz[i], data[i]);
20510 var tree_cover = function(x, y) {
20511 if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
20518 // If the quadtree has no extent, initialize them.
20519 // Integer extent are necessary so that if we later double the extent,
20520 // the existing quadrant boundaries don’t change due to floating point error!
20522 x1 = (x0 = Math.floor(x)) + 1;
20523 y1 = (y0 = Math.floor(y)) + 1;
20526 // Otherwise, double repeatedly to cover.
20527 else if (x0 > x || x > x1 || y0 > y || y > y1) {
20533 switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
20535 do parent = new Array(4), parent[i] = node, node = parent;
20536 while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
20540 do parent = new Array(4), parent[i] = node, node = parent;
20541 while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
20545 do parent = new Array(4), parent[i] = node, node = parent;
20546 while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
20550 do parent = new Array(4), parent[i] = node, node = parent;
20551 while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
20556 if (this._root && this._root.length) this._root = node;
20559 // If the quadtree covers the point already, just return.
20569 var tree_data = function() {
20571 this.visit(function(node) {
20572 if (!node.length) do data.push(node.data); while (node = node.next)
20577 var tree_extent = function(_) {
20578 return arguments.length
20579 ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
20580 : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
20583 var Quad = function(node, x0, y0, x1, y1) {
20591 var tree_find = function(x, y, radius) {
20606 if (node) quads.push(new Quad(node, x0, y0, x3, y3));
20607 if (radius == null) radius = Infinity;
20609 x0 = x - radius, y0 = y - radius;
20610 x3 = x + radius, y3 = y + radius;
20614 while (q = quads.pop()) {
20616 // Stop searching if this quadrant can’t contain a closer node.
20617 if (!(node = q.node)
20618 || (x1 = q.x0) > x3
20619 || (y1 = q.y0) > y3
20620 || (x2 = q.x1) < x0
20621 || (y2 = q.y1) < y0) continue;
20623 // Bisect the current quadrant.
20625 var xm = (x1 + x2) / 2,
20626 ym = (y1 + y2) / 2;
20629 new Quad(node[3], xm, ym, x2, y2),
20630 new Quad(node[2], x1, ym, xm, y2),
20631 new Quad(node[1], xm, y1, x2, ym),
20632 new Quad(node[0], x1, y1, xm, ym)
20635 // Visit the closest quadrant first.
20636 if (i = (y >= ym) << 1 | (x >= xm)) {
20637 q = quads[quads.length - 1];
20638 quads[quads.length - 1] = quads[quads.length - 1 - i];
20639 quads[quads.length - 1 - i] = q;
20643 // Visit this point. (Visiting coincident points isn’t necessary!)
20645 var dx = x - +this._x.call(null, node.data),
20646 dy = y - +this._y.call(null, node.data),
20647 d2 = dx * dx + dy * dy;
20649 var d = Math.sqrt(radius = d2);
20650 x0 = x - d, y0 = y - d;
20651 x3 = x + d, y3 = y + d;
20660 var tree_remove = function(d) {
20661 if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
20681 // If the tree is empty, initialize the root as a leaf.
20682 if (!node) return this;
20684 // Find the leaf node for the point.
20685 // While descending, also retain the deepest parent with a non-removed sibling.
20686 if (node.length) while (true) {
20687 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
20688 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
20689 if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
20690 if (!node.length) break;
20691 if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
20694 // Find the point to remove.
20695 while (node.data !== d) if (!(previous = node, node = node.next)) return this;
20696 if (next = node.next) delete node.next;
20698 // If there are multiple coincident points, remove just the point.
20699 if (previous) return (next ? previous.next = next : delete previous.next), this;
20701 // If this is the root point, remove it.
20702 if (!parent) return this._root = next, this;
20704 // Remove this leaf.
20705 next ? parent[i] = next : delete parent[i];
20707 // If the parent now contains exactly one leaf, collapse superfluous parents.
20708 if ((node = parent[0] || parent[1] || parent[2] || parent[3])
20709 && node === (parent[3] || parent[2] || parent[1] || parent[0])
20711 if (retainer) retainer[j] = node;
20712 else this._root = node;
20718 function removeAll(data) {
20719 for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
20723 var tree_root = function() {
20727 var tree_size = function() {
20729 this.visit(function(node) {
20730 if (!node.length) do ++size; while (node = node.next)
20735 var tree_visit = function(callback) {
20736 var quads = [], q, node = this._root, child, x0, y0, x1, y1;
20737 if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
20738 while (q = quads.pop()) {
20739 if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
20740 var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
20741 if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
20742 if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
20743 if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
20744 if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
20750 var tree_visitAfter = function(callback) {
20751 var quads = [], next = [], q;
20752 if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
20753 while (q = quads.pop()) {
20756 var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
20757 if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
20758 if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
20759 if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
20760 if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
20764 while (q = next.pop()) {
20765 callback(q.node, q.x0, q.y0, q.x1, q.y1);
20770 function defaultX(d) {
20774 var tree_x = function(_) {
20775 return arguments.length ? (this._x = _, this) : this._x;
20778 function defaultY(d) {
20782 var tree_y = function(_) {
20783 return arguments.length ? (this._y = _, this) : this._y;
20786 function quadtree(nodes, x, y) {
20787 var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
20788 return nodes == null ? tree : tree.addAll(nodes);
20791 function Quadtree(x, y, x0, y0, x1, y1) {
20798 this._root = undefined;
20801 function leaf_copy(leaf) {
20802 var copy = {data: leaf.data}, next = copy;
20803 while (leaf = leaf.next) next = next.next = {data: leaf.data};
20807 var treeProto = quadtree.prototype = Quadtree.prototype;
20809 treeProto.copy = function() {
20810 var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
20815 if (!node) return copy;
20817 if (!node.length) return copy._root = leaf_copy(node), copy;
20819 nodes = [{source: node, target: copy._root = new Array(4)}];
20820 while (node = nodes.pop()) {
20821 for (var i = 0; i < 4; ++i) {
20822 if (child = node.source[i]) {
20823 if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
20824 else node.target[i] = leaf_copy(child);
20832 treeProto.add = tree_add;
20833 treeProto.addAll = addAll;
20834 treeProto.cover = tree_cover;
20835 treeProto.data = tree_data;
20836 treeProto.extent = tree_extent;
20837 treeProto.find = tree_find;
20838 treeProto.remove = tree_remove;
20839 treeProto.removeAll = removeAll;
20840 treeProto.root = tree_root;
20841 treeProto.size = tree_size;
20842 treeProto.visit = tree_visit;
20843 treeProto.visitAfter = tree_visitAfter;
20844 treeProto.x = tree_x;
20845 treeProto.y = tree_y;
20847 var slice$1 = [].slice;
20851 function Queue(size) {
20852 if (!(size >= 1)) throw new Error;
20855 this._error = null;
20861 this._start = 0; // inside a synchronous task callback?
20864 Queue.prototype = queue.prototype = {
20865 constructor: Queue,
20866 defer: function(callback) {
20867 if (typeof callback !== "function" || this._call) throw new Error;
20868 if (this._error != null) return this;
20869 var t = slice$1.call(arguments, 1);
20871 ++this._waiting, this._tasks.push(t);
20875 abort: function() {
20876 if (this._error == null) abort(this, new Error("abort"));
20879 await: function(callback) {
20880 if (typeof callback !== "function" || this._call) throw new Error;
20881 this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
20885 awaitAll: function(callback) {
20886 if (typeof callback !== "function" || this._call) throw new Error;
20887 this._call = callback;
20895 try { start(q); } // let the current task complete
20897 if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
20898 else if (!q._data) throw e; // await callback errored synchronously
20903 function start(q) {
20904 while (q._start = q._waiting && q._active < q._size) {
20905 var i = q._ended + q._active,
20910 --q._waiting, ++q._active;
20911 t = c.apply(null, t);
20912 if (!q._tasks[i]) continue; // task finished synchronously
20913 q._tasks[i] = t || noabort;
20917 function end(q, i) {
20918 return function(e, r) {
20919 if (!q._tasks[i]) return; // ignore multiple callbacks
20920 --q._active, ++q._ended;
20921 q._tasks[i] = null;
20922 if (q._error != null) return; // ignore secondary errors
20927 if (q._waiting) poke(q);
20928 else maybeNotify(q);
20933 function abort(q, e) {
20934 var i = q._tasks.length, t;
20935 q._error = e; // ignore active callbacks
20936 q._data = undefined; // allow gc
20937 q._waiting = NaN; // prevent starting
20940 if (t = q._tasks[i]) {
20941 q._tasks[i] = null;
20944 catch (e) { /* ignore */ }
20949 q._active = NaN; // allow notification
20953 function maybeNotify(q) {
20954 if (!q._active && q._call) {
20956 q._data = undefined; // allow gc
20957 q._call(q._error, d);
20961 function queue(concurrency) {
20962 return new Queue(arguments.length ? +concurrency : Infinity);
20965 var constant$2 = function(x) {
20966 return function constant() {
20971 var epsilon$1 = 1e-12;
20972 var pi$2 = Math.PI;
20973 var halfPi$1 = pi$2 / 2;
20974 var tau$2 = 2 * pi$2;
20976 function arcInnerRadius(d) {
20977 return d.innerRadius;
20980 function arcOuterRadius(d) {
20981 return d.outerRadius;
20984 function arcStartAngle(d) {
20985 return d.startAngle;
20988 function arcEndAngle(d) {
20992 function arcPadAngle(d) {
20993 return d && d.padAngle; // Note: optional!
20997 return x >= 1 ? halfPi$1 : x <= -1 ? -halfPi$1 : Math.asin(x);
21000 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
21001 var x10 = x1 - x0, y10 = y1 - y0,
21002 x32 = x3 - x2, y32 = y3 - y2,
21003 t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
21004 return [x0 + t * x10, y0 + t * y10];
21007 // Compute perpendicular offset line of length rc.
21008 // http://mathworld.wolfram.com/Circle-LineIntersection.html
21009 function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
21012 lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01),
21019 x00 = (x11 + x10) / 2,
21020 y00 = (y11 + y10) / 2,
21023 d2 = dx * dx + dy * dy,
21025 D = x11 * y10 - x10 * y11,
21026 d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)),
21027 cx0 = (D * dy - dx * d) / d2,
21028 cy0 = (-D * dx - dy * d) / d2,
21029 cx1 = (D * dy + dx * d) / d2,
21030 cy1 = (-D * dx + dy * d) / d2,
21036 // Pick the closer of the two intersection points.
21037 // TODO Is there a faster way to determine which intersection to use?
21038 if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
21045 x11: cx0 * (r1 / r - 1),
21046 y11: cy0 * (r1 / r - 1)
21050 var arc = function() {
21051 var innerRadius = arcInnerRadius,
21052 outerRadius = arcOuterRadius,
21053 cornerRadius = constant$2(0),
21055 startAngle = arcStartAngle,
21056 endAngle = arcEndAngle,
21057 padAngle = arcPadAngle,
21063 r0 = +innerRadius.apply(this, arguments),
21064 r1 = +outerRadius.apply(this, arguments),
21065 a0 = startAngle.apply(this, arguments) - halfPi$1,
21066 a1 = endAngle.apply(this, arguments) - halfPi$1,
21067 da = Math.abs(a1 - a0),
21070 if (!context) context = buffer = path();
21072 // Ensure that the outer radius is always larger than the inner radius.
21073 if (r1 < r0) r = r1, r1 = r0, r0 = r;
21076 if (!(r1 > epsilon$1)) context.moveTo(0, 0);
21078 // Or is it a circle or annulus?
21079 else if (da > tau$2 - epsilon$1) {
21080 context.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0));
21081 context.arc(0, 0, r1, a0, a1, !cw);
21082 if (r0 > epsilon$1) {
21083 context.moveTo(r0 * Math.cos(a1), r0 * Math.sin(a1));
21084 context.arc(0, 0, r0, a1, a0, cw);
21088 // Or is it a circular or annular sector?
21096 ap = padAngle.apply(this, arguments) / 2,
21097 rp = (ap > epsilon$1) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)),
21098 rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
21104 // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
21105 if (rp > epsilon$1) {
21106 var p0 = asin(rp / r0 * Math.sin(ap)),
21107 p1 = asin(rp / r1 * Math.sin(ap));
21108 if ((da0 -= p0 * 2) > epsilon$1) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
21109 else da0 = 0, a00 = a10 = (a0 + a1) / 2;
21110 if ((da1 -= p1 * 2) > epsilon$1) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
21111 else da1 = 0, a01 = a11 = (a0 + a1) / 2;
21114 var x01 = r1 * Math.cos(a01),
21115 y01 = r1 * Math.sin(a01),
21116 x10 = r0 * Math.cos(a10),
21117 y10 = r0 * Math.sin(a10);
21119 // Apply rounded corners?
21120 if (rc > epsilon$1) {
21121 var x11 = r1 * Math.cos(a11),
21122 y11 = r1 * Math.sin(a11),
21123 x00 = r0 * Math.cos(a00),
21124 y00 = r0 * Math.sin(a00);
21126 // Restrict the corner radius according to the sector angle.
21128 var oc = da0 > epsilon$1 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
21133 kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2),
21134 lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
21135 rc0 = Math.min(rc, (r0 - lc) / (kc - 1));
21136 rc1 = Math.min(rc, (r1 - lc) / (kc + 1));
21140 // Is the sector collapsed to a line?
21141 if (!(da1 > epsilon$1)) context.moveTo(x01, y01);
21143 // Does the sector’s outer ring have rounded corners?
21144 else if (rc1 > epsilon$1) {
21145 t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
21146 t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
21148 context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
21150 // Have the corners merged?
21151 if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
21153 // Otherwise, draw the two corners and the ring.
21155 context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
21156 context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
21157 context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
21161 // Or is the outer ring just a circular arc?
21162 else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
21164 // Is there no inner ring, and it’s a circular sector?
21165 // Or perhaps it’s an annular sector collapsed due to padding?
21166 if (!(r0 > epsilon$1) || !(da0 > epsilon$1)) context.lineTo(x10, y10);
21168 // Does the sector’s inner ring (or point) have rounded corners?
21169 else if (rc0 > epsilon$1) {
21170 t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
21171 t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
21173 context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
21175 // Have the corners merged?
21176 if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
21178 // Otherwise, draw the two corners and the ring.
21180 context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
21181 context.arc(0, 0, r0, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
21182 context.arc(t1.cx, t1.cy, rc0, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
21186 // Or is the inner ring just a circular arc?
21187 else context.arc(0, 0, r0, a10, a00, cw);
21190 context.closePath();
21192 if (buffer) return context = null, buffer + "" || null;
21195 arc.centroid = function() {
21196 var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
21197 a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$2 / 2;
21198 return [Math.cos(a) * r, Math.sin(a) * r];
21201 arc.innerRadius = function(_) {
21202 return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : innerRadius;
21205 arc.outerRadius = function(_) {
21206 return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : outerRadius;
21209 arc.cornerRadius = function(_) {
21210 return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : cornerRadius;
21213 arc.padRadius = function(_) {
21214 return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), arc) : padRadius;
21217 arc.startAngle = function(_) {
21218 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : startAngle;
21221 arc.endAngle = function(_) {
21222 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : endAngle;
21225 arc.padAngle = function(_) {
21226 return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : padAngle;
21229 arc.context = function(_) {
21230 return arguments.length ? ((context = _ == null ? null : _), arc) : context;
21236 function Linear(context) {
21237 this._context = context;
21240 Linear.prototype = {
21241 areaStart: function() {
21244 areaEnd: function() {
21247 lineStart: function() {
21250 lineEnd: function() {
21251 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
21252 this._line = 1 - this._line;
21254 point: function(x, y) {
21256 switch (this._point) {
21257 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
21258 case 1: this._point = 2; // proceed
21259 default: this._context.lineTo(x, y); break;
21264 var curveLinear = function(context) {
21265 return new Linear(context);
21276 var line = function() {
21279 defined = constant$2(true),
21281 curve = curveLinear,
21284 function line(data) {
21291 if (context == null) output = curve(buffer = path());
21293 for (i = 0; i <= n; ++i) {
21294 if (!(i < n && defined(d = data[i], i, data)) === defined0) {
21295 if (defined0 = !defined0) output.lineStart();
21296 else output.lineEnd();
21298 if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
21301 if (buffer) return output = null, buffer + "" || null;
21304 line.x = function(_) {
21305 return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$2(+_), line) : x$$1;
21308 line.y = function(_) {
21309 return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$2(+_), line) : y$$1;
21312 line.defined = function(_) {
21313 return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), line) : defined;
21316 line.curve = function(_) {
21317 return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
21320 line.context = function(_) {
21321 return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
21327 var area = function() {
21330 y0 = constant$2(0),
21332 defined = constant$2(true),
21334 curve = curveLinear,
21337 function area(data) {
21345 x0z = new Array(n),
21346 y0z = new Array(n);
21348 if (context == null) output = curve(buffer = path());
21350 for (i = 0; i <= n; ++i) {
21351 if (!(i < n && defined(d = data[i], i, data)) === defined0) {
21352 if (defined0 = !defined0) {
21354 output.areaStart();
21355 output.lineStart();
21358 output.lineStart();
21359 for (k = i - 1; k >= j; --k) {
21360 output.point(x0z[k], y0z[k]);
21367 x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
21368 output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
21372 if (buffer) return output = null, buffer + "" || null;
21375 function arealine() {
21376 return line().defined(defined).curve(curve).context(context);
21379 area.x = function(_) {
21380 return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), x1 = null, area) : x0;
21383 area.x0 = function(_) {
21384 return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), area) : x0;
21387 area.x1 = function(_) {
21388 return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : x1;
21391 area.y = function(_) {
21392 return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), y1 = null, area) : y0;
21395 area.y0 = function(_) {
21396 return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), area) : y0;
21399 area.y1 = function(_) {
21400 return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : y1;
21404 area.lineY0 = function() {
21405 return arealine().x(x0).y(y0);
21408 area.lineY1 = function() {
21409 return arealine().x(x0).y(y1);
21412 area.lineX1 = function() {
21413 return arealine().x(x1).y(y0);
21416 area.defined = function(_) {
21417 return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), area) : defined;
21420 area.curve = function(_) {
21421 return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
21424 area.context = function(_) {
21425 return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
21431 var descending$1 = function(a, b) {
21432 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
21435 var identity$1 = function(d) {
21439 var pie = function() {
21440 var value = identity$1,
21441 sortValues = descending$1,
21443 startAngle = constant$2(0),
21444 endAngle = constant$2(tau$2),
21445 padAngle = constant$2(0);
21447 function pie(data) {
21453 index = new Array(n),
21454 arcs = new Array(n),
21455 a0 = +startAngle.apply(this, arguments),
21456 da = Math.min(tau$2, Math.max(-tau$2, endAngle.apply(this, arguments) - a0)),
21458 p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
21459 pa = p * (da < 0 ? -1 : 1),
21462 for (i = 0; i < n; ++i) {
21463 if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
21468 // Optionally sort the arcs by previously-computed values or by data.
21469 if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
21470 else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
21472 // Compute the arcs! They are stored in the original data's order.
21473 for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
21474 j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
21487 pie.value = function(_) {
21488 return arguments.length ? (value = typeof _ === "function" ? _ : constant$2(+_), pie) : value;
21491 pie.sortValues = function(_) {
21492 return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
21495 pie.sort = function(_) {
21496 return arguments.length ? (sort = _, sortValues = null, pie) : sort;
21499 pie.startAngle = function(_) {
21500 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : startAngle;
21503 pie.endAngle = function(_) {
21504 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : endAngle;
21507 pie.padAngle = function(_) {
21508 return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), pie) : padAngle;
21514 var curveRadialLinear = curveRadial(curveLinear);
21516 function Radial(curve) {
21517 this._curve = curve;
21520 Radial.prototype = {
21521 areaStart: function() {
21522 this._curve.areaStart();
21524 areaEnd: function() {
21525 this._curve.areaEnd();
21527 lineStart: function() {
21528 this._curve.lineStart();
21530 lineEnd: function() {
21531 this._curve.lineEnd();
21533 point: function(a, r) {
21534 this._curve.point(r * Math.sin(a), r * -Math.cos(a));
21538 function curveRadial(curve) {
21540 function radial(context) {
21541 return new Radial(curve(context));
21544 radial._curve = curve;
21549 function radialLine(l) {
21552 l.angle = l.x, delete l.x;
21553 l.radius = l.y, delete l.y;
21555 l.curve = function(_) {
21556 return arguments.length ? c(curveRadial(_)) : c()._curve;
21562 var radialLine$1 = function() {
21563 return radialLine(line().curve(curveRadialLinear));
21566 var radialArea = function() {
21567 var a = area().curve(curveRadialLinear),
21574 a.angle = a.x, delete a.x;
21575 a.startAngle = a.x0, delete a.x0;
21576 a.endAngle = a.x1, delete a.x1;
21577 a.radius = a.y, delete a.y;
21578 a.innerRadius = a.y0, delete a.y0;
21579 a.outerRadius = a.y1, delete a.y1;
21580 a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0;
21581 a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1;
21582 a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0;
21583 a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1;
21585 a.curve = function(_) {
21586 return arguments.length ? c(curveRadial(_)) : c()._curve;
21593 draw: function(context, size) {
21594 var r = Math.sqrt(size / pi$2);
21595 context.moveTo(r, 0);
21596 context.arc(0, 0, r, 0, tau$2);
21601 draw: function(context, size) {
21602 var r = Math.sqrt(size / 5) / 2;
21603 context.moveTo(-3 * r, -r);
21604 context.lineTo(-r, -r);
21605 context.lineTo(-r, -3 * r);
21606 context.lineTo(r, -3 * r);
21607 context.lineTo(r, -r);
21608 context.lineTo(3 * r, -r);
21609 context.lineTo(3 * r, r);
21610 context.lineTo(r, r);
21611 context.lineTo(r, 3 * r);
21612 context.lineTo(-r, 3 * r);
21613 context.lineTo(-r, r);
21614 context.lineTo(-3 * r, r);
21615 context.closePath();
21619 var tan30 = Math.sqrt(1 / 3);
21620 var tan30_2 = tan30 * 2;
21623 draw: function(context, size) {
21624 var y = Math.sqrt(size / tan30_2),
21626 context.moveTo(0, -y);
21627 context.lineTo(x, 0);
21628 context.lineTo(0, y);
21629 context.lineTo(-x, 0);
21630 context.closePath();
21634 var ka = 0.89081309152928522810;
21635 var kr = Math.sin(pi$2 / 10) / Math.sin(7 * pi$2 / 10);
21636 var kx = Math.sin(tau$2 / 10) * kr;
21637 var ky = -Math.cos(tau$2 / 10) * kr;
21640 draw: function(context, size) {
21641 var r = Math.sqrt(size * ka),
21644 context.moveTo(0, -r);
21645 context.lineTo(x, y);
21646 for (var i = 1; i < 5; ++i) {
21647 var a = tau$2 * i / 5,
21650 context.lineTo(s * r, -c * r);
21651 context.lineTo(c * x - s * y, s * x + c * y);
21653 context.closePath();
21658 draw: function(context, size) {
21659 var w = Math.sqrt(size),
21661 context.rect(x, x, w, w);
21665 var sqrt3 = Math.sqrt(3);
21668 draw: function(context, size) {
21669 var y = -Math.sqrt(size / (sqrt3 * 3));
21670 context.moveTo(0, y * 2);
21671 context.lineTo(-sqrt3 * y, -y);
21672 context.lineTo(sqrt3 * y, -y);
21673 context.closePath();
21678 var s = Math.sqrt(3) / 2;
21679 var k = 1 / Math.sqrt(12);
21680 var a = (k / 2 + 1) * 3;
21683 draw: function(context, size) {
21684 var r = Math.sqrt(size / a),
21691 context.moveTo(x0, y0);
21692 context.lineTo(x1, y1);
21693 context.lineTo(x2, y2);
21694 context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
21695 context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
21696 context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
21697 context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
21698 context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
21699 context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
21700 context.closePath();
21714 var symbol = function() {
21715 var type = constant$2(circle),
21716 size = constant$2(64),
21719 function symbol() {
21721 if (!context) context = buffer = path();
21722 type.apply(this, arguments).draw(context, +size.apply(this, arguments));
21723 if (buffer) return context = null, buffer + "" || null;
21726 symbol.type = function(_) {
21727 return arguments.length ? (type = typeof _ === "function" ? _ : constant$2(_), symbol) : type;
21730 symbol.size = function(_) {
21731 return arguments.length ? (size = typeof _ === "function" ? _ : constant$2(+_), symbol) : size;
21734 symbol.context = function(_) {
21735 return arguments.length ? (context = _ == null ? null : _, symbol) : context;
21741 var noop = function() {};
21743 function point(that, x, y) {
21744 that._context.bezierCurveTo(
21745 (2 * that._x0 + that._x1) / 3,
21746 (2 * that._y0 + that._y1) / 3,
21747 (that._x0 + 2 * that._x1) / 3,
21748 (that._y0 + 2 * that._y1) / 3,
21749 (that._x0 + 4 * that._x1 + x) / 6,
21750 (that._y0 + 4 * that._y1 + y) / 6
21754 function Basis(context) {
21755 this._context = context;
21758 Basis.prototype = {
21759 areaStart: function() {
21762 areaEnd: function() {
21765 lineStart: function() {
21766 this._x0 = this._x1 =
21767 this._y0 = this._y1 = NaN;
21770 lineEnd: function() {
21771 switch (this._point) {
21772 case 3: point(this, this._x1, this._y1); // proceed
21773 case 2: this._context.lineTo(this._x1, this._y1); break;
21775 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
21776 this._line = 1 - this._line;
21778 point: function(x, y) {
21780 switch (this._point) {
21781 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
21782 case 1: this._point = 2; break;
21783 case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
21784 default: point(this, x, y); break;
21786 this._x0 = this._x1, this._x1 = x;
21787 this._y0 = this._y1, this._y1 = y;
21791 var basis = function(context) {
21792 return new Basis(context);
21795 function BasisClosed(context) {
21796 this._context = context;
21799 BasisClosed.prototype = {
21802 lineStart: function() {
21803 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
21804 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
21807 lineEnd: function() {
21808 switch (this._point) {
21810 this._context.moveTo(this._x2, this._y2);
21811 this._context.closePath();
21815 this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
21816 this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
21817 this._context.closePath();
21821 this.point(this._x2, this._y2);
21822 this.point(this._x3, this._y3);
21823 this.point(this._x4, this._y4);
21828 point: function(x, y) {
21830 switch (this._point) {
21831 case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
21832 case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
21833 case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;
21834 default: point(this, x, y); break;
21836 this._x0 = this._x1, this._x1 = x;
21837 this._y0 = this._y1, this._y1 = y;
21841 var basisClosed = function(context) {
21842 return new BasisClosed(context);
21845 function BasisOpen(context) {
21846 this._context = context;
21849 BasisOpen.prototype = {
21850 areaStart: function() {
21853 areaEnd: function() {
21856 lineStart: function() {
21857 this._x0 = this._x1 =
21858 this._y0 = this._y1 = NaN;
21861 lineEnd: function() {
21862 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
21863 this._line = 1 - this._line;
21865 point: function(x, y) {
21867 switch (this._point) {
21868 case 0: this._point = 1; break;
21869 case 1: this._point = 2; break;
21870 case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;
21871 case 3: this._point = 4; // proceed
21872 default: point(this, x, y); break;
21874 this._x0 = this._x1, this._x1 = x;
21875 this._y0 = this._y1, this._y1 = y;
21879 var basisOpen = function(context) {
21880 return new BasisOpen(context);
21883 function Bundle(context, beta) {
21884 this._basis = new Basis(context);
21888 Bundle.prototype = {
21889 lineStart: function() {
21892 this._basis.lineStart();
21894 lineEnd: function() {
21910 this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
21911 this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
21916 this._x = this._y = null;
21917 this._basis.lineEnd();
21919 point: function(x, y) {
21925 var bundle = (function custom(beta) {
21927 function bundle(context) {
21928 return beta === 1 ? new Basis(context) : new Bundle(context, beta);
21931 bundle.beta = function(beta) {
21932 return custom(+beta);
21938 function point$1(that, x, y) {
21939 that._context.bezierCurveTo(
21940 that._x1 + that._k * (that._x2 - that._x0),
21941 that._y1 + that._k * (that._y2 - that._y0),
21942 that._x2 + that._k * (that._x1 - x),
21943 that._y2 + that._k * (that._y1 - y),
21949 function Cardinal(context, tension) {
21950 this._context = context;
21951 this._k = (1 - tension) / 6;
21954 Cardinal.prototype = {
21955 areaStart: function() {
21958 areaEnd: function() {
21961 lineStart: function() {
21962 this._x0 = this._x1 = this._x2 =
21963 this._y0 = this._y1 = this._y2 = NaN;
21966 lineEnd: function() {
21967 switch (this._point) {
21968 case 2: this._context.lineTo(this._x2, this._y2); break;
21969 case 3: point$1(this, this._x1, this._y1); break;
21971 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
21972 this._line = 1 - this._line;
21974 point: function(x, y) {
21976 switch (this._point) {
21977 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
21978 case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
21979 case 2: this._point = 3; // proceed
21980 default: point$1(this, x, y); break;
21982 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
21983 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
21987 var cardinal = (function custom(tension) {
21989 function cardinal(context) {
21990 return new Cardinal(context, tension);
21993 cardinal.tension = function(tension) {
21994 return custom(+tension);
22000 function CardinalClosed(context, tension) {
22001 this._context = context;
22002 this._k = (1 - tension) / 6;
22005 CardinalClosed.prototype = {
22008 lineStart: function() {
22009 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
22010 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
22013 lineEnd: function() {
22014 switch (this._point) {
22016 this._context.moveTo(this._x3, this._y3);
22017 this._context.closePath();
22021 this._context.lineTo(this._x3, this._y3);
22022 this._context.closePath();
22026 this.point(this._x3, this._y3);
22027 this.point(this._x4, this._y4);
22028 this.point(this._x5, this._y5);
22033 point: function(x, y) {
22035 switch (this._point) {
22036 case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
22037 case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
22038 case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
22039 default: point$1(this, x, y); break;
22041 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22042 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22046 var cardinalClosed = (function custom(tension) {
22048 function cardinal(context) {
22049 return new CardinalClosed(context, tension);
22052 cardinal.tension = function(tension) {
22053 return custom(+tension);
22059 function CardinalOpen(context, tension) {
22060 this._context = context;
22061 this._k = (1 - tension) / 6;
22064 CardinalOpen.prototype = {
22065 areaStart: function() {
22068 areaEnd: function() {
22071 lineStart: function() {
22072 this._x0 = this._x1 = this._x2 =
22073 this._y0 = this._y1 = this._y2 = NaN;
22076 lineEnd: function() {
22077 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
22078 this._line = 1 - this._line;
22080 point: function(x, y) {
22082 switch (this._point) {
22083 case 0: this._point = 1; break;
22084 case 1: this._point = 2; break;
22085 case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
22086 case 3: this._point = 4; // proceed
22087 default: point$1(this, x, y); break;
22089 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22090 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22094 var cardinalOpen = (function custom(tension) {
22096 function cardinal(context) {
22097 return new CardinalOpen(context, tension);
22100 cardinal.tension = function(tension) {
22101 return custom(+tension);
22107 function point$2(that, x, y) {
22113 if (that._l01_a > epsilon$1) {
22114 var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
22115 n = 3 * that._l01_a * (that._l01_a + that._l12_a);
22116 x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
22117 y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
22120 if (that._l23_a > epsilon$1) {
22121 var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
22122 m = 3 * that._l23_a * (that._l23_a + that._l12_a);
22123 x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
22124 y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
22127 that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
22130 function CatmullRom(context, alpha) {
22131 this._context = context;
22132 this._alpha = alpha;
22135 CatmullRom.prototype = {
22136 areaStart: function() {
22139 areaEnd: function() {
22142 lineStart: function() {
22143 this._x0 = this._x1 = this._x2 =
22144 this._y0 = this._y1 = this._y2 = NaN;
22145 this._l01_a = this._l12_a = this._l23_a =
22146 this._l01_2a = this._l12_2a = this._l23_2a =
22149 lineEnd: function() {
22150 switch (this._point) {
22151 case 2: this._context.lineTo(this._x2, this._y2); break;
22152 case 3: this.point(this._x2, this._y2); break;
22154 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
22155 this._line = 1 - this._line;
22157 point: function(x, y) {
22161 var x23 = this._x2 - x,
22162 y23 = this._y2 - y;
22163 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
22166 switch (this._point) {
22167 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
22168 case 1: this._point = 2; break;
22169 case 2: this._point = 3; // proceed
22170 default: point$2(this, x, y); break;
22173 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
22174 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
22175 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22176 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22180 var catmullRom = (function custom(alpha) {
22182 function catmullRom(context) {
22183 return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
22186 catmullRom.alpha = function(alpha) {
22187 return custom(+alpha);
22193 function CatmullRomClosed(context, alpha) {
22194 this._context = context;
22195 this._alpha = alpha;
22198 CatmullRomClosed.prototype = {
22201 lineStart: function() {
22202 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
22203 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
22204 this._l01_a = this._l12_a = this._l23_a =
22205 this._l01_2a = this._l12_2a = this._l23_2a =
22208 lineEnd: function() {
22209 switch (this._point) {
22211 this._context.moveTo(this._x3, this._y3);
22212 this._context.closePath();
22216 this._context.lineTo(this._x3, this._y3);
22217 this._context.closePath();
22221 this.point(this._x3, this._y3);
22222 this.point(this._x4, this._y4);
22223 this.point(this._x5, this._y5);
22228 point: function(x, y) {
22232 var x23 = this._x2 - x,
22233 y23 = this._y2 - y;
22234 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
22237 switch (this._point) {
22238 case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
22239 case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
22240 case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
22241 default: point$2(this, x, y); break;
22244 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
22245 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
22246 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22247 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22251 var catmullRomClosed = (function custom(alpha) {
22253 function catmullRom(context) {
22254 return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
22257 catmullRom.alpha = function(alpha) {
22258 return custom(+alpha);
22264 function CatmullRomOpen(context, alpha) {
22265 this._context = context;
22266 this._alpha = alpha;
22269 CatmullRomOpen.prototype = {
22270 areaStart: function() {
22273 areaEnd: function() {
22276 lineStart: function() {
22277 this._x0 = this._x1 = this._x2 =
22278 this._y0 = this._y1 = this._y2 = NaN;
22279 this._l01_a = this._l12_a = this._l23_a =
22280 this._l01_2a = this._l12_2a = this._l23_2a =
22283 lineEnd: function() {
22284 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
22285 this._line = 1 - this._line;
22287 point: function(x, y) {
22291 var x23 = this._x2 - x,
22292 y23 = this._y2 - y;
22293 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
22296 switch (this._point) {
22297 case 0: this._point = 1; break;
22298 case 1: this._point = 2; break;
22299 case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
22300 case 3: this._point = 4; // proceed
22301 default: point$2(this, x, y); break;
22304 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
22305 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
22306 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
22307 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
22311 var catmullRomOpen = (function custom(alpha) {
22313 function catmullRom(context) {
22314 return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
22317 catmullRom.alpha = function(alpha) {
22318 return custom(+alpha);
22324 function LinearClosed(context) {
22325 this._context = context;
22328 LinearClosed.prototype = {
22331 lineStart: function() {
22334 lineEnd: function() {
22335 if (this._point) this._context.closePath();
22337 point: function(x, y) {
22339 if (this._point) this._context.lineTo(x, y);
22340 else this._point = 1, this._context.moveTo(x, y);
22344 var linearClosed = function(context) {
22345 return new LinearClosed(context);
22349 return x < 0 ? -1 : 1;
22352 // Calculate the slopes of the tangents (Hermite-type interpolation) based on
22353 // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
22354 // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
22355 // NOV(II), P. 443, 1990.
22356 function slope3(that, x2, y2) {
22357 var h0 = that._x1 - that._x0,
22358 h1 = x2 - that._x1,
22359 s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
22360 s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
22361 p = (s0 * h1 + s1 * h0) / (h0 + h1);
22362 return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
22365 // Calculate a one-sided slope.
22366 function slope2(that, t) {
22367 var h = that._x1 - that._x0;
22368 return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
22371 // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
22372 // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
22373 // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
22374 function point$3(that, t0, t1) {
22379 dx = (x1 - x0) / 3;
22380 that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
22383 function MonotoneX(context) {
22384 this._context = context;
22387 MonotoneX.prototype = {
22388 areaStart: function() {
22391 areaEnd: function() {
22394 lineStart: function() {
22395 this._x0 = this._x1 =
22396 this._y0 = this._y1 =
22400 lineEnd: function() {
22401 switch (this._point) {
22402 case 2: this._context.lineTo(this._x1, this._y1); break;
22403 case 3: point$3(this, this._t0, slope2(this, this._t0)); break;
22405 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
22406 this._line = 1 - this._line;
22408 point: function(x, y) {
22412 if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
22413 switch (this._point) {
22414 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
22415 case 1: this._point = 2; break;
22416 case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
22417 default: point$3(this, this._t0, t1 = slope3(this, x, y)); break;
22420 this._x0 = this._x1, this._x1 = x;
22421 this._y0 = this._y1, this._y1 = y;
22426 function MonotoneY(context) {
22427 this._context = new ReflectContext(context);
22430 (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
22431 MonotoneX.prototype.point.call(this, y, x);
22434 function ReflectContext(context) {
22435 this._context = context;
22438 ReflectContext.prototype = {
22439 moveTo: function(x, y) { this._context.moveTo(y, x); },
22440 closePath: function() { this._context.closePath(); },
22441 lineTo: function(x, y) { this._context.lineTo(y, x); },
22442 bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
22445 function monotoneX(context) {
22446 return new MonotoneX(context);
22449 function monotoneY(context) {
22450 return new MonotoneY(context);
22453 function Natural(context) {
22454 this._context = context;
22457 Natural.prototype = {
22458 areaStart: function() {
22461 areaEnd: function() {
22464 lineStart: function() {
22468 lineEnd: function() {
22474 this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
22476 this._context.lineTo(x[1], y[1]);
22478 var px = controlPoints(x),
22479 py = controlPoints(y);
22480 for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
22481 this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
22486 if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
22487 this._line = 1 - this._line;
22488 this._x = this._y = null;
22490 point: function(x, y) {
22496 // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
22497 function controlPoints(x) {
22504 a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
22505 for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
22506 a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
22507 for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
22508 a[n - 1] = r[n - 1] / b[n - 1];
22509 for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
22510 b[n - 1] = (x[n] + a[n - 1]) / 2;
22511 for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
22515 var natural = function(context) {
22516 return new Natural(context);
22519 function Step(context, t) {
22520 this._context = context;
22525 areaStart: function() {
22528 areaEnd: function() {
22531 lineStart: function() {
22532 this._x = this._y = NaN;
22535 lineEnd: function() {
22536 if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
22537 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
22538 if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
22540 point: function(x, y) {
22542 switch (this._point) {
22543 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
22544 case 1: this._point = 2; // proceed
22546 if (this._t <= 0) {
22547 this._context.lineTo(this._x, y);
22548 this._context.lineTo(x, y);
22550 var x1 = this._x * (1 - this._t) + x * this._t;
22551 this._context.lineTo(x1, this._y);
22552 this._context.lineTo(x1, y);
22557 this._x = x, this._y = y;
22561 var step = function(context) {
22562 return new Step(context, 0.5);
22565 function stepBefore(context) {
22566 return new Step(context, 0);
22569 function stepAfter(context) {
22570 return new Step(context, 1);
22573 var slice$2 = Array.prototype.slice;
22575 var none = function(series, order) {
22576 if (!((n = series.length) > 1)) return;
22577 for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
22578 s0 = s1, s1 = series[order[i]];
22579 for (var j = 0; j < m; ++j) {
22580 s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
22585 var none$1 = function(series) {
22586 var n = series.length, o = new Array(n);
22587 while (--n >= 0) o[n] = n;
22591 function stackValue(d, key) {
22595 var stack = function() {
22596 var keys = constant$2([]),
22599 value = stackValue;
22601 function stack(data) {
22602 var kz = keys.apply(this, arguments),
22609 for (i = 0; i < n; ++i) {
22610 for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
22611 si[j] = sij = [0, +value(data[j], ki, j, data)];
22612 sij.data = data[j];
22617 for (i = 0, oz = order(sz); i < n; ++i) {
22618 sz[oz[i]].index = i;
22625 stack.keys = function(_) {
22626 return arguments.length ? (keys = typeof _ === "function" ? _ : constant$2(slice$2.call(_)), stack) : keys;
22629 stack.value = function(_) {
22630 return arguments.length ? (value = typeof _ === "function" ? _ : constant$2(+_), stack) : value;
22633 stack.order = function(_) {
22634 return arguments.length ? (order = _ == null ? none$1 : typeof _ === "function" ? _ : constant$2(slice$2.call(_)), stack) : order;
22637 stack.offset = function(_) {
22638 return arguments.length ? (offset = _ == null ? none : _, stack) : offset;
22644 var expand = function(series, order) {
22645 if (!((n = series.length) > 0)) return;
22646 for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
22647 for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
22648 if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
22650 none(series, order);
22653 var silhouette = function(series, order) {
22654 if (!((n = series.length) > 0)) return;
22655 for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
22656 for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
22657 s0[j][1] += s0[j][0] = -y / 2;
22659 none(series, order);
22662 var wiggle = function(series, order) {
22663 if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
22664 for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
22665 for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
22666 var si = series[order[i]],
22667 sij0 = si[j][1] || 0,
22668 sij1 = si[j - 1][1] || 0,
22669 s3 = (sij0 - sij1) / 2;
22670 for (var k = 0; k < i; ++k) {
22671 var sk = series[order[k]],
22672 skj0 = sk[j][1] || 0,
22673 skj1 = sk[j - 1][1] || 0;
22676 s1 += sij0, s2 += s3 * sij0;
22678 s0[j - 1][1] += s0[j - 1][0] = y;
22679 if (s1) y -= s2 / s1;
22681 s0[j - 1][1] += s0[j - 1][0] = y;
22682 none(series, order);
22685 var ascending$1 = function(series) {
22686 var sums = series.map(sum$1);
22687 return none$1(series).sort(function(a, b) { return sums[a] - sums[b]; });
22690 function sum$1(series) {
22691 var s = 0, i = -1, n = series.length, v;
22692 while (++i < n) if (v = +series[i][1]) s += v;
22696 var descending$2 = function(series) {
22697 return ascending$1(series).reverse();
22700 var insideOut = function(series) {
22701 var n = series.length,
22704 sums = series.map(sum$1),
22705 order = none$1(series).sort(function(a, b) { return sums[b] - sums[a]; }),
22711 for (i = 0; i < n; ++i) {
22713 if (top < bottom) {
22722 return bottoms.reverse().concat(tops);
22725 var reverse = function(series) {
22726 return none$1(series).reverse();
22729 var define$1 = function(constructor, factory, prototype) {
22730 constructor.prototype = factory.prototype = prototype;
22731 prototype.constructor = constructor;
22734 function extend(parent, definition) {
22735 var prototype = Object.create(parent.prototype);
22736 for (var key in definition) prototype[key] = definition[key];
22740 function Color() {}
22743 var brighter = 1 / darker;
22745 var reI = "\\s*([+-]?\\d+)\\s*";
22746 var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*";
22747 var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
22748 var reHex3 = /^#([0-9a-f]{3})$/;
22749 var reHex6 = /^#([0-9a-f]{6})$/;
22750 var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$");
22751 var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$");
22752 var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$");
22753 var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$");
22754 var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$");
22755 var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
22758 aliceblue: 0xf0f8ff,
22759 antiquewhite: 0xfaebd7,
22761 aquamarine: 0x7fffd4,
22766 blanchedalmond: 0xffebcd,
22768 blueviolet: 0x8a2be2,
22770 burlywood: 0xdeb887,
22771 cadetblue: 0x5f9ea0,
22772 chartreuse: 0x7fff00,
22773 chocolate: 0xd2691e,
22775 cornflowerblue: 0x6495ed,
22776 cornsilk: 0xfff8dc,
22779 darkblue: 0x00008b,
22780 darkcyan: 0x008b8b,
22781 darkgoldenrod: 0xb8860b,
22782 darkgray: 0xa9a9a9,
22783 darkgreen: 0x006400,
22784 darkgrey: 0xa9a9a9,
22785 darkkhaki: 0xbdb76b,
22786 darkmagenta: 0x8b008b,
22787 darkolivegreen: 0x556b2f,
22788 darkorange: 0xff8c00,
22789 darkorchid: 0x9932cc,
22791 darksalmon: 0xe9967a,
22792 darkseagreen: 0x8fbc8f,
22793 darkslateblue: 0x483d8b,
22794 darkslategray: 0x2f4f4f,
22795 darkslategrey: 0x2f4f4f,
22796 darkturquoise: 0x00ced1,
22797 darkviolet: 0x9400d3,
22798 deeppink: 0xff1493,
22799 deepskyblue: 0x00bfff,
22802 dodgerblue: 0x1e90ff,
22803 firebrick: 0xb22222,
22804 floralwhite: 0xfffaf0,
22805 forestgreen: 0x228b22,
22807 gainsboro: 0xdcdcdc,
22808 ghostwhite: 0xf8f8ff,
22810 goldenrod: 0xdaa520,
22813 greenyellow: 0xadff2f,
22815 honeydew: 0xf0fff0,
22817 indianred: 0xcd5c5c,
22821 lavender: 0xe6e6fa,
22822 lavenderblush: 0xfff0f5,
22823 lawngreen: 0x7cfc00,
22824 lemonchiffon: 0xfffacd,
22825 lightblue: 0xadd8e6,
22826 lightcoral: 0xf08080,
22827 lightcyan: 0xe0ffff,
22828 lightgoldenrodyellow: 0xfafad2,
22829 lightgray: 0xd3d3d3,
22830 lightgreen: 0x90ee90,
22831 lightgrey: 0xd3d3d3,
22832 lightpink: 0xffb6c1,
22833 lightsalmon: 0xffa07a,
22834 lightseagreen: 0x20b2aa,
22835 lightskyblue: 0x87cefa,
22836 lightslategray: 0x778899,
22837 lightslategrey: 0x778899,
22838 lightsteelblue: 0xb0c4de,
22839 lightyellow: 0xffffe0,
22841 limegreen: 0x32cd32,
22845 mediumaquamarine: 0x66cdaa,
22846 mediumblue: 0x0000cd,
22847 mediumorchid: 0xba55d3,
22848 mediumpurple: 0x9370db,
22849 mediumseagreen: 0x3cb371,
22850 mediumslateblue: 0x7b68ee,
22851 mediumspringgreen: 0x00fa9a,
22852 mediumturquoise: 0x48d1cc,
22853 mediumvioletred: 0xc71585,
22854 midnightblue: 0x191970,
22855 mintcream: 0xf5fffa,
22856 mistyrose: 0xffe4e1,
22857 moccasin: 0xffe4b5,
22858 navajowhite: 0xffdead,
22862 olivedrab: 0x6b8e23,
22864 orangered: 0xff4500,
22866 palegoldenrod: 0xeee8aa,
22867 palegreen: 0x98fb98,
22868 paleturquoise: 0xafeeee,
22869 palevioletred: 0xdb7093,
22870 papayawhip: 0xffefd5,
22871 peachpuff: 0xffdab9,
22875 powderblue: 0xb0e0e6,
22877 rebeccapurple: 0x663399,
22879 rosybrown: 0xbc8f8f,
22880 royalblue: 0x4169e1,
22881 saddlebrown: 0x8b4513,
22883 sandybrown: 0xf4a460,
22884 seagreen: 0x2e8b57,
22885 seashell: 0xfff5ee,
22889 slateblue: 0x6a5acd,
22890 slategray: 0x708090,
22891 slategrey: 0x708090,
22893 springgreen: 0x00ff7f,
22894 steelblue: 0x4682b4,
22899 turquoise: 0x40e0d0,
22903 whitesmoke: 0xf5f5f5,
22905 yellowgreen: 0x9acd32
22908 define$1(Color, color, {
22909 displayable: function() {
22910 return this.rgb().displayable();
22912 toString: function() {
22913 return this.rgb() + "";
22917 function color(format) {
22919 format = (format + "").trim().toLowerCase();
22920 return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00
22921 : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
22922 : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
22923 : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
22924 : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
22925 : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
22926 : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
22927 : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
22928 : named.hasOwnProperty(format) ? rgbn(named[format])
22929 : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
22934 return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
22937 function rgba(r, g, b, a) {
22938 if (a <= 0) r = g = b = NaN;
22939 return new Rgb(r, g, b, a);
22942 function rgbConvert(o) {
22943 if (!(o instanceof Color)) o = color(o);
22944 if (!o) return new Rgb;
22946 return new Rgb(o.r, o.g, o.b, o.opacity);
22949 function rgb(r, g, b, opacity) {
22950 return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
22953 function Rgb(r, g, b, opacity) {
22957 this.opacity = +opacity;
22960 define$1(Rgb, rgb, extend(Color, {
22961 brighter: function(k) {
22962 k = k == null ? brighter : Math.pow(brighter, k);
22963 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
22965 darker: function(k) {
22966 k = k == null ? darker : Math.pow(darker, k);
22967 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
22972 displayable: function() {
22973 return (0 <= this.r && this.r <= 255)
22974 && (0 <= this.g && this.g <= 255)
22975 && (0 <= this.b && this.b <= 255)
22976 && (0 <= this.opacity && this.opacity <= 1);
22978 toString: function() {
22979 var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
22980 return (a === 1 ? "rgb(" : "rgba(")
22981 + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
22982 + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
22983 + Math.max(0, Math.min(255, Math.round(this.b) || 0))
22984 + (a === 1 ? ")" : ", " + a + ")");
22988 function hsla(h, s, l, a) {
22989 if (a <= 0) h = s = l = NaN;
22990 else if (l <= 0 || l >= 1) h = s = NaN;
22991 else if (s <= 0) h = NaN;
22992 return new Hsl(h, s, l, a);
22995 function hslConvert(o) {
22996 if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
22997 if (!(o instanceof Color)) o = color(o);
22998 if (!o) return new Hsl;
22999 if (o instanceof Hsl) return o;
23004 min = Math.min(r, g, b),
23005 max = Math.max(r, g, b),
23008 l = (max + min) / 2;
23010 if (r === max) h = (g - b) / s + (g < b) * 6;
23011 else if (g === max) h = (b - r) / s + 2;
23012 else h = (r - g) / s + 4;
23013 s /= l < 0.5 ? max + min : 2 - max - min;
23016 s = l > 0 && l < 1 ? 0 : h;
23018 return new Hsl(h, s, l, o.opacity);
23021 function hsl(h, s, l, opacity) {
23022 return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
23025 function Hsl(h, s, l, opacity) {
23029 this.opacity = +opacity;
23032 define$1(Hsl, hsl, extend(Color, {
23033 brighter: function(k) {
23034 k = k == null ? brighter : Math.pow(brighter, k);
23035 return new Hsl(this.h, this.s, this.l * k, this.opacity);
23037 darker: function(k) {
23038 k = k == null ? darker : Math.pow(darker, k);
23039 return new Hsl(this.h, this.s, this.l * k, this.opacity);
23042 var h = this.h % 360 + (this.h < 0) * 360,
23043 s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
23045 m2 = l + (l < 0.5 ? l : 1 - l) * s,
23048 hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
23049 hsl2rgb(h, m1, m2),
23050 hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
23054 displayable: function() {
23055 return (0 <= this.s && this.s <= 1 || isNaN(this.s))
23056 && (0 <= this.l && this.l <= 1)
23057 && (0 <= this.opacity && this.opacity <= 1);
23061 /* From FvD 13.37, CSS Color Module Level 3 */
23062 function hsl2rgb(h, m1, m2) {
23063 return (h < 60 ? m1 + (m2 - m1) * h / 60
23065 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
23069 var deg2rad = Math.PI / 180;
23070 var rad2deg = 180 / Math.PI;
23078 var t2 = 3 * t1 * t1;
23079 var t3 = t1 * t1 * t1;
23081 function labConvert(o) {
23082 if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
23083 if (o instanceof Hcl) {
23084 var h = o.h * deg2rad;
23085 return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
23087 if (!(o instanceof Rgb)) o = rgbConvert(o);
23088 var b = rgb2xyz(o.r),
23091 x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
23092 y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
23093 z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
23094 return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
23097 function lab(l, a, b, opacity) {
23098 return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
23101 function Lab(l, a, b, opacity) {
23105 this.opacity = +opacity;
23108 define$1(Lab, lab, extend(Color, {
23109 brighter: function(k) {
23110 return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
23112 darker: function(k) {
23113 return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
23116 var y = (this.l + 16) / 116,
23117 x = isNaN(this.a) ? y : y + this.a / 500,
23118 z = isNaN(this.b) ? y : y - this.b / 200;
23119 y = Yn * lab2xyz(y);
23120 x = Xn * lab2xyz(x);
23121 z = Zn * lab2xyz(z);
23123 xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
23124 xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
23125 xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
23131 function xyz2lab(t) {
23132 return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
23135 function lab2xyz(t) {
23136 return t > t1 ? t * t * t : t2 * (t - t0);
23139 function xyz2rgb(x) {
23140 return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
23143 function rgb2xyz(x) {
23144 return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
23147 function hclConvert(o) {
23148 if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
23149 if (!(o instanceof Lab)) o = labConvert(o);
23150 var h = Math.atan2(o.b, o.a) * rad2deg;
23151 return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
23154 function hcl(h, c, l, opacity) {
23155 return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
23158 function Hcl(h, c, l, opacity) {
23162 this.opacity = +opacity;
23165 define$1(Hcl, hcl, extend(Color, {
23166 brighter: function(k) {
23167 return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
23169 darker: function(k) {
23170 return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
23173 return labConvert(this).rgb();
23184 var BC_DA = B * C - D * A;
23186 function cubehelixConvert(o) {
23187 if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
23188 if (!(o instanceof Rgb)) o = rgbConvert(o);
23192 l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
23194 k = (E * (g - l) - C * bl) / D,
23195 s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
23196 h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
23197 return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
23200 function cubehelix(h, s, l, opacity) {
23201 return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
23204 function Cubehelix(h, s, l, opacity) {
23208 this.opacity = +opacity;
23211 define$1(Cubehelix, cubehelix, extend(Color, {
23212 brighter: function(k) {
23213 k = k == null ? brighter : Math.pow(brighter, k);
23214 return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
23216 darker: function(k) {
23217 k = k == null ? darker : Math.pow(darker, k);
23218 return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
23221 var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
23223 a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
23224 cosh = Math.cos(h),
23225 sinh = Math.sin(h);
23227 255 * (l + a * (A * cosh + B * sinh)),
23228 255 * (l + a * (C * cosh + D * sinh)),
23229 255 * (l + a * (E * cosh)),
23235 function basis$1(t1, v0, v1, v2, v3) {
23236 var t2 = t1 * t1, t3 = t2 * t1;
23237 return ((1 - 3 * t1 + 3 * t2 - t3) * v0
23238 + (4 - 6 * t2 + 3 * t3) * v1
23239 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
23243 var basis$2 = function(values) {
23244 var n = values.length - 1;
23245 return function(t) {
23246 var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
23248 v2 = values[i + 1],
23249 v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
23250 v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
23251 return basis$1((t - i / n) * n, v0, v1, v2, v3);
23255 var basisClosed$1 = function(values) {
23256 var n = values.length;
23257 return function(t) {
23258 var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
23259 v0 = values[(i + n - 1) % n],
23260 v1 = values[i % n],
23261 v2 = values[(i + 1) % n],
23262 v3 = values[(i + 2) % n];
23263 return basis$1((t - i / n) * n, v0, v1, v2, v3);
23267 var constant$3 = function(x) {
23268 return function() {
23273 function linear$1(a, d) {
23274 return function(t) {
23279 function exponential$1(a, b, y) {
23280 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
23281 return Math.pow(a + t * b, y);
23285 function hue(a, b) {
23287 return d ? linear$1(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
23290 function gamma(y) {
23291 return (y = +y) === 1 ? nogamma : function(a, b) {
23292 return b - a ? exponential$1(a, b, y) : constant$3(isNaN(a) ? b : a);
23296 function nogamma(a, b) {
23298 return d ? linear$1(a, d) : constant$3(isNaN(a) ? b : a);
23301 var interpolateRgb = (function rgbGamma(y) {
23302 var color$$1 = gamma(y);
23304 function rgb$$1(start, end) {
23305 var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
23306 g = color$$1(start.g, end.g),
23307 b = color$$1(start.b, end.b),
23308 opacity = color$$1(start.opacity, end.opacity);
23309 return function(t) {
23313 start.opacity = opacity(t);
23318 rgb$$1.gamma = rgbGamma;
23323 function rgbSpline(spline) {
23324 return function(colors) {
23325 var n = colors.length,
23330 for (i = 0; i < n; ++i) {
23331 color$$1 = rgb(colors[i]);
23332 r[i] = color$$1.r || 0;
23333 g[i] = color$$1.g || 0;
23334 b[i] = color$$1.b || 0;
23339 color$$1.opacity = 1;
23340 return function(t) {
23344 return color$$1 + "";
23349 var rgbBasis = rgbSpline(basis$2);
23350 var rgbBasisClosed = rgbSpline(basisClosed$1);
23352 var array$1 = function(a, b) {
23353 var nb = b ? b.length : 0,
23354 na = a ? Math.min(nb, a.length) : 0,
23359 for (i = 0; i < na; ++i) x[i] = interpolate(a[i], b[i]);
23360 for (; i < nb; ++i) c[i] = b[i];
23362 return function(t) {
23363 for (i = 0; i < na; ++i) c[i] = x[i](t);
23368 var date = function(a, b) {
23370 return a = +a, b -= a, function(t) {
23371 return d.setTime(a + b * t), d;
23375 var interpolateNumber = function(a, b) {
23376 return a = +a, b -= a, function(t) {
23381 var object = function(a, b) {
23386 if (a === null || typeof a !== "object") a = {};
23387 if (b === null || typeof b !== "object") b = {};
23391 i[k] = interpolate(a[k], b[k]);
23397 return function(t) {
23398 for (k in i) c[k] = i[k](t);
23403 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
23404 var reB = new RegExp(reA.source, "g");
23407 return function() {
23413 return function(t) {
23418 var interpolateString = function(a, b) {
23419 var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
23420 am, // current match in a
23421 bm, // current match in b
23422 bs, // string preceding current number in b, if any
23423 i = -1, // index in s
23424 s = [], // string constants and placeholders
23425 q = []; // number interpolators
23427 // Coerce inputs to strings.
23428 a = a + "", b = b + "";
23430 // Interpolate pairs of numbers in a & b.
23431 while ((am = reA.exec(a))
23432 && (bm = reB.exec(b))) {
23433 if ((bs = bm.index) > bi) { // a string precedes the next number in b
23434 bs = b.slice(bi, bs);
23435 if (s[i]) s[i] += bs; // coalesce with previous string
23438 if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
23439 if (s[i]) s[i] += bm; // coalesce with previous string
23441 } else { // interpolate non-matching numbers
23443 q.push({i: i, x: interpolateNumber(am, bm)});
23445 bi = reB.lastIndex;
23448 // Add remains of b.
23449 if (bi < b.length) {
23451 if (s[i]) s[i] += bs; // coalesce with previous string
23455 // Special optimization for only a single match.
23456 // Otherwise, interpolate each of the numbers and rejoin the string.
23457 return s.length < 2 ? (q[0]
23460 : (b = q.length, function(t) {
23461 for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
23466 var interpolate = function(a, b) {
23467 var t = typeof b, c;
23468 return b == null || t === "boolean" ? constant$3(b)
23469 : (t === "number" ? interpolateNumber
23470 : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)
23471 : b instanceof color ? interpolateRgb
23472 : b instanceof Date ? date
23473 : Array.isArray(b) ? array$1
23474 : isNaN(b) ? object
23475 : interpolateNumber)(a, b);
23478 var interpolateRound = function(a, b) {
23479 return a = +a, b -= a, function(t) {
23480 return Math.round(a + b * t);
23484 var degrees = 180 / Math.PI;
23495 var decompose = function(a, b, c, d, e, f) {
23496 var scaleX, scaleY, skewX;
23497 if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
23498 if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
23499 if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
23500 if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
23504 rotate: Math.atan2(b, a) * degrees,
23505 skewX: Math.atan(skewX) * degrees,
23516 function parseCss(value) {
23517 if (value === "none") return identity$2;
23518 if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
23519 cssNode.style.transform = value;
23520 value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
23521 cssRoot.removeChild(cssNode);
23522 value = value.slice(7, -1).split(",");
23523 return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
23526 function parseSvg(value) {
23527 if (value == null) return identity$2;
23528 if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
23529 svgNode.setAttribute("transform", value);
23530 if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
23531 value = value.matrix;
23532 return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
23535 function interpolateTransform(parse, pxComma, pxParen, degParen) {
23538 return s.length ? s.pop() + " " : "";
23541 function translate(xa, ya, xb, yb, s, q) {
23542 if (xa !== xb || ya !== yb) {
23543 var i = s.push("translate(", null, pxComma, null, pxParen);
23544 q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)});
23545 } else if (xb || yb) {
23546 s.push("translate(" + xb + pxComma + yb + pxParen);
23550 function rotate(a, b, s, q) {
23552 if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
23553 q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)});
23555 s.push(pop(s) + "rotate(" + b + degParen);
23559 function skewX(a, b, s, q) {
23561 q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)});
23563 s.push(pop(s) + "skewX(" + b + degParen);
23567 function scale(xa, ya, xb, yb, s, q) {
23568 if (xa !== xb || ya !== yb) {
23569 var i = s.push(pop(s) + "scale(", null, ",", null, ")");
23570 q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)});
23571 } else if (xb !== 1 || yb !== 1) {
23572 s.push(pop(s) + "scale(" + xb + "," + yb + ")");
23576 return function(a, b) {
23577 var s = [], // string constants and placeholders
23578 q = []; // number interpolators
23579 a = parse(a), b = parse(b);
23580 translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
23581 rotate(a.rotate, b.rotate, s, q);
23582 skewX(a.skewX, b.skewX, s, q);
23583 scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
23584 a = b = null; // gc
23585 return function(t) {
23586 var i = -1, n = q.length, o;
23587 while (++i < n) s[(o = q[i]).i] = o.x(t);
23593 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
23594 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
23596 var rho = Math.SQRT2;
23599 var epsilon2 = 1e-12;
23602 return ((x = Math.exp(x)) + 1 / x) / 2;
23606 return ((x = Math.exp(x)) - 1 / x) / 2;
23610 return ((x = Math.exp(2 * x)) - 1) / (x + 1);
23613 // p0 = [ux0, uy0, w0]
23614 // p1 = [ux1, uy1, w1]
23615 var interpolateZoom = function(p0, p1) {
23616 var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
23617 ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
23620 d2 = dx * dx + dy * dy,
23624 // Special case for u0 ≅ u1.
23625 if (d2 < epsilon2) {
23626 S = Math.log(w1 / w0) / rho;
23631 w0 * Math.exp(rho * t * S)
23638 var d1 = Math.sqrt(d2),
23639 b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
23640 b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
23641 r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
23642 r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
23643 S = (r1 - r0) / rho;
23647 u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
23651 w0 * coshr0 / cosh(rho * s + r0)
23656 i.duration = S * 1000;
23661 function hsl$1(hue$$1) {
23662 return function(start, end) {
23663 var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
23664 s = nogamma(start.s, end.s),
23665 l = nogamma(start.l, end.l),
23666 opacity = nogamma(start.opacity, end.opacity);
23667 return function(t) {
23671 start.opacity = opacity(t);
23677 var hsl$2 = hsl$1(hue);
23678 var hslLong = hsl$1(nogamma);
23680 function lab$1(start, end) {
23681 var l = nogamma((start = lab(start)).l, (end = lab(end)).l),
23682 a = nogamma(start.a, end.a),
23683 b = nogamma(start.b, end.b),
23684 opacity = nogamma(start.opacity, end.opacity);
23685 return function(t) {
23689 start.opacity = opacity(t);
23694 function hcl$1(hue$$1) {
23695 return function(start, end) {
23696 var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
23697 c = nogamma(start.c, end.c),
23698 l = nogamma(start.l, end.l),
23699 opacity = nogamma(start.opacity, end.opacity);
23700 return function(t) {
23704 start.opacity = opacity(t);
23710 var hcl$2 = hcl$1(hue);
23711 var hclLong = hcl$1(nogamma);
23713 function cubehelix$1(hue$$1) {
23714 return (function cubehelixGamma(y) {
23717 function cubehelix$$1(start, end) {
23718 var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
23719 s = nogamma(start.s, end.s),
23720 l = nogamma(start.l, end.l),
23721 opacity = nogamma(start.opacity, end.opacity);
23722 return function(t) {
23725 start.l = l(Math.pow(t, y));
23726 start.opacity = opacity(t);
23731 cubehelix$$1.gamma = cubehelixGamma;
23733 return cubehelix$$1;
23737 var cubehelix$2 = cubehelix$1(hue);
23738 var cubehelixLong = cubehelix$1(nogamma);
23740 var quantize = function(interpolator, n) {
23741 var samples = new Array(n);
23742 for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
23746 var noop$1 = {value: function() {}};
23748 function dispatch() {
23749 for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
23750 if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
23753 return new Dispatch(_);
23756 function Dispatch(_) {
23760 function parseTypenames(typenames, types) {
23761 return typenames.trim().split(/^|\s+/).map(function(t) {
23762 var name = "", i = t.indexOf(".");
23763 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
23764 if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
23765 return {type: t, name: name};
23769 Dispatch.prototype = dispatch.prototype = {
23770 constructor: Dispatch,
23771 on: function(typename, callback) {
23773 T = parseTypenames(typename + "", _),
23778 // If no callback was specified, return the callback of the given type and name.
23779 if (arguments.length < 2) {
23780 while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
23784 // If a type was specified, set the callback for the given type and name.
23785 // Otherwise, if a null callback was specified, remove callbacks of the given name.
23786 if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
23788 if (t = (typename = T[i]).type) _[t] = set$2(_[t], typename.name, callback);
23789 else if (callback == null) for (t in _) _[t] = set$2(_[t], typename.name, null);
23795 var copy = {}, _ = this._;
23796 for (var t in _) copy[t] = _[t].slice();
23797 return new Dispatch(copy);
23799 call: function(type, that) {
23800 if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
23801 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
23802 for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
23804 apply: function(type, that, args) {
23805 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
23806 for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
23810 function get(type, name) {
23811 for (var i = 0, n = type.length, c; i < n; ++i) {
23812 if ((c = type[i]).name === name) {
23818 function set$2(type, name, callback) {
23819 for (var i = 0, n = type.length; i < n; ++i) {
23820 if (type[i].name === name) {
23821 type[i] = noop$1, type = type.slice(0, i).concat(type.slice(i + 1));
23825 if (callback != null) type.push({name: name, value: callback});
23829 function objectConverter(columns) {
23830 return new Function("d", "return {" + columns.map(function(name, i) {
23831 return JSON.stringify(name) + ": d[" + i + "]";
23832 }).join(",") + "}");
23835 function customConverter(columns, f) {
23836 var object = objectConverter(columns);
23837 return function(row, i) {
23838 return f(object(row), i, columns);
23842 // Compute unique columns in order of discovery.
23843 function inferColumns(rows) {
23844 var columnSet = Object.create(null),
23847 rows.forEach(function(row) {
23848 for (var column in row) {
23849 if (!(column in columnSet)) {
23850 columns.push(columnSet[column] = column);
23858 var dsv = function(delimiter) {
23859 var reFormat = new RegExp("[\"" + delimiter + "\n]"),
23860 delimiterCode = delimiter.charCodeAt(0);
23862 function parse(text, f) {
23863 var convert, columns, rows = parseRows(text, function(row, i) {
23864 if (convert) return convert(row, i - 1);
23865 columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
23867 rows.columns = columns;
23871 function parseRows(text, f) {
23872 var EOL = {}, // sentinel value for end-of-line
23873 EOF = {}, // sentinel value for end-of-file
23874 rows = [], // output rows
23876 I = 0, // current character index
23877 n = 0, // the current line number
23878 t, // the current token
23879 eol; // is the current token followed by EOL?
23882 if (I >= N) return EOF; // special case: end of file
23883 if (eol) return eol = false, EOL; // special case: end of line
23885 // special case: quotes
23887 if (text.charCodeAt(j) === 34) {
23890 if (text.charCodeAt(i) === 34) {
23891 if (text.charCodeAt(i + 1) !== 34) break;
23896 c = text.charCodeAt(i + 1);
23899 if (text.charCodeAt(i + 2) === 10) ++I;
23900 } else if (c === 10) {
23903 return text.slice(j + 1, i).replace(/""/g, "\"");
23906 // common case: find next delimiter or newline
23909 c = text.charCodeAt(I++);
23910 if (c === 10) eol = true; // \n
23911 else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n
23912 else if (c !== delimiterCode) continue;
23913 return text.slice(j, I - k);
23916 // special case: last token before EOF
23917 return text.slice(j);
23920 while ((t = token()) !== EOF) {
23922 while (t !== EOL && t !== EOF) {
23926 if (f && (a = f(a, n++)) == null) continue;
23933 function format(rows, columns) {
23934 if (columns == null) columns = inferColumns(rows);
23935 return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
23936 return columns.map(function(column) {
23937 return formatValue(row[column]);
23938 }).join(delimiter);
23942 function formatRows(rows) {
23943 return rows.map(formatRow).join("\n");
23946 function formatRow(row) {
23947 return row.map(formatValue).join(delimiter);
23950 function formatValue(text) {
23951 return text == null ? ""
23952 : reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\""
23958 parseRows: parseRows,
23960 formatRows: formatRows
23964 var csv = dsv(",");
23966 var csvParse = csv.parse;
23967 var csvParseRows = csv.parseRows;
23968 var csvFormat = csv.format;
23969 var csvFormatRows = csv.formatRows;
23971 var tsv = dsv("\t");
23973 var tsvParse = tsv.parse;
23974 var tsvParseRows = tsv.parseRows;
23975 var tsvFormat = tsv.format;
23976 var tsvFormatRows = tsv.formatRows;
23978 var request = function(url, callback) {
23980 event = dispatch("beforesend", "progress", "load", "error"),
23983 xhr = new XMLHttpRequest,
23990 // If IE does not support CORS, use XDomainRequest.
23991 if (typeof XDomainRequest !== "undefined"
23992 && !("withCredentials" in xhr)
23993 && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
23996 ? xhr.onload = xhr.onerror = xhr.ontimeout = respond
23997 : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
23999 function respond(o) {
24000 var status = xhr.status, result;
24001 if (!status && hasResponse(xhr)
24002 || status >= 200 && status < 300
24003 || status === 304) {
24006 result = response.call(request, xhr);
24008 event.call("error", request, e);
24014 event.call("load", request, result);
24016 event.call("error", request, o);
24020 xhr.onprogress = function(e) {
24021 event.call("progress", request, e);
24025 header: function(name, value) {
24026 name = (name + "").toLowerCase();
24027 if (arguments.length < 2) return headers.get(name);
24028 if (value == null) headers.remove(name);
24029 else headers.set(name, value + "");
24033 // If mimeType is non-null and no Accept header is set, a default is used.
24034 mimeType: function(value) {
24035 if (!arguments.length) return mimeType;
24036 mimeType = value == null ? null : value + "";
24040 // Specifies what type the response value should take;
24041 // for instance, arraybuffer, blob, document, or text.
24042 responseType: function(value) {
24043 if (!arguments.length) return responseType;
24044 responseType = value;
24048 timeout: function(value) {
24049 if (!arguments.length) return timeout;
24054 user: function(value) {
24055 return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
24058 password: function(value) {
24059 return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
24062 // Specify how to convert the response content to a specific type;
24063 // changes the callback value on "load" events.
24064 response: function(value) {
24069 // Alias for send("GET", …).
24070 get: function(data, callback) {
24071 return request.send("GET", data, callback);
24074 // Alias for send("POST", …).
24075 post: function(data, callback) {
24076 return request.send("POST", data, callback);
24079 // If callback is non-null, it will be used for error and load events.
24080 send: function(method, data, callback) {
24081 xhr.open(method, url, true, user, password);
24082 if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
24083 if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
24084 if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
24085 if (responseType != null) xhr.responseType = responseType;
24086 if (timeout > 0) xhr.timeout = timeout;
24087 if (callback == null && typeof data === "function") callback = data, data = null;
24088 if (callback != null && callback.length === 1) callback = fixCallback(callback);
24089 if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
24090 event.call("beforesend", request, xhr);
24091 xhr.send(data == null ? null : data);
24095 abort: function() {
24101 var value = event.on.apply(event, arguments);
24102 return value === event ? request : value;
24106 if (callback != null) {
24107 if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
24108 return request.get(callback);
24114 function fixCallback(callback) {
24115 return function(error, xhr) {
24116 callback(error == null ? xhr : null);
24120 function hasResponse(xhr) {
24121 var type = xhr.responseType;
24122 return type && type !== "text"
24123 ? xhr.response // null on error
24124 : xhr.responseText; // "" on error
24127 var type$2 = function(defaultMimeType, response) {
24128 return function(url, callback) {
24129 var r = request(url).mimeType(defaultMimeType).response(response);
24130 if (callback != null) {
24131 if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
24132 return r.get(callback);
24138 var html = type$2("text/html", function(xhr) {
24139 return document.createRange().createContextualFragment(xhr.responseText);
24142 var json = type$2("application/json", function(xhr) {
24143 return JSON.parse(xhr.responseText);
24146 var text = type$2("text/plain", function(xhr) {
24147 return xhr.responseText;
24150 var xml = type$2("application/xml", function(xhr) {
24151 var xml = xhr.responseXML;
24152 if (!xml) throw new Error("parse error");
24156 var dsv$1 = function(defaultMimeType, parse) {
24157 return function(url, row, callback) {
24158 if (arguments.length < 3) callback = row, row = null;
24159 var r = request(url).mimeType(defaultMimeType);
24160 r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
24162 return callback ? r.get(callback) : r;
24166 function responseOf(parse, row) {
24167 return function(request$$1) {
24168 return parse(request$$1.responseText, row);
24172 var csv$1 = dsv$1("text/csv", csvParse);
24174 var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
24179 var pokeDelay = 1000;
24185 var clock = typeof performance === "object" && performance.now ? performance : Date;
24186 var setFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : function(f) { setTimeout(f, 17); };
24189 return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
24192 function clearNow() {
24202 Timer.prototype = timer.prototype = {
24203 constructor: Timer,
24204 restart: function(callback, delay, time) {
24205 if (typeof callback !== "function") throw new TypeError("callback is not a function");
24206 time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
24207 if (!this._next && taskTail !== this) {
24208 if (taskTail) taskTail._next = this;
24209 else taskHead = this;
24212 this._call = callback;
24219 this._time = Infinity;
24225 function timer(callback, delay, time) {
24227 t.restart(callback, delay, time);
24231 function timerFlush() {
24232 now(); // Get the current time, if not already set.
24233 ++frame; // Pretend we’ve set an alarm, if we haven’t already.
24234 var t = taskHead, e;
24236 if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
24243 clockNow = (clockLast = clock.now()) + clockSkew;
24244 frame = timeout = 0;
24254 function poke$1() {
24255 var now = clock.now(), delay = now - clockLast;
24256 if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
24260 var t0, t1 = taskHead, t2, time = Infinity;
24263 if (time > t1._time) time = t1._time;
24264 t0 = t1, t1 = t1._next;
24266 t2 = t1._next, t1._next = null;
24267 t1 = t0 ? t0._next = t2 : taskHead = t2;
24274 function sleep(time) {
24275 if (frame) return; // Soonest alarm already set, or will be.
24276 if (timeout) timeout = clearTimeout(timeout);
24277 var delay = time - clockNow;
24279 if (time < Infinity) timeout = setTimeout(wake, delay);
24280 if (interval) interval = clearInterval(interval);
24282 if (!interval) interval = setInterval(poke$1, pokeDelay);
24283 frame = 1, setFrame(wake);
24287 var timeout$1 = function(callback, delay, time) {
24289 delay = delay == null ? 0 : +delay;
24290 t.restart(function(elapsed) {
24292 callback(elapsed + delay);
24297 var interval$1 = function(callback, delay, time) {
24298 var t = new Timer, total = delay;
24299 if (delay == null) return t.restart(callback, delay, time), t;
24300 delay = +delay, time = time == null ? now() : +time;
24301 t.restart(function tick(elapsed) {
24303 t.restart(tick, total += delay, time);
24309 var t0$1 = new Date;
24310 var t1$1 = new Date;
24312 function newInterval(floori, offseti, count, field) {
24314 function interval(date) {
24315 return floori(date = new Date(+date)), date;
24318 interval.floor = interval;
24320 interval.ceil = function(date) {
24321 return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
24324 interval.round = function(date) {
24325 var d0 = interval(date),
24326 d1 = interval.ceil(date);
24327 return date - d0 < d1 - date ? d0 : d1;
24330 interval.offset = function(date, step) {
24331 return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
24334 interval.range = function(start, stop, step) {
24336 start = interval.ceil(start);
24337 step = step == null ? 1 : Math.floor(step);
24338 if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
24339 do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop)
24343 interval.filter = function(test) {
24344 return newInterval(function(date) {
24345 if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
24346 }, function(date, step) {
24347 if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty
24352 interval.count = function(start, end) {
24353 t0$1.setTime(+start), t1$1.setTime(+end);
24354 floori(t0$1), floori(t1$1);
24355 return Math.floor(count(t0$1, t1$1));
24358 interval.every = function(step) {
24359 step = Math.floor(step);
24360 return !isFinite(step) || !(step > 0) ? null
24361 : !(step > 1) ? interval
24362 : interval.filter(field
24363 ? function(d) { return field(d) % step === 0; }
24364 : function(d) { return interval.count(0, d) % step === 0; });
24371 var millisecond = newInterval(function() {
24373 }, function(date, step) {
24374 date.setTime(+date + step);
24375 }, function(start, end) {
24376 return end - start;
24379 // An optimized implementation for this simple case.
24380 millisecond.every = function(k) {
24382 if (!isFinite(k) || !(k > 0)) return null;
24383 if (!(k > 1)) return millisecond;
24384 return newInterval(function(date) {
24385 date.setTime(Math.floor(date / k) * k);
24386 }, function(date, step) {
24387 date.setTime(+date + step * k);
24388 }, function(start, end) {
24389 return (end - start) / k;
24393 var milliseconds = millisecond.range;
24395 var durationSecond = 1e3;
24396 var durationMinute = 6e4;
24397 var durationHour = 36e5;
24398 var durationDay = 864e5;
24399 var durationWeek = 6048e5;
24401 var second = newInterval(function(date) {
24402 date.setTime(Math.floor(date / durationSecond) * durationSecond);
24403 }, function(date, step) {
24404 date.setTime(+date + step * durationSecond);
24405 }, function(start, end) {
24406 return (end - start) / durationSecond;
24407 }, function(date) {
24408 return date.getUTCSeconds();
24411 var seconds = second.range;
24413 var minute = newInterval(function(date) {
24414 date.setTime(Math.floor(date / durationMinute) * durationMinute);
24415 }, function(date, step) {
24416 date.setTime(+date + step * durationMinute);
24417 }, function(start, end) {
24418 return (end - start) / durationMinute;
24419 }, function(date) {
24420 return date.getMinutes();
24423 var minutes = minute.range;
24425 var hour = newInterval(function(date) {
24426 var offset = date.getTimezoneOffset() * durationMinute % durationHour;
24427 if (offset < 0) offset += durationHour;
24428 date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset);
24429 }, function(date, step) {
24430 date.setTime(+date + step * durationHour);
24431 }, function(start, end) {
24432 return (end - start) / durationHour;
24433 }, function(date) {
24434 return date.getHours();
24437 var hours = hour.range;
24439 var day = newInterval(function(date) {
24440 date.setHours(0, 0, 0, 0);
24441 }, function(date, step) {
24442 date.setDate(date.getDate() + step);
24443 }, function(start, end) {
24444 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;
24445 }, function(date) {
24446 return date.getDate() - 1;
24449 var days = day.range;
24451 function weekday(i) {
24452 return newInterval(function(date) {
24453 date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
24454 date.setHours(0, 0, 0, 0);
24455 }, function(date, step) {
24456 date.setDate(date.getDate() + step * 7);
24457 }, function(start, end) {
24458 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
24462 var sunday = weekday(0);
24463 var monday = weekday(1);
24464 var tuesday = weekday(2);
24465 var wednesday = weekday(3);
24466 var thursday = weekday(4);
24467 var friday = weekday(5);
24468 var saturday = weekday(6);
24470 var sundays = sunday.range;
24471 var mondays = monday.range;
24472 var tuesdays = tuesday.range;
24473 var wednesdays = wednesday.range;
24474 var thursdays = thursday.range;
24475 var fridays = friday.range;
24476 var saturdays = saturday.range;
24478 var month = newInterval(function(date) {
24480 date.setHours(0, 0, 0, 0);
24481 }, function(date, step) {
24482 date.setMonth(date.getMonth() + step);
24483 }, function(start, end) {
24484 return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
24485 }, function(date) {
24486 return date.getMonth();
24489 var months = month.range;
24491 var year = newInterval(function(date) {
24492 date.setMonth(0, 1);
24493 date.setHours(0, 0, 0, 0);
24494 }, function(date, step) {
24495 date.setFullYear(date.getFullYear() + step);
24496 }, function(start, end) {
24497 return end.getFullYear() - start.getFullYear();
24498 }, function(date) {
24499 return date.getFullYear();
24502 // An optimized implementation for this simple case.
24503 year.every = function(k) {
24504 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
24505 date.setFullYear(Math.floor(date.getFullYear() / k) * k);
24506 date.setMonth(0, 1);
24507 date.setHours(0, 0, 0, 0);
24508 }, function(date, step) {
24509 date.setFullYear(date.getFullYear() + step * k);
24513 var years = year.range;
24515 var utcMinute = newInterval(function(date) {
24516 date.setUTCSeconds(0, 0);
24517 }, function(date, step) {
24518 date.setTime(+date + step * durationMinute);
24519 }, function(start, end) {
24520 return (end - start) / durationMinute;
24521 }, function(date) {
24522 return date.getUTCMinutes();
24525 var utcMinutes = utcMinute.range;
24527 var utcHour = newInterval(function(date) {
24528 date.setUTCMinutes(0, 0, 0);
24529 }, function(date, step) {
24530 date.setTime(+date + step * durationHour);
24531 }, function(start, end) {
24532 return (end - start) / durationHour;
24533 }, function(date) {
24534 return date.getUTCHours();
24537 var utcHours = utcHour.range;
24539 var utcDay = newInterval(function(date) {
24540 date.setUTCHours(0, 0, 0, 0);
24541 }, function(date, step) {
24542 date.setUTCDate(date.getUTCDate() + step);
24543 }, function(start, end) {
24544 return (end - start) / durationDay;
24545 }, function(date) {
24546 return date.getUTCDate() - 1;
24549 var utcDays = utcDay.range;
24551 function utcWeekday(i) {
24552 return newInterval(function(date) {
24553 date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
24554 date.setUTCHours(0, 0, 0, 0);
24555 }, function(date, step) {
24556 date.setUTCDate(date.getUTCDate() + step * 7);
24557 }, function(start, end) {
24558 return (end - start) / durationWeek;
24562 var utcSunday = utcWeekday(0);
24563 var utcMonday = utcWeekday(1);
24564 var utcTuesday = utcWeekday(2);
24565 var utcWednesday = utcWeekday(3);
24566 var utcThursday = utcWeekday(4);
24567 var utcFriday = utcWeekday(5);
24568 var utcSaturday = utcWeekday(6);
24570 var utcSundays = utcSunday.range;
24571 var utcMondays = utcMonday.range;
24572 var utcTuesdays = utcTuesday.range;
24573 var utcWednesdays = utcWednesday.range;
24574 var utcThursdays = utcThursday.range;
24575 var utcFridays = utcFriday.range;
24576 var utcSaturdays = utcSaturday.range;
24578 var utcMonth = newInterval(function(date) {
24579 date.setUTCDate(1);
24580 date.setUTCHours(0, 0, 0, 0);
24581 }, function(date, step) {
24582 date.setUTCMonth(date.getUTCMonth() + step);
24583 }, function(start, end) {
24584 return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
24585 }, function(date) {
24586 return date.getUTCMonth();
24589 var utcMonths = utcMonth.range;
24591 var utcYear = newInterval(function(date) {
24592 date.setUTCMonth(0, 1);
24593 date.setUTCHours(0, 0, 0, 0);
24594 }, function(date, step) {
24595 date.setUTCFullYear(date.getUTCFullYear() + step);
24596 }, function(start, end) {
24597 return end.getUTCFullYear() - start.getUTCFullYear();
24598 }, function(date) {
24599 return date.getUTCFullYear();
24602 // An optimized implementation for this simple case.
24603 utcYear.every = function(k) {
24604 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
24605 date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
24606 date.setUTCMonth(0, 1);
24607 date.setUTCHours(0, 0, 0, 0);
24608 }, function(date, step) {
24609 date.setUTCFullYear(date.getUTCFullYear() + step * k);
24613 var utcYears = utcYear.range;
24615 // Computes the decimal coefficient and exponent of the specified number x with
24616 // significant digits p, where x is positive and p is in [1, 21] or undefined.
24617 // For example, formatDecimal(1.23) returns ["123", 0].
24618 var formatDecimal = function(x, p) {
24619 if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
24620 var i, coefficient = x.slice(0, i);
24622 // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
24623 // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
24625 coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
24630 var exponent$1 = function(x) {
24631 return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
24634 var formatGroup = function(grouping, thousands) {
24635 return function(value, width) {
24636 var i = value.length,
24642 while (i > 0 && g > 0) {
24643 if (length + g + 1 > width) g = Math.max(1, width - length);
24644 t.push(value.substring(i -= g, i + g));
24645 if ((length += g + 1) > width) break;
24646 g = grouping[j = (j + 1) % grouping.length];
24649 return t.reverse().join(thousands);
24653 var formatDefault = function(x, p) {
24654 x = x.toPrecision(p);
24656 out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
24658 case ".": i0 = i1 = i; break;
24659 case "0": if (i0 === 0) i0 = i; i1 = i; break;
24660 case "e": break out;
24661 default: if (i0 > 0) i0 = 0; break;
24665 return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
24668 var prefixExponent;
24670 var formatPrefixAuto = function(x, p) {
24671 var d = formatDecimal(x, p);
24672 if (!d) return x + "";
24673 var coefficient = d[0],
24675 i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
24676 n = coefficient.length;
24677 return i === n ? coefficient
24678 : i > n ? coefficient + new Array(i - n + 1).join("0")
24679 : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
24680 : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
24683 var formatRounded = function(x, p) {
24684 var d = formatDecimal(x, p);
24685 if (!d) return x + "";
24686 var coefficient = d[0],
24688 return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
24689 : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
24690 : coefficient + new Array(exponent - coefficient.length + 2).join("0");
24693 var formatTypes = {
24695 "%": function(x, p) { return (x * 100).toFixed(p); },
24696 "b": function(x) { return Math.round(x).toString(2); },
24697 "c": function(x) { return x + ""; },
24698 "d": function(x) { return Math.round(x).toString(10); },
24699 "e": function(x, p) { return x.toExponential(p); },
24700 "f": function(x, p) { return x.toFixed(p); },
24701 "g": function(x, p) { return x.toPrecision(p); },
24702 "o": function(x) { return Math.round(x).toString(8); },
24703 "p": function(x, p) { return formatRounded(x * 100, p); },
24704 "r": formatRounded,
24705 "s": formatPrefixAuto,
24706 "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
24707 "x": function(x) { return Math.round(x).toString(16); }
24710 // [[fill]align][sign][symbol][0][width][,][.precision][type]
24711 var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
24713 var formatSpecifier = function(specifier) {
24714 return new FormatSpecifier(specifier);
24717 function FormatSpecifier(specifier) {
24718 if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
24721 fill = match[1] || " ",
24722 align = match[2] || ">",
24723 sign = match[3] || "-",
24724 symbol = match[4] || "",
24726 width = match[6] && +match[6],
24727 comma = !!match[7],
24728 precision = match[8] && +match[8].slice(1),
24729 type = match[9] || "";
24731 // The "n" type is an alias for ",g".
24732 if (type === "n") comma = true, type = "g";
24734 // Map invalid types to the default format.
24735 else if (!formatTypes[type]) type = "";
24737 // If zero fill is specified, padding goes after sign and before digits.
24738 if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
24741 this.align = align;
24743 this.symbol = symbol;
24745 this.width = width;
24746 this.comma = comma;
24747 this.precision = precision;
24751 FormatSpecifier.prototype.toString = function() {
24756 + (this.zero ? "0" : "")
24757 + (this.width == null ? "" : Math.max(1, this.width | 0))
24758 + (this.comma ? "," : "")
24759 + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
24763 var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
24765 function identity$3(x) {
24769 var formatLocale = function(locale) {
24770 var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
24771 currency = locale.currency,
24772 decimal = locale.decimal;
24774 function newFormat(specifier) {
24775 specifier = formatSpecifier(specifier);
24777 var fill = specifier.fill,
24778 align = specifier.align,
24779 sign = specifier.sign,
24780 symbol = specifier.symbol,
24781 zero = specifier.zero,
24782 width = specifier.width,
24783 comma = specifier.comma,
24784 precision = specifier.precision,
24785 type = specifier.type;
24787 // Compute the prefix and suffix.
24788 // For SI-prefix, the suffix is lazily computed.
24789 var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
24790 suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : "";
24792 // What format function should we use?
24793 // Is this an integer type?
24794 // Can this type generate exponential notation?
24795 var formatType = formatTypes[type],
24796 maybeSuffix = !type || /[defgprs%]/.test(type);
24798 // Set the default precision if not specified,
24799 // or clamp the specified precision to the supported range.
24800 // For significant precision, it must be in [1, 21].
24801 // For fixed precision, it must be in [0, 20].
24802 precision = precision == null ? (type ? 6 : 12)
24803 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
24804 : Math.max(0, Math.min(20, precision));
24806 function format(value) {
24807 var valuePrefix = prefix,
24808 valueSuffix = suffix,
24811 if (type === "c") {
24812 valueSuffix = formatType(value) + valueSuffix;
24817 // Convert negative to positive, and compute the prefix.
24818 // Note that -0 is not less than 0, but 1 / -0 is!
24819 var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true);
24821 // Perform the initial formatting.
24822 value = formatType(value, precision);
24824 // If the original value was negative, it may be rounded to zero during
24825 // formatting; treat this as (positive) zero.
24826 if (valueNegative) {
24827 i = -1, n = value.length;
24828 valueNegative = false;
24830 if (c = value.charCodeAt(i), (48 < c && c < 58)
24831 || (type === "x" && 96 < c && c < 103)
24832 || (type === "X" && 64 < c && c < 71)) {
24833 valueNegative = true;
24839 // Compute the prefix and suffix.
24840 valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
24841 valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
24843 // Break the formatted value into the integer “value” part that can be
24844 // grouped, and fractional or exponential “suffix” part that is not.
24846 i = -1, n = value.length;
24848 if (c = value.charCodeAt(i), 48 > c || c > 57) {
24849 valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
24850 value = value.slice(0, i);
24857 // If the fill character is not "0", grouping is applied before padding.
24858 if (comma && !zero) value = group(value, Infinity);
24860 // Compute the padding.
24861 var length = valuePrefix.length + value.length + valueSuffix.length,
24862 padding = length < width ? new Array(width - length + 1).join(fill) : "";
24864 // If the fill character is "0", grouping is applied after padding.
24865 if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
24867 // Reconstruct the final output based on the desired alignment.
24869 case "<": return valuePrefix + value + valueSuffix + padding;
24870 case "=": return valuePrefix + padding + value + valueSuffix;
24871 case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
24873 return padding + valuePrefix + value + valueSuffix;
24876 format.toString = function() {
24877 return specifier + "";
24883 function formatPrefix(specifier, value) {
24884 var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
24885 e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
24886 k = Math.pow(10, -e),
24887 prefix = prefixes[8 + e / 3];
24888 return function(value) {
24889 return f(k * value) + prefix;
24895 formatPrefix: formatPrefix
24907 currency: ["$", ""]
24910 function defaultLocale(definition) {
24911 locale$1 = formatLocale(definition);
24912 format = locale$1.format;
24913 formatPrefix = locale$1.formatPrefix;
24917 var precisionFixed = function(step) {
24918 return Math.max(0, -exponent$1(Math.abs(step)));
24921 var precisionPrefix = function(step, value) {
24922 return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
24925 var precisionRound = function(step, max) {
24926 step = Math.abs(step), max = Math.abs(max) - step;
24927 return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
24930 function localDate(d) {
24931 if (0 <= d.y && d.y < 100) {
24932 var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
24933 date.setFullYear(d.y);
24936 return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
24939 function utcDate(d) {
24940 if (0 <= d.y && d.y < 100) {
24941 var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
24942 date.setUTCFullYear(d.y);
24945 return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
24948 function newYear(y) {
24949 return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
24952 function formatLocale$1(locale) {
24953 var locale_dateTime = locale.dateTime,
24954 locale_date = locale.date,
24955 locale_time = locale.time,
24956 locale_periods = locale.periods,
24957 locale_weekdays = locale.days,
24958 locale_shortWeekdays = locale.shortDays,
24959 locale_months = locale.months,
24960 locale_shortMonths = locale.shortMonths;
24962 var periodRe = formatRe(locale_periods),
24963 periodLookup = formatLookup(locale_periods),
24964 weekdayRe = formatRe(locale_weekdays),
24965 weekdayLookup = formatLookup(locale_weekdays),
24966 shortWeekdayRe = formatRe(locale_shortWeekdays),
24967 shortWeekdayLookup = formatLookup(locale_shortWeekdays),
24968 monthRe = formatRe(locale_months),
24969 monthLookup = formatLookup(locale_months),
24970 shortMonthRe = formatRe(locale_shortMonths),
24971 shortMonthLookup = formatLookup(locale_shortMonths);
24974 "a": formatShortWeekday,
24975 "A": formatWeekday,
24976 "b": formatShortMonth,
24979 "d": formatDayOfMonth,
24980 "e": formatDayOfMonth,
24983 "j": formatDayOfYear,
24984 "L": formatMilliseconds,
24985 "m": formatMonthNumber,
24986 "M": formatMinutes,
24988 "S": formatSeconds,
24989 "U": formatWeekNumberSunday,
24990 "w": formatWeekdayNumber,
24991 "W": formatWeekNumberMonday,
24995 "Y": formatFullYear,
24997 "%": formatLiteralPercent
25001 "a": formatUTCShortWeekday,
25002 "A": formatUTCWeekday,
25003 "b": formatUTCShortMonth,
25004 "B": formatUTCMonth,
25006 "d": formatUTCDayOfMonth,
25007 "e": formatUTCDayOfMonth,
25008 "H": formatUTCHour24,
25009 "I": formatUTCHour12,
25010 "j": formatUTCDayOfYear,
25011 "L": formatUTCMilliseconds,
25012 "m": formatUTCMonthNumber,
25013 "M": formatUTCMinutes,
25014 "p": formatUTCPeriod,
25015 "S": formatUTCSeconds,
25016 "U": formatUTCWeekNumberSunday,
25017 "w": formatUTCWeekdayNumber,
25018 "W": formatUTCWeekNumberMonday,
25021 "y": formatUTCYear,
25022 "Y": formatUTCFullYear,
25023 "Z": formatUTCZone,
25024 "%": formatLiteralPercent
25028 "a": parseShortWeekday,
25030 "b": parseShortMonth,
25032 "c": parseLocaleDateTime,
25033 "d": parseDayOfMonth,
25034 "e": parseDayOfMonth,
25037 "j": parseDayOfYear,
25038 "L": parseMilliseconds,
25039 "m": parseMonthNumber,
25043 "U": parseWeekNumberSunday,
25044 "w": parseWeekdayNumber,
25045 "W": parseWeekNumberMonday,
25046 "x": parseLocaleDate,
25047 "X": parseLocaleTime,
25049 "Y": parseFullYear,
25051 "%": parseLiteralPercent
25054 // These recursive directive definitions must be deferred.
25055 formats.x = newFormat(locale_date, formats);
25056 formats.X = newFormat(locale_time, formats);
25057 formats.c = newFormat(locale_dateTime, formats);
25058 utcFormats.x = newFormat(locale_date, utcFormats);
25059 utcFormats.X = newFormat(locale_time, utcFormats);
25060 utcFormats.c = newFormat(locale_dateTime, utcFormats);
25062 function newFormat(specifier, formats) {
25063 return function(date) {
25067 n = specifier.length,
25072 if (!(date instanceof Date)) date = new Date(+date);
25075 if (specifier.charCodeAt(i) === 37) {
25076 string.push(specifier.slice(j, i));
25077 if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
25078 else pad = c === "e" ? " " : "0";
25079 if (format = formats[c]) c = format(date, pad);
25085 string.push(specifier.slice(j, i));
25086 return string.join("");
25090 function newParse(specifier, newDate) {
25091 return function(string) {
25092 var d = newYear(1900),
25093 i = parseSpecifier(d, specifier, string += "", 0);
25094 if (i != string.length) return null;
25096 // The am-pm flag is 0 for AM, and 1 for PM.
25097 if ("p" in d) d.H = d.H % 12 + d.p * 12;
25099 // Convert day-of-week and week-of-year to day-of-year.
25100 if ("W" in d || "U" in d) {
25101 if (!("w" in d)) d.w = "W" in d ? 1 : 0;
25102 var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
25104 d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7;
25107 // If a time zone is specified, all fields are interpreted as UTC and then
25108 // offset according to the specified time zone.
25110 d.H += d.Z / 100 | 0;
25115 // Otherwise, all fields are in local time.
25120 function parseSpecifier(d, specifier, string, j) {
25122 n = specifier.length,
25128 if (j >= m) return -1;
25129 c = specifier.charCodeAt(i++);
25131 c = specifier.charAt(i++);
25132 parse = parses[c in pads ? specifier.charAt(i++) : c];
25133 if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
25134 } else if (c != string.charCodeAt(j++)) {
25142 function parsePeriod(d, string, i) {
25143 var n = periodRe.exec(string.slice(i));
25144 return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25147 function parseShortWeekday(d, string, i) {
25148 var n = shortWeekdayRe.exec(string.slice(i));
25149 return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25152 function parseWeekday(d, string, i) {
25153 var n = weekdayRe.exec(string.slice(i));
25154 return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25157 function parseShortMonth(d, string, i) {
25158 var n = shortMonthRe.exec(string.slice(i));
25159 return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25162 function parseMonth(d, string, i) {
25163 var n = monthRe.exec(string.slice(i));
25164 return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
25167 function parseLocaleDateTime(d, string, i) {
25168 return parseSpecifier(d, locale_dateTime, string, i);
25171 function parseLocaleDate(d, string, i) {
25172 return parseSpecifier(d, locale_date, string, i);
25175 function parseLocaleTime(d, string, i) {
25176 return parseSpecifier(d, locale_time, string, i);
25179 function formatShortWeekday(d) {
25180 return locale_shortWeekdays[d.getDay()];
25183 function formatWeekday(d) {
25184 return locale_weekdays[d.getDay()];
25187 function formatShortMonth(d) {
25188 return locale_shortMonths[d.getMonth()];
25191 function formatMonth(d) {
25192 return locale_months[d.getMonth()];
25195 function formatPeriod(d) {
25196 return locale_periods[+(d.getHours() >= 12)];
25199 function formatUTCShortWeekday(d) {
25200 return locale_shortWeekdays[d.getUTCDay()];
25203 function formatUTCWeekday(d) {
25204 return locale_weekdays[d.getUTCDay()];
25207 function formatUTCShortMonth(d) {
25208 return locale_shortMonths[d.getUTCMonth()];
25211 function formatUTCMonth(d) {
25212 return locale_months[d.getUTCMonth()];
25215 function formatUTCPeriod(d) {
25216 return locale_periods[+(d.getUTCHours() >= 12)];
25220 format: function(specifier) {
25221 var f = newFormat(specifier += "", formats);
25222 f.toString = function() { return specifier; };
25225 parse: function(specifier) {
25226 var p = newParse(specifier += "", localDate);
25227 p.toString = function() { return specifier; };
25230 utcFormat: function(specifier) {
25231 var f = newFormat(specifier += "", utcFormats);
25232 f.toString = function() { return specifier; };
25235 utcParse: function(specifier) {
25236 var p = newParse(specifier, utcDate);
25237 p.toString = function() { return specifier; };
25243 var pads = {"-": "", "_": " ", "0": "0"};
25244 var numberRe = /^\s*\d+/;
25245 var percentRe = /^%/;
25246 var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
25248 function pad(value, fill, width) {
25249 var sign = value < 0 ? "-" : "",
25250 string = (sign ? -value : value) + "",
25251 length = string.length;
25252 return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
25255 function requote(s) {
25256 return s.replace(requoteRe, "\\$&");
25259 function formatRe(names) {
25260 return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
25263 function formatLookup(names) {
25264 var map = {}, i = -1, n = names.length;
25265 while (++i < n) map[names[i].toLowerCase()] = i;
25269 function parseWeekdayNumber(d, string, i) {
25270 var n = numberRe.exec(string.slice(i, i + 1));
25271 return n ? (d.w = +n[0], i + n[0].length) : -1;
25274 function parseWeekNumberSunday(d, string, i) {
25275 var n = numberRe.exec(string.slice(i));
25276 return n ? (d.U = +n[0], i + n[0].length) : -1;
25279 function parseWeekNumberMonday(d, string, i) {
25280 var n = numberRe.exec(string.slice(i));
25281 return n ? (d.W = +n[0], i + n[0].length) : -1;
25284 function parseFullYear(d, string, i) {
25285 var n = numberRe.exec(string.slice(i, i + 4));
25286 return n ? (d.y = +n[0], i + n[0].length) : -1;
25289 function parseYear(d, string, i) {
25290 var n = numberRe.exec(string.slice(i, i + 2));
25291 return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
25294 function parseZone(d, string, i) {
25295 var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6));
25296 return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
25299 function parseMonthNumber(d, string, i) {
25300 var n = numberRe.exec(string.slice(i, i + 2));
25301 return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
25304 function parseDayOfMonth(d, string, i) {
25305 var n = numberRe.exec(string.slice(i, i + 2));
25306 return n ? (d.d = +n[0], i + n[0].length) : -1;
25309 function parseDayOfYear(d, string, i) {
25310 var n = numberRe.exec(string.slice(i, i + 3));
25311 return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
25314 function parseHour24(d, string, i) {
25315 var n = numberRe.exec(string.slice(i, i + 2));
25316 return n ? (d.H = +n[0], i + n[0].length) : -1;
25319 function parseMinutes(d, string, i) {
25320 var n = numberRe.exec(string.slice(i, i + 2));
25321 return n ? (d.M = +n[0], i + n[0].length) : -1;
25324 function parseSeconds(d, string, i) {
25325 var n = numberRe.exec(string.slice(i, i + 2));
25326 return n ? (d.S = +n[0], i + n[0].length) : -1;
25329 function parseMilliseconds(d, string, i) {
25330 var n = numberRe.exec(string.slice(i, i + 3));
25331 return n ? (d.L = +n[0], i + n[0].length) : -1;
25334 function parseLiteralPercent(d, string, i) {
25335 var n = percentRe.exec(string.slice(i, i + 1));
25336 return n ? i + n[0].length : -1;
25339 function formatDayOfMonth(d, p) {
25340 return pad(d.getDate(), p, 2);
25343 function formatHour24(d, p) {
25344 return pad(d.getHours(), p, 2);
25347 function formatHour12(d, p) {
25348 return pad(d.getHours() % 12 || 12, p, 2);
25351 function formatDayOfYear(d, p) {
25352 return pad(1 + day.count(year(d), d), p, 3);
25355 function formatMilliseconds(d, p) {
25356 return pad(d.getMilliseconds(), p, 3);
25359 function formatMonthNumber(d, p) {
25360 return pad(d.getMonth() + 1, p, 2);
25363 function formatMinutes(d, p) {
25364 return pad(d.getMinutes(), p, 2);
25367 function formatSeconds(d, p) {
25368 return pad(d.getSeconds(), p, 2);
25371 function formatWeekNumberSunday(d, p) {
25372 return pad(sunday.count(year(d), d), p, 2);
25375 function formatWeekdayNumber(d) {
25379 function formatWeekNumberMonday(d, p) {
25380 return pad(monday.count(year(d), d), p, 2);
25383 function formatYear(d, p) {
25384 return pad(d.getFullYear() % 100, p, 2);
25387 function formatFullYear(d, p) {
25388 return pad(d.getFullYear() % 10000, p, 4);
25391 function formatZone(d) {
25392 var z = d.getTimezoneOffset();
25393 return (z > 0 ? "-" : (z *= -1, "+"))
25394 + pad(z / 60 | 0, "0", 2)
25395 + pad(z % 60, "0", 2);
25398 function formatUTCDayOfMonth(d, p) {
25399 return pad(d.getUTCDate(), p, 2);
25402 function formatUTCHour24(d, p) {
25403 return pad(d.getUTCHours(), p, 2);
25406 function formatUTCHour12(d, p) {
25407 return pad(d.getUTCHours() % 12 || 12, p, 2);
25410 function formatUTCDayOfYear(d, p) {
25411 return pad(1 + utcDay.count(utcYear(d), d), p, 3);
25414 function formatUTCMilliseconds(d, p) {
25415 return pad(d.getUTCMilliseconds(), p, 3);
25418 function formatUTCMonthNumber(d, p) {
25419 return pad(d.getUTCMonth() + 1, p, 2);
25422 function formatUTCMinutes(d, p) {
25423 return pad(d.getUTCMinutes(), p, 2);
25426 function formatUTCSeconds(d, p) {
25427 return pad(d.getUTCSeconds(), p, 2);
25430 function formatUTCWeekNumberSunday(d, p) {
25431 return pad(utcSunday.count(utcYear(d), d), p, 2);
25434 function formatUTCWeekdayNumber(d) {
25435 return d.getUTCDay();
25438 function formatUTCWeekNumberMonday(d, p) {
25439 return pad(utcMonday.count(utcYear(d), d), p, 2);
25442 function formatUTCYear(d, p) {
25443 return pad(d.getUTCFullYear() % 100, p, 2);
25446 function formatUTCFullYear(d, p) {
25447 return pad(d.getUTCFullYear() % 10000, p, 4);
25450 function formatUTCZone() {
25454 function formatLiteralPercent() {
25465 dateTime: "%x, %X",
25466 date: "%-m/%-d/%Y",
25467 time: "%-I:%M:%S %p",
25468 periods: ["AM", "PM"],
25469 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
25470 shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
25471 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
25472 shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
25475 function defaultLocale$1(definition) {
25476 locale$2 = formatLocale$1(definition);
25477 timeFormat = locale$2.format;
25478 timeParse = locale$2.parse;
25479 utcFormat = locale$2.utcFormat;
25480 utcParse = locale$2.utcParse;
25484 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
25486 function formatIsoNative(date) {
25487 return date.toISOString();
25490 var formatIso = Date.prototype.toISOString
25492 : utcFormat(isoSpecifier);
25494 function parseIsoNative(string) {
25495 var date = new Date(string);
25496 return isNaN(date) ? null : date;
25499 var parseIso = +new Date("2000-01-01T00:00:00.000Z")
25501 : utcParse(isoSpecifier);
25503 var array$2 = Array.prototype;
25505 var map$3 = array$2.map;
25506 var slice$3 = array$2.slice;
25508 var implicit = {name: "implicit"};
25510 function ordinal(range) {
25511 var index = map$1(),
25513 unknown = implicit;
25515 range = range == null ? [] : slice$3.call(range);
25517 function scale(d) {
25518 var key = d + "", i = index.get(key);
25520 if (unknown !== implicit) return unknown;
25521 index.set(key, i = domain.push(d));
25523 return range[(i - 1) % range.length];
25526 scale.domain = function(_) {
25527 if (!arguments.length) return domain.slice();
25528 domain = [], index = map$1();
25529 var i = -1, n = _.length, d, key;
25530 while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
25534 scale.range = function(_) {
25535 return arguments.length ? (range = slice$3.call(_), scale) : range.slice();
25538 scale.unknown = function(_) {
25539 return arguments.length ? (unknown = _, scale) : unknown;
25542 scale.copy = function() {
25553 var scale = ordinal().unknown(undefined),
25554 domain = scale.domain,
25555 ordinalRange = scale.range,
25564 delete scale.unknown;
25566 function rescale() {
25567 var n = domain().length,
25568 reverse = range$$1[1] < range$$1[0],
25569 start = range$$1[reverse - 0],
25570 stop = range$$1[1 - reverse];
25571 step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
25572 if (round) step = Math.floor(step);
25573 start += (stop - start - step * (n - paddingInner)) * align;
25574 bandwidth = step * (1 - paddingInner);
25575 if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
25576 var values = range(n).map(function(i) { return start + step * i; });
25577 return ordinalRange(reverse ? values.reverse() : values);
25580 scale.domain = function(_) {
25581 return arguments.length ? (domain(_), rescale()) : domain();
25584 scale.range = function(_) {
25585 return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
25588 scale.rangeRound = function(_) {
25589 return range$$1 = [+_[0], +_[1]], round = true, rescale();
25592 scale.bandwidth = function() {
25596 scale.step = function() {
25600 scale.round = function(_) {
25601 return arguments.length ? (round = !!_, rescale()) : round;
25604 scale.padding = function(_) {
25605 return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
25608 scale.paddingInner = function(_) {
25609 return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
25612 scale.paddingOuter = function(_) {
25613 return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
25616 scale.align = function(_) {
25617 return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
25620 scale.copy = function() {
25625 .paddingInner(paddingInner)
25626 .paddingOuter(paddingOuter)
25633 function pointish(scale) {
25634 var copy = scale.copy;
25636 scale.padding = scale.paddingOuter;
25637 delete scale.paddingInner;
25638 delete scale.paddingOuter;
25640 scale.copy = function() {
25641 return pointish(copy());
25647 function point$4() {
25648 return pointish(band().paddingInner(1));
25651 var constant$4 = function(x) {
25652 return function() {
25657 var number$1 = function(x) {
25663 function deinterpolateLinear(a, b) {
25664 return (b -= (a = +a))
25665 ? function(x) { return (x - a) / b; }
25669 function deinterpolateClamp(deinterpolate) {
25670 return function(a, b) {
25671 var d = deinterpolate(a = +a, b = +b);
25672 return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
25676 function reinterpolateClamp(reinterpolate) {
25677 return function(a, b) {
25678 var r = reinterpolate(a = +a, b = +b);
25679 return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
25683 function bimap(domain, range$$1, deinterpolate, reinterpolate) {
25684 var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1];
25685 if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
25686 else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
25687 return function(x) { return r0(d0(x)); };
25690 function polymap(domain, range$$1, deinterpolate, reinterpolate) {
25691 var j = Math.min(domain.length, range$$1.length) - 1,
25696 // Reverse descending domains.
25697 if (domain[j] < domain[0]) {
25698 domain = domain.slice().reverse();
25699 range$$1 = range$$1.slice().reverse();
25703 d[i] = deinterpolate(domain[i], domain[i + 1]);
25704 r[i] = reinterpolate(range$$1[i], range$$1[i + 1]);
25707 return function(x) {
25708 var i = bisectRight(domain, x, 1, j) - 1;
25709 return r[i](d[i](x));
25713 function copy(source, target) {
25715 .domain(source.domain())
25716 .range(source.range())
25717 .interpolate(source.interpolate())
25718 .clamp(source.clamp());
25721 // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
25722 // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
25723 function continuous(deinterpolate, reinterpolate) {
25726 interpolate$$1 = interpolate,
25732 function rescale() {
25733 piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap;
25734 output = input = null;
25738 function scale(x) {
25739 return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);
25742 scale.invert = function(y) {
25743 return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
25746 scale.domain = function(_) {
25747 return arguments.length ? (domain = map$3.call(_, number$1), rescale()) : domain.slice();
25750 scale.range = function(_) {
25751 return arguments.length ? (range$$1 = slice$3.call(_), rescale()) : range$$1.slice();
25754 scale.rangeRound = function(_) {
25755 return range$$1 = slice$3.call(_), interpolate$$1 = interpolateRound, rescale();
25758 scale.clamp = function(_) {
25759 return arguments.length ? (clamp = !!_, rescale()) : clamp;
25762 scale.interpolate = function(_) {
25763 return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;
25769 var tickFormat = function(domain, count, specifier) {
25770 var start = domain[0],
25771 stop = domain[domain.length - 1],
25772 step = tickStep(start, stop, count == null ? 10 : count),
25774 specifier = formatSpecifier(specifier == null ? ",f" : specifier);
25775 switch (specifier.type) {
25777 var value = Math.max(Math.abs(start), Math.abs(stop));
25778 if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
25779 return formatPrefix(specifier, value);
25786 if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
25791 if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
25795 return format(specifier);
25798 function linearish(scale) {
25799 var domain = scale.domain;
25801 scale.ticks = function(count) {
25803 return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
25806 scale.tickFormat = function(count, specifier) {
25807 return tickFormat(domain(), count, specifier);
25810 scale.nice = function(count) {
25813 n = count == null ? 10 : count,
25816 step = tickStep(start, stop, n);
25819 step = tickStep(Math.floor(start / step) * step, Math.ceil(stop / step) * step, n);
25820 d[0] = Math.floor(start / step) * step;
25821 d[i] = Math.ceil(stop / step) * step;
25831 function linear$2() {
25832 var scale = continuous(deinterpolateLinear, interpolateNumber);
25834 scale.copy = function() {
25835 return copy(scale, linear$2());
25838 return linearish(scale);
25841 function identity$4() {
25842 var domain = [0, 1];
25844 function scale(x) {
25848 scale.invert = scale;
25850 scale.domain = scale.range = function(_) {
25851 return arguments.length ? (domain = map$3.call(_, number$1), scale) : domain.slice();
25854 scale.copy = function() {
25855 return identity$4().domain(domain);
25858 return linearish(scale);
25861 var nice = function(domain, interval) {
25862 domain = domain.slice();
25865 i1 = domain.length - 1,
25871 t = i0, i0 = i1, i1 = t;
25872 t = x0, x0 = x1, x1 = t;
25875 domain[i0] = interval.floor(x0);
25876 domain[i1] = interval.ceil(x1);
25880 function deinterpolate(a, b) {
25881 return (b = Math.log(b / a))
25882 ? function(x) { return Math.log(x / a) / b; }
25886 function reinterpolate(a, b) {
25888 ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
25889 : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
25892 function pow10(x) {
25893 return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
25896 function powp(base) {
25897 return base === 10 ? pow10
25898 : base === Math.E ? Math.exp
25899 : function(x) { return Math.pow(base, x); };
25902 function logp(base) {
25903 return base === Math.E ? Math.log
25904 : base === 10 && Math.log10
25905 || base === 2 && Math.log2
25906 || (base = Math.log(base), function(x) { return Math.log(x) / base; });
25909 function reflect(f) {
25910 return function(x) {
25916 var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]),
25917 domain = scale.domain,
25922 function rescale() {
25923 logs = logp(base), pows = powp(base);
25924 if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
25928 scale.base = function(_) {
25929 return arguments.length ? (base = +_, rescale()) : base;
25932 scale.domain = function(_) {
25933 return arguments.length ? (domain(_), rescale()) : domain();
25936 scale.ticks = function(count) {
25939 v = d[d.length - 1],
25942 if (r = v < u) i = u, u = v, v = i;
25949 n = count == null ? 10 : +count,
25952 if (!(base % 1) && j - i < n) {
25953 i = Math.round(i) - 1, j = Math.round(j) + 1;
25954 if (u > 0) for (; i < j; ++i) {
25955 for (k = 1, p = pows(i); k < base; ++k) {
25957 if (t < u) continue;
25961 } else for (; i < j; ++i) {
25962 for (k = base - 1, p = pows(i); k >= 1; --k) {
25964 if (t < u) continue;
25970 z = ticks(i, j, Math.min(j - i, n)).map(pows);
25973 return r ? z.reverse() : z;
25976 scale.tickFormat = function(count, specifier) {
25977 if (specifier == null) specifier = base === 10 ? ".0e" : ",";
25978 if (typeof specifier !== "function") specifier = format(specifier);
25979 if (count === Infinity) return specifier;
25980 if (count == null) count = 10;
25981 var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
25982 return function(d) {
25983 var i = d / pows(Math.round(logs(d)));
25984 if (i * base < base - 0.5) i *= base;
25985 return i <= k ? specifier(d) : "";
25989 scale.nice = function() {
25990 return domain(nice(domain(), {
25991 floor: function(x) { return pows(Math.floor(logs(x))); },
25992 ceil: function(x) { return pows(Math.ceil(logs(x))); }
25996 scale.copy = function() {
25997 return copy(scale, log().base(base));
26003 function raise(x, exponent) {
26004 return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
26009 scale = continuous(deinterpolate, reinterpolate),
26010 domain = scale.domain;
26012 function deinterpolate(a, b) {
26013 return (b = raise(b, exponent) - (a = raise(a, exponent)))
26014 ? function(x) { return (raise(x, exponent) - a) / b; }
26018 function reinterpolate(a, b) {
26019 b = raise(b, exponent) - (a = raise(a, exponent));
26020 return function(t) { return raise(a + b * t, 1 / exponent); };
26023 scale.exponent = function(_) {
26024 return arguments.length ? (exponent = +_, domain(domain())) : exponent;
26027 scale.copy = function() {
26028 return copy(scale, pow().exponent(exponent));
26031 return linearish(scale);
26035 return pow().exponent(0.5);
26038 function quantile$$1() {
26043 function rescale() {
26044 var i = 0, n = Math.max(1, range$$1.length);
26045 thresholds = new Array(n - 1);
26046 while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
26050 function scale(x) {
26051 if (!isNaN(x = +x)) return range$$1[bisectRight(thresholds, x)];
26054 scale.invertExtent = function(y) {
26055 var i = range$$1.indexOf(y);
26056 return i < 0 ? [NaN, NaN] : [
26057 i > 0 ? thresholds[i - 1] : domain[0],
26058 i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
26062 scale.domain = function(_) {
26063 if (!arguments.length) return domain.slice();
26065 for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
26066 domain.sort(ascending);
26070 scale.range = function(_) {
26071 return arguments.length ? (range$$1 = slice$3.call(_), rescale()) : range$$1.slice();
26074 scale.quantiles = function() {
26075 return thresholds.slice();
26078 scale.copy = function() {
26079 return quantile$$1()
26087 function quantize$1() {
26094 function scale(x) {
26095 if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
26098 function rescale() {
26100 domain = new Array(n);
26101 while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
26105 scale.domain = function(_) {
26106 return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
26109 scale.range = function(_) {
26110 return arguments.length ? (n = (range$$1 = slice$3.call(_)).length - 1, rescale()) : range$$1.slice();
26113 scale.invertExtent = function(y) {
26114 var i = range$$1.indexOf(y);
26115 return i < 0 ? [NaN, NaN]
26116 : i < 1 ? [x0, domain[0]]
26117 : i >= n ? [domain[n - 1], x1]
26118 : [domain[i - 1], domain[i]];
26121 scale.copy = function() {
26122 return quantize$1()
26127 return linearish(scale);
26130 function threshold$1() {
26131 var domain = [0.5],
26135 function scale(x) {
26136 if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
26139 scale.domain = function(_) {
26140 return arguments.length ? (domain = slice$3.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice();
26143 scale.range = function(_) {
26144 return arguments.length ? (range$$1 = slice$3.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice();
26147 scale.invertExtent = function(y) {
26148 var i = range$$1.indexOf(y);
26149 return [domain[i - 1], domain[i]];
26152 scale.copy = function() {
26153 return threshold$1()
26161 var durationSecond$1 = 1000;
26162 var durationMinute$1 = durationSecond$1 * 60;
26163 var durationHour$1 = durationMinute$1 * 60;
26164 var durationDay$1 = durationHour$1 * 24;
26165 var durationWeek$1 = durationDay$1 * 7;
26166 var durationMonth = durationDay$1 * 30;
26167 var durationYear = durationDay$1 * 365;
26169 function date$1(t) {
26170 return new Date(t);
26173 function number$2(t) {
26174 return t instanceof Date ? +t : +new Date(+t);
26177 function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
26178 var scale = continuous(deinterpolateLinear, interpolateNumber),
26179 invert = scale.invert,
26180 domain = scale.domain;
26182 var formatMillisecond = format(".%L"),
26183 formatSecond = format(":%S"),
26184 formatMinute = format("%I:%M"),
26185 formatHour = format("%I %p"),
26186 formatDay = format("%a %d"),
26187 formatWeek = format("%b %d"),
26188 formatMonth = format("%B"),
26189 formatYear = format("%Y");
26191 var tickIntervals = [
26192 [second$$1, 1, durationSecond$1],
26193 [second$$1, 5, 5 * durationSecond$1],
26194 [second$$1, 15, 15 * durationSecond$1],
26195 [second$$1, 30, 30 * durationSecond$1],
26196 [minute$$1, 1, durationMinute$1],
26197 [minute$$1, 5, 5 * durationMinute$1],
26198 [minute$$1, 15, 15 * durationMinute$1],
26199 [minute$$1, 30, 30 * durationMinute$1],
26200 [ hour$$1, 1, durationHour$1 ],
26201 [ hour$$1, 3, 3 * durationHour$1 ],
26202 [ hour$$1, 6, 6 * durationHour$1 ],
26203 [ hour$$1, 12, 12 * durationHour$1 ],
26204 [ day$$1, 1, durationDay$1 ],
26205 [ day$$1, 2, 2 * durationDay$1 ],
26206 [ week, 1, durationWeek$1 ],
26207 [ month$$1, 1, durationMonth ],
26208 [ month$$1, 3, 3 * durationMonth ],
26209 [ year$$1, 1, durationYear ]
26212 function tickFormat(date) {
26213 return (second$$1(date) < date ? formatMillisecond
26214 : minute$$1(date) < date ? formatSecond
26215 : hour$$1(date) < date ? formatMinute
26216 : day$$1(date) < date ? formatHour
26217 : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)
26218 : year$$1(date) < date ? formatMonth
26219 : formatYear)(date);
26222 function tickInterval(interval, start, stop, step) {
26223 if (interval == null) interval = 10;
26225 // If a desired tick count is specified, pick a reasonable tick interval
26226 // based on the extent of the domain and a rough estimate of tick size.
26227 // Otherwise, assume interval is already a time interval and use it.
26228 if (typeof interval === "number") {
26229 var target = Math.abs(stop - start) / interval,
26230 i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);
26231 if (i === tickIntervals.length) {
26232 step = tickStep(start / durationYear, stop / durationYear, interval);
26233 interval = year$$1;
26235 i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
26239 step = tickStep(start, stop, interval);
26240 interval = millisecond$$1;
26244 return step == null ? interval : interval.every(step);
26247 scale.invert = function(y) {
26248 return new Date(invert(y));
26251 scale.domain = function(_) {
26252 return arguments.length ? domain(map$3.call(_, number$2)) : domain().map(date$1);
26255 scale.ticks = function(interval, step) {
26258 t1 = d[d.length - 1],
26261 if (r) t = t0, t0 = t1, t1 = t;
26262 t = tickInterval(interval, t0, t1, step);
26263 t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
26264 return r ? t.reverse() : t;
26267 scale.tickFormat = function(count, specifier) {
26268 return specifier == null ? tickFormat : format(specifier);
26271 scale.nice = function(interval, step) {
26273 return (interval = tickInterval(interval, d[0], d[d.length - 1], step))
26274 ? domain(nice(d, interval))
26278 scale.copy = function() {
26279 return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
26285 var time = function() {
26286 return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
26289 var utcTime = function() {
26290 return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
26293 var colors = function(s) {
26294 return s.match(/.{6}/g).map(function(x) {
26299 var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
26301 var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
26303 var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
26305 var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
26307 var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
26309 var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
26311 var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
26313 var rainbow = cubehelix();
26315 var rainbow$1 = function(t) {
26316 if (t < 0 || t > 1) t -= Math.floor(t);
26317 var ts = Math.abs(t - 0.5);
26318 rainbow.h = 360 * t - 100;
26319 rainbow.s = 1.5 - 1.5 * ts;
26320 rainbow.l = 0.8 - 0.9 * ts;
26321 return rainbow + "";
26324 function ramp(range) {
26325 var n = range.length;
26326 return function(t) {
26327 return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
26331 var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
26333 var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
26335 var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
26337 var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
26339 function sequential(interpolator) {
26344 function scale(x) {
26345 var t = (x - x0) / (x1 - x0);
26346 return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
26349 scale.domain = function(_) {
26350 return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
26353 scale.clamp = function(_) {
26354 return arguments.length ? (clamp = !!_, scale) : clamp;
26357 scale.interpolator = function(_) {
26358 return arguments.length ? (interpolator = _, scale) : interpolator;
26361 scale.copy = function() {
26362 return sequential(interpolator).domain([x0, x1]).clamp(clamp);
26365 return linearish(scale);
26368 var xhtml = "http://www.w3.org/1999/xhtml";
26371 svg: "http://www.w3.org/2000/svg",
26373 xlink: "http://www.w3.org/1999/xlink",
26374 xml: "http://www.w3.org/XML/1998/namespace",
26375 xmlns: "http://www.w3.org/2000/xmlns/"
26378 var namespace = function(name) {
26379 var prefix = name += "", i = prefix.indexOf(":");
26380 if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
26381 return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
26384 function creatorInherit(name) {
26385 return function() {
26386 var document = this.ownerDocument,
26387 uri = this.namespaceURI;
26388 return uri === xhtml && document.documentElement.namespaceURI === xhtml
26389 ? document.createElement(name)
26390 : document.createElementNS(uri, name);
26394 function creatorFixed(fullname) {
26395 return function() {
26396 return this.ownerDocument.createElementNS(fullname.space, fullname.local);
26400 var creator = function(name) {
26401 var fullname = namespace(name);
26402 return (fullname.local
26404 : creatorInherit)(fullname);
26414 this._ = "@" + (++nextId).toString(36);
26417 Local.prototype = local.prototype = {
26418 constructor: Local,
26419 get: function(node) {
26421 while (!(id in node)) if (!(node = node.parentNode)) return;
26424 set: function(node, value) {
26425 return node[this._] = value;
26427 remove: function(node) {
26428 return this._ in node && delete node[this._];
26430 toString: function() {
26435 var matcher = function(selector) {
26436 return function() {
26437 return this.matches(selector);
26441 if (typeof document !== "undefined") {
26442 var element = document.documentElement;
26443 if (!element.matches) {
26444 var vendorMatches = element.webkitMatchesSelector
26445 || element.msMatchesSelector
26446 || element.mozMatchesSelector
26447 || element.oMatchesSelector;
26448 matcher = function(selector) {
26449 return function() {
26450 return vendorMatches.call(this, selector);
26456 var matcher$1 = matcher;
26458 var filterEvents = {};
26462 if (typeof document !== "undefined") {
26463 var element$1 = document.documentElement;
26464 if (!("onmouseenter" in element$1)) {
26465 filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
26469 function filterContextListener(listener, index, group) {
26470 listener = contextListener(listener, index, group);
26471 return function(event) {
26472 var related = event.relatedTarget;
26473 if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
26474 listener.call(this, event);
26479 function contextListener(listener, index, group) {
26480 return function(event1) {
26481 var event0 = event; // Events can be reentrant (e.g., focus).
26484 listener.call(this, this.__data__, index, group);
26491 function parseTypenames$1(typenames) {
26492 return typenames.trim().split(/^|\s+/).map(function(t) {
26493 var name = "", i = t.indexOf(".");
26494 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
26495 return {type: t, name: name};
26499 function onRemove(typename) {
26500 return function() {
26501 var on = this.__on;
26503 for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
26504 if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
26505 this.removeEventListener(o.type, o.listener, o.capture);
26510 if (++i) on.length = i;
26511 else delete this.__on;
26515 function onAdd(typename, value, capture) {
26516 var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
26517 return function(d, i, group) {
26518 var on = this.__on, o, listener = wrap(value, i, group);
26519 if (on) for (var j = 0, m = on.length; j < m; ++j) {
26520 if ((o = on[j]).type === typename.type && o.name === typename.name) {
26521 this.removeEventListener(o.type, o.listener, o.capture);
26522 this.addEventListener(o.type, o.listener = listener, o.capture = capture);
26527 this.addEventListener(typename.type, listener, capture);
26528 o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
26529 if (!on) this.__on = [o];
26534 var selection_on = function(typename, value, capture) {
26535 var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
26537 if (arguments.length < 2) {
26538 var on = this.node().__on;
26539 if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
26540 for (i = 0, o = on[j]; i < n; ++i) {
26541 if ((t = typenames[i]).type === o.type && t.name === o.name) {
26549 on = value ? onAdd : onRemove;
26550 if (capture == null) capture = false;
26551 for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
26555 function customEvent(event1, listener, that, args) {
26556 var event0 = event;
26557 event1.sourceEvent = event;
26560 return listener.apply(that, args);
26566 var sourceEvent = function() {
26567 var current = event, source;
26568 while (source = current.sourceEvent) current = source;
26572 var point$5 = function(node, event) {
26573 var svg = node.ownerSVGElement || node;
26575 if (svg.createSVGPoint) {
26576 var point = svg.createSVGPoint();
26577 point.x = event.clientX, point.y = event.clientY;
26578 point = point.matrixTransform(node.getScreenCTM().inverse());
26579 return [point.x, point.y];
26582 var rect = node.getBoundingClientRect();
26583 return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
26586 var mouse = function(node) {
26587 var event = sourceEvent();
26588 if (event.changedTouches) event = event.changedTouches[0];
26589 return point$5(node, event);
26592 function none$2() {}
26594 var selector = function(selector) {
26595 return selector == null ? none$2 : function() {
26596 return this.querySelector(selector);
26600 var selection_select = function(select) {
26601 if (typeof select !== "function") select = selector(select);
26603 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
26604 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
26605 if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
26606 if ("__data__" in node) subnode.__data__ = node.__data__;
26607 subgroup[i] = subnode;
26612 return new Selection(subgroups, this._parents);
26619 var selectorAll = function(selector) {
26620 return selector == null ? empty : function() {
26621 return this.querySelectorAll(selector);
26625 var selection_selectAll = function(select) {
26626 if (typeof select !== "function") select = selectorAll(select);
26628 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
26629 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
26630 if (node = group[i]) {
26631 subgroups.push(select.call(node, node.__data__, i, group));
26632 parents.push(node);
26637 return new Selection(subgroups, parents);
26640 var selection_filter = function(match) {
26641 if (typeof match !== "function") match = matcher$1(match);
26643 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
26644 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
26645 if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
26646 subgroup.push(node);
26651 return new Selection(subgroups, this._parents);
26654 var sparse = function(update) {
26655 return new Array(update.length);
26658 var selection_enter = function() {
26659 return new Selection(this._enter || this._groups.map(sparse), this._parents);
26662 function EnterNode(parent, datum) {
26663 this.ownerDocument = parent.ownerDocument;
26664 this.namespaceURI = parent.namespaceURI;
26666 this._parent = parent;
26667 this.__data__ = datum;
26670 EnterNode.prototype = {
26671 constructor: EnterNode,
26672 appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
26673 insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
26674 querySelector: function(selector) { return this._parent.querySelector(selector); },
26675 querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
26678 var constant$5 = function(x) {
26679 return function() {
26684 var keyPrefix = "$"; // Protect against keys like “__proto__”.
26686 function bindIndex(parent, group, enter, update, exit, data) {
26689 groupLength = group.length,
26690 dataLength = data.length;
26692 // Put any non-null nodes that fit into update.
26693 // Put any null nodes into enter.
26694 // Put any remaining data into enter.
26695 for (; i < dataLength; ++i) {
26696 if (node = group[i]) {
26697 node.__data__ = data[i];
26700 enter[i] = new EnterNode(parent, data[i]);
26704 // Put any non-null nodes that don’t fit into exit.
26705 for (; i < groupLength; ++i) {
26706 if (node = group[i]) {
26712 function bindKey(parent, group, enter, update, exit, data, key) {
26715 nodeByKeyValue = {},
26716 groupLength = group.length,
26717 dataLength = data.length,
26718 keyValues = new Array(groupLength),
26721 // Compute the key for each node.
26722 // If multiple nodes have the same key, the duplicates are added to exit.
26723 for (i = 0; i < groupLength; ++i) {
26724 if (node = group[i]) {
26725 keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
26726 if (keyValue in nodeByKeyValue) {
26729 nodeByKeyValue[keyValue] = node;
26734 // Compute the key for each datum.
26735 // If there a node associated with this key, join and add it to update.
26736 // If there is not (or the key is a duplicate), add it to enter.
26737 for (i = 0; i < dataLength; ++i) {
26738 keyValue = keyPrefix + key.call(parent, data[i], i, data);
26739 if (node = nodeByKeyValue[keyValue]) {
26741 node.__data__ = data[i];
26742 nodeByKeyValue[keyValue] = null;
26744 enter[i] = new EnterNode(parent, data[i]);
26748 // Add any remaining nodes that were not bound to data to exit.
26749 for (i = 0; i < groupLength; ++i) {
26750 if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
26756 var selection_data = function(value, key) {
26758 data = new Array(this.size()), j = -1;
26759 this.each(function(d) { data[++j] = d; });
26763 var bind = key ? bindKey : bindIndex,
26764 parents = this._parents,
26765 groups = this._groups;
26767 if (typeof value !== "function") value = constant$5(value);
26769 for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
26770 var parent = parents[j],
26772 groupLength = group.length,
26773 data = value.call(parent, parent && parent.__data__, j, parents),
26774 dataLength = data.length,
26775 enterGroup = enter[j] = new Array(dataLength),
26776 updateGroup = update[j] = new Array(dataLength),
26777 exitGroup = exit[j] = new Array(groupLength);
26779 bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
26781 // Now connect the enter nodes to their following update node, such that
26782 // appendChild can insert the materialized enter node before this node,
26783 // rather than at the end of the parent node.
26784 for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
26785 if (previous = enterGroup[i0]) {
26786 if (i0 >= i1) i1 = i0 + 1;
26787 while (!(next = updateGroup[i1]) && ++i1 < dataLength);
26788 previous._next = next || null;
26793 update = new Selection(update, parents);
26794 update._enter = enter;
26795 update._exit = exit;
26799 var selection_exit = function() {
26800 return new Selection(this._exit || this._groups.map(sparse), this._parents);
26803 var selection_merge = function(selection) {
26805 for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
26806 for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
26807 if (node = group0[i] || group1[i]) {
26813 for (; j < m0; ++j) {
26814 merges[j] = groups0[j];
26817 return new Selection(merges, this._parents);
26820 var selection_order = function() {
26822 for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
26823 for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
26824 if (node = group[i]) {
26825 if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
26834 var selection_sort = function(compare) {
26835 if (!compare) compare = ascending$2;
26837 function compareNode(a, b) {
26838 return a && b ? compare(a.__data__, b.__data__) : !a - !b;
26841 for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
26842 for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
26843 if (node = group[i]) {
26844 sortgroup[i] = node;
26847 sortgroup.sort(compareNode);
26850 return new Selection(sortgroups, this._parents).order();
26853 function ascending$2(a, b) {
26854 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
26857 var selection_call = function() {
26858 var callback = arguments[0];
26859 arguments[0] = this;
26860 callback.apply(null, arguments);
26864 var selection_nodes = function() {
26865 var nodes = new Array(this.size()), i = -1;
26866 this.each(function() { nodes[++i] = this; });
26870 var selection_node = function() {
26872 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
26873 for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
26874 var node = group[i];
26875 if (node) return node;
26882 var selection_size = function() {
26884 this.each(function() { ++size; });
26888 var selection_empty = function() {
26889 return !this.node();
26892 var selection_each = function(callback) {
26894 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
26895 for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
26896 if (node = group[i]) callback.call(node, node.__data__, i, group);
26903 function attrRemove(name) {
26904 return function() {
26905 this.removeAttribute(name);
26909 function attrRemoveNS(fullname) {
26910 return function() {
26911 this.removeAttributeNS(fullname.space, fullname.local);
26915 function attrConstant(name, value) {
26916 return function() {
26917 this.setAttribute(name, value);
26921 function attrConstantNS(fullname, value) {
26922 return function() {
26923 this.setAttributeNS(fullname.space, fullname.local, value);
26927 function attrFunction(name, value) {
26928 return function() {
26929 var v = value.apply(this, arguments);
26930 if (v == null) this.removeAttribute(name);
26931 else this.setAttribute(name, v);
26935 function attrFunctionNS(fullname, value) {
26936 return function() {
26937 var v = value.apply(this, arguments);
26938 if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
26939 else this.setAttributeNS(fullname.space, fullname.local, v);
26943 var selection_attr = function(name, value) {
26944 var fullname = namespace(name);
26946 if (arguments.length < 2) {
26947 var node = this.node();
26948 return fullname.local
26949 ? node.getAttributeNS(fullname.space, fullname.local)
26950 : node.getAttribute(fullname);
26953 return this.each((value == null
26954 ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
26955 ? (fullname.local ? attrFunctionNS : attrFunction)
26956 : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
26959 var window$1 = function(node) {
26960 return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
26961 || (node.document && node) // node is a Window
26962 || node.defaultView; // node is a Document
26965 function styleRemove(name) {
26966 return function() {
26967 this.style.removeProperty(name);
26971 function styleConstant(name, value, priority) {
26972 return function() {
26973 this.style.setProperty(name, value, priority);
26977 function styleFunction(name, value, priority) {
26978 return function() {
26979 var v = value.apply(this, arguments);
26980 if (v == null) this.style.removeProperty(name);
26981 else this.style.setProperty(name, v, priority);
26985 var selection_style = function(name, value, priority) {
26987 return arguments.length > 1
26988 ? this.each((value == null
26989 ? styleRemove : typeof value === "function"
26991 : styleConstant)(name, value, priority == null ? "" : priority))
26992 : window$1(node = this.node())
26993 .getComputedStyle(node, null)
26994 .getPropertyValue(name);
26997 function propertyRemove(name) {
26998 return function() {
27003 function propertyConstant(name, value) {
27004 return function() {
27005 this[name] = value;
27009 function propertyFunction(name, value) {
27010 return function() {
27011 var v = value.apply(this, arguments);
27012 if (v == null) delete this[name];
27013 else this[name] = v;
27017 var selection_property = function(name, value) {
27018 return arguments.length > 1
27019 ? this.each((value == null
27020 ? propertyRemove : typeof value === "function"
27022 : propertyConstant)(name, value))
27023 : this.node()[name];
27026 function classArray(string) {
27027 return string.trim().split(/^|\s+/);
27030 function classList(node) {
27031 return node.classList || new ClassList(node);
27034 function ClassList(node) {
27036 this._names = classArray(node.getAttribute("class") || "");
27039 ClassList.prototype = {
27040 add: function(name) {
27041 var i = this._names.indexOf(name);
27043 this._names.push(name);
27044 this._node.setAttribute("class", this._names.join(" "));
27047 remove: function(name) {
27048 var i = this._names.indexOf(name);
27050 this._names.splice(i, 1);
27051 this._node.setAttribute("class", this._names.join(" "));
27054 contains: function(name) {
27055 return this._names.indexOf(name) >= 0;
27059 function classedAdd(node, names) {
27060 var list = classList(node), i = -1, n = names.length;
27061 while (++i < n) list.add(names[i]);
27064 function classedRemove(node, names) {
27065 var list = classList(node), i = -1, n = names.length;
27066 while (++i < n) list.remove(names[i]);
27069 function classedTrue(names) {
27070 return function() {
27071 classedAdd(this, names);
27075 function classedFalse(names) {
27076 return function() {
27077 classedRemove(this, names);
27081 function classedFunction(names, value) {
27082 return function() {
27083 (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
27087 var selection_classed = function(name, value) {
27088 var names = classArray(name + "");
27090 if (arguments.length < 2) {
27091 var list = classList(this.node()), i = -1, n = names.length;
27092 while (++i < n) if (!list.contains(names[i])) return false;
27096 return this.each((typeof value === "function"
27097 ? classedFunction : value
27099 : classedFalse)(names, value));
27102 function textRemove() {
27103 this.textContent = "";
27106 function textConstant(value) {
27107 return function() {
27108 this.textContent = value;
27112 function textFunction(value) {
27113 return function() {
27114 var v = value.apply(this, arguments);
27115 this.textContent = v == null ? "" : v;
27119 var selection_text = function(value) {
27120 return arguments.length
27121 ? this.each(value == null
27122 ? textRemove : (typeof value === "function"
27124 : textConstant)(value))
27125 : this.node().textContent;
27128 function htmlRemove() {
27129 this.innerHTML = "";
27132 function htmlConstant(value) {
27133 return function() {
27134 this.innerHTML = value;
27138 function htmlFunction(value) {
27139 return function() {
27140 var v = value.apply(this, arguments);
27141 this.innerHTML = v == null ? "" : v;
27145 var selection_html = function(value) {
27146 return arguments.length
27147 ? this.each(value == null
27148 ? htmlRemove : (typeof value === "function"
27150 : htmlConstant)(value))
27151 : this.node().innerHTML;
27154 function raise$1() {
27155 if (this.nextSibling) this.parentNode.appendChild(this);
27158 var selection_raise = function() {
27159 return this.each(raise$1);
27163 if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
27166 var selection_lower = function() {
27167 return this.each(lower);
27170 var selection_append = function(name) {
27171 var create = typeof name === "function" ? name : creator(name);
27172 return this.select(function() {
27173 return this.appendChild(create.apply(this, arguments));
27177 function constantNull() {
27181 var selection_insert = function(name, before) {
27182 var create = typeof name === "function" ? name : creator(name),
27183 select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
27184 return this.select(function() {
27185 return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
27189 function remove() {
27190 var parent = this.parentNode;
27191 if (parent) parent.removeChild(this);
27194 var selection_remove = function() {
27195 return this.each(remove);
27198 var selection_datum = function(value) {
27199 return arguments.length
27200 ? this.property("__data__", value)
27201 : this.node().__data__;
27204 function dispatchEvent(node, type, params) {
27205 var window = window$1(node),
27206 event = window.CustomEvent;
27209 event = new event(type, params);
27211 event = window.document.createEvent("Event");
27212 if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
27213 else event.initEvent(type, false, false);
27216 node.dispatchEvent(event);
27219 function dispatchConstant(type, params) {
27220 return function() {
27221 return dispatchEvent(this, type, params);
27225 function dispatchFunction(type, params) {
27226 return function() {
27227 return dispatchEvent(this, type, params.apply(this, arguments));
27231 var selection_dispatch = function(type, params) {
27232 return this.each((typeof params === "function"
27234 : dispatchConstant)(type, params));
27239 function Selection(groups, parents) {
27240 this._groups = groups;
27241 this._parents = parents;
27244 function selection() {
27245 return new Selection([[document.documentElement]], root);
27248 Selection.prototype = selection.prototype = {
27249 constructor: Selection,
27250 select: selection_select,
27251 selectAll: selection_selectAll,
27252 filter: selection_filter,
27253 data: selection_data,
27254 enter: selection_enter,
27255 exit: selection_exit,
27256 merge: selection_merge,
27257 order: selection_order,
27258 sort: selection_sort,
27259 call: selection_call,
27260 nodes: selection_nodes,
27261 node: selection_node,
27262 size: selection_size,
27263 empty: selection_empty,
27264 each: selection_each,
27265 attr: selection_attr,
27266 style: selection_style,
27267 property: selection_property,
27268 classed: selection_classed,
27269 text: selection_text,
27270 html: selection_html,
27271 raise: selection_raise,
27272 lower: selection_lower,
27273 append: selection_append,
27274 insert: selection_insert,
27275 remove: selection_remove,
27276 datum: selection_datum,
27278 dispatch: selection_dispatch
27281 var select = function(selector) {
27282 return typeof selector === "string"
27283 ? new Selection([[document.querySelector(selector)]], [document.documentElement])
27284 : new Selection([[selector]], root);
27287 var selectAll = function(selector) {
27288 return typeof selector === "string"
27289 ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
27290 : new Selection([selector == null ? [] : selector], root);
27293 var touch = function(node, touches, identifier) {
27294 if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
27296 for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
27297 if ((touch = touches[i]).identifier === identifier) {
27298 return point$5(node, touch);
27305 var touches = function(node, touches) {
27306 if (touches == null) touches = sourceEvent().touches;
27308 for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
27309 points[i] = point$5(node, touches[i]);
27315 var emptyOn = dispatch("start", "end", "interrupt");
27316 var emptyTween = [];
27326 var schedule = function(node, name, id, index, group, timing) {
27327 var schedules = node.__transition;
27328 if (!schedules) node.__transition = {};
27329 else if (id in schedules) return;
27332 index: index, // For context during callback.
27333 group: group, // For context during callback.
27337 delay: timing.delay,
27338 duration: timing.duration,
27345 function init(node, id) {
27346 var schedule = node.__transition;
27347 if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late");
27351 function set$3(node, id) {
27352 var schedule = node.__transition;
27353 if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late");
27357 function get$1(node, id) {
27358 var schedule = node.__transition;
27359 if (!schedule || !(schedule = schedule[id])) throw new Error("too late");
27363 function create(node, id, self) {
27364 var schedules = node.__transition,
27367 // Initialize the self timer when the transition is created.
27368 // Note the actual delay is not known until the first callback!
27369 schedules[id] = self;
27370 self.timer = timer(schedule, 0, self.time);
27372 function schedule(elapsed) {
27373 self.state = SCHEDULED;
27374 self.timer.restart(start, self.delay, self.time);
27376 // If the elapsed delay is less than our first sleep, start immediately.
27377 if (self.delay <= elapsed) start(elapsed - self.delay);
27380 function start(elapsed) {
27383 // If the state is not SCHEDULED, then we previously errored on start.
27384 if (self.state !== SCHEDULED) return stop();
27386 for (i in schedules) {
27388 if (o.name !== self.name) continue;
27390 // While this element already has a starting transition during this frame,
27391 // defer starting an interrupting transition until that transition has a
27392 // chance to tick (and possibly end); see d3/d3-transition#54!
27393 if (o.state === STARTED) return timeout$1(start);
27395 // Interrupt the active transition, if any.
27396 // Dispatch the interrupt event.
27397 if (o.state === RUNNING) {
27400 o.on.call("interrupt", node, node.__data__, o.index, o.group);
27401 delete schedules[i];
27404 // Cancel any pre-empted transitions. No interrupt event is dispatched
27405 // because the cancelled transitions never started. Note that this also
27406 // removes this transition from the pending list!
27407 else if (+i < id) {
27410 delete schedules[i];
27414 // Defer the first tick to end of the current frame; see d3/d3#1576.
27415 // Note the transition may be canceled after start and before the first tick!
27416 // Note this must be scheduled before the start event; see d3/d3-transition#16!
27417 // Assuming this is successful, subsequent callbacks go straight to tick.
27418 timeout$1(function() {
27419 if (self.state === STARTED) {
27420 self.state = RUNNING;
27421 self.timer.restart(tick, self.delay, self.time);
27426 // Dispatch the start event.
27427 // Note this must be done before the tween are initialized.
27428 self.state = STARTING;
27429 self.on.call("start", node, node.__data__, self.index, self.group);
27430 if (self.state !== STARTING) return; // interrupted
27431 self.state = STARTED;
27433 // Initialize the tween, deleting null tween.
27434 tween = new Array(n = self.tween.length);
27435 for (i = 0, j = -1; i < n; ++i) {
27436 if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
27440 tween.length = j + 1;
27443 function tick(elapsed) {
27444 var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
27449 tween[i].call(null, t);
27452 // Dispatch the end event.
27453 if (self.state === ENDING) {
27454 self.on.call("end", node, node.__data__, self.index, self.group);
27460 self.state = ENDED;
27462 delete schedules[id];
27463 for (var i in schedules) return; // eslint-disable-line no-unused-vars
27464 delete node.__transition;
27468 var interrupt = function(node, name) {
27469 var schedules = node.__transition,
27475 if (!schedules) return;
27477 name = name == null ? null : name + "";
27479 for (i in schedules) {
27480 if ((schedule = schedules[i]).name !== name) { empty = false; continue; }
27481 active = schedule.state > STARTING && schedule.state < ENDING;
27482 schedule.state = ENDED;
27483 schedule.timer.stop();
27484 if (active) schedule.on.call("interrupt", node, node.__data__, schedule.index, schedule.group);
27485 delete schedules[i];
27488 if (empty) delete node.__transition;
27491 var selection_interrupt = function(name) {
27492 return this.each(function() {
27493 interrupt(this, name);
27497 function tweenRemove(id, name) {
27498 var tween0, tween1;
27499 return function() {
27500 var schedule = set$3(this, id),
27501 tween = schedule.tween;
27503 // If this node shared tween with the previous node,
27504 // just assign the updated shared tween and we’re done!
27505 // Otherwise, copy-on-write.
27506 if (tween !== tween0) {
27507 tween1 = tween0 = tween;
27508 for (var i = 0, n = tween1.length; i < n; ++i) {
27509 if (tween1[i].name === name) {
27510 tween1 = tween1.slice();
27511 tween1.splice(i, 1);
27517 schedule.tween = tween1;
27521 function tweenFunction(id, name, value) {
27522 var tween0, tween1;
27523 if (typeof value !== "function") throw new Error;
27524 return function() {
27525 var schedule = set$3(this, id),
27526 tween = schedule.tween;
27528 // If this node shared tween with the previous node,
27529 // just assign the updated shared tween and we’re done!
27530 // Otherwise, copy-on-write.
27531 if (tween !== tween0) {
27532 tween1 = (tween0 = tween).slice();
27533 for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
27534 if (tween1[i].name === name) {
27539 if (i === n) tween1.push(t);
27542 schedule.tween = tween1;
27546 var transition_tween = function(name, value) {
27551 if (arguments.length < 2) {
27552 var tween = get$1(this.node(), id).tween;
27553 for (var i = 0, n = tween.length, t; i < n; ++i) {
27554 if ((t = tween[i]).name === name) {
27561 return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
27564 function tweenValue(transition, name, value) {
27565 var id = transition._id;
27567 transition.each(function() {
27568 var schedule = set$3(this, id);
27569 (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);
27572 return function(node) {
27573 return get$1(node, id).value[name];
27577 var interpolate$1 = function(a, b) {
27579 return (typeof b === "number" ? interpolateNumber
27580 : b instanceof color ? interpolateRgb
27581 : (c = color(b)) ? (b = c, interpolateRgb)
27582 : interpolateString)(a, b);
27585 function attrRemove$1(name) {
27586 return function() {
27587 this.removeAttribute(name);
27591 function attrRemoveNS$1(fullname) {
27592 return function() {
27593 this.removeAttributeNS(fullname.space, fullname.local);
27597 function attrConstant$1(name, interpolate$$1, value1) {
27600 return function() {
27601 var value0 = this.getAttribute(name);
27602 return value0 === value1 ? null
27603 : value0 === value00 ? interpolate0
27604 : interpolate0 = interpolate$$1(value00 = value0, value1);
27608 function attrConstantNS$1(fullname, interpolate$$1, value1) {
27611 return function() {
27612 var value0 = this.getAttributeNS(fullname.space, fullname.local);
27613 return value0 === value1 ? null
27614 : value0 === value00 ? interpolate0
27615 : interpolate0 = interpolate$$1(value00 = value0, value1);
27619 function attrFunction$1(name, interpolate$$1, value) {
27623 return function() {
27624 var value0, value1 = value(this);
27625 if (value1 == null) return void this.removeAttribute(name);
27626 value0 = this.getAttribute(name);
27627 return value0 === value1 ? null
27628 : value0 === value00 && value1 === value10 ? interpolate0
27629 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27633 function attrFunctionNS$1(fullname, interpolate$$1, value) {
27637 return function() {
27638 var value0, value1 = value(this);
27639 if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
27640 value0 = this.getAttributeNS(fullname.space, fullname.local);
27641 return value0 === value1 ? null
27642 : value0 === value00 && value1 === value10 ? interpolate0
27643 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27647 var transition_attr = function(name, value) {
27648 var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate$1;
27649 return this.attrTween(name, typeof value === "function"
27650 ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
27651 : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
27652 : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value));
27655 function attrTweenNS(fullname, value) {
27657 var node = this, i = value.apply(node, arguments);
27658 return i && function(t) {
27659 node.setAttributeNS(fullname.space, fullname.local, i(t));
27662 tween._value = value;
27666 function attrTween(name, value) {
27668 var node = this, i = value.apply(node, arguments);
27669 return i && function(t) {
27670 node.setAttribute(name, i(t));
27673 tween._value = value;
27677 var transition_attrTween = function(name, value) {
27678 var key = "attr." + name;
27679 if (arguments.length < 2) return (key = this.tween(key)) && key._value;
27680 if (value == null) return this.tween(key, null);
27681 if (typeof value !== "function") throw new Error;
27682 var fullname = namespace(name);
27683 return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
27686 function delayFunction(id, value) {
27687 return function() {
27688 init(this, id).delay = +value.apply(this, arguments);
27692 function delayConstant(id, value) {
27693 return value = +value, function() {
27694 init(this, id).delay = value;
27698 var transition_delay = function(value) {
27701 return arguments.length
27702 ? this.each((typeof value === "function"
27704 : delayConstant)(id, value))
27705 : get$1(this.node(), id).delay;
27708 function durationFunction(id, value) {
27709 return function() {
27710 set$3(this, id).duration = +value.apply(this, arguments);
27714 function durationConstant(id, value) {
27715 return value = +value, function() {
27716 set$3(this, id).duration = value;
27720 var transition_duration = function(value) {
27723 return arguments.length
27724 ? this.each((typeof value === "function"
27726 : durationConstant)(id, value))
27727 : get$1(this.node(), id).duration;
27730 function easeConstant(id, value) {
27731 if (typeof value !== "function") throw new Error;
27732 return function() {
27733 set$3(this, id).ease = value;
27737 var transition_ease = function(value) {
27740 return arguments.length
27741 ? this.each(easeConstant(id, value))
27742 : get$1(this.node(), id).ease;
27745 var transition_filter = function(match) {
27746 if (typeof match !== "function") match = matcher$1(match);
27748 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
27749 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
27750 if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
27751 subgroup.push(node);
27756 return new Transition(subgroups, this._parents, this._name, this._id);
27759 var transition_merge = function(transition) {
27760 if (transition._id !== this._id) throw new Error;
27762 for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
27763 for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
27764 if (node = group0[i] || group1[i]) {
27770 for (; j < m0; ++j) {
27771 merges[j] = groups0[j];
27774 return new Transition(merges, this._parents, this._name, this._id);
27777 function start$1(name) {
27778 return (name + "").trim().split(/^|\s+/).every(function(t) {
27779 var i = t.indexOf(".");
27780 if (i >= 0) t = t.slice(0, i);
27781 return !t || t === "start";
27785 function onFunction(id, name, listener) {
27786 var on0, on1, sit = start$1(name) ? init : set$3;
27787 return function() {
27788 var schedule = sit(this, id),
27791 // If this node shared a dispatch with the previous node,
27792 // just assign the updated shared dispatch and we’re done!
27793 // Otherwise, copy-on-write.
27794 if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
27800 var transition_on = function(name, listener) {
27803 return arguments.length < 2
27804 ? get$1(this.node(), id).on.on(name)
27805 : this.each(onFunction(id, name, listener));
27808 function removeFunction(id) {
27809 return function() {
27810 var parent = this.parentNode;
27811 for (var i in this.__transition) if (+i !== id) return;
27812 if (parent) parent.removeChild(this);
27816 var transition_remove = function() {
27817 return this.on("end.remove", removeFunction(this._id));
27820 var transition_select = function(select$$1) {
27821 var name = this._name,
27824 if (typeof select$$1 !== "function") select$$1 = selector(select$$1);
27826 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
27827 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
27828 if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) {
27829 if ("__data__" in node) subnode.__data__ = node.__data__;
27830 subgroup[i] = subnode;
27831 schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
27836 return new Transition(subgroups, this._parents, name, id);
27839 var transition_selectAll = function(select$$1) {
27840 var name = this._name,
27843 if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1);
27845 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
27846 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
27847 if (node = group[i]) {
27848 for (var children = select$$1.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {
27849 if (child = children[k]) {
27850 schedule(child, name, id, k, children, inherit);
27853 subgroups.push(children);
27854 parents.push(node);
27859 return new Transition(subgroups, parents, name, id);
27862 var Selection$1 = selection.prototype.constructor;
27864 var transition_selection = function() {
27865 return new Selection$1(this._groups, this._parents);
27868 function styleRemove$1(name, interpolate$$1) {
27872 return function() {
27873 var style = window$1(this).getComputedStyle(this, null),
27874 value0 = style.getPropertyValue(name),
27875 value1 = (this.style.removeProperty(name), style.getPropertyValue(name));
27876 return value0 === value1 ? null
27877 : value0 === value00 && value1 === value10 ? interpolate0
27878 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27882 function styleRemoveEnd(name) {
27883 return function() {
27884 this.style.removeProperty(name);
27888 function styleConstant$1(name, interpolate$$1, value1) {
27891 return function() {
27892 var value0 = window$1(this).getComputedStyle(this, null).getPropertyValue(name);
27893 return value0 === value1 ? null
27894 : value0 === value00 ? interpolate0
27895 : interpolate0 = interpolate$$1(value00 = value0, value1);
27899 function styleFunction$1(name, interpolate$$1, value) {
27903 return function() {
27904 var style = window$1(this).getComputedStyle(this, null),
27905 value0 = style.getPropertyValue(name),
27906 value1 = value(this);
27907 if (value1 == null) value1 = (this.style.removeProperty(name), style.getPropertyValue(name));
27908 return value0 === value1 ? null
27909 : value0 === value00 && value1 === value10 ? interpolate0
27910 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
27914 var transition_style = function(name, value, priority) {
27915 var i = (name += "") === "transform" ? interpolateTransformCss : interpolate$1;
27916 return value == null ? this
27917 .styleTween(name, styleRemove$1(name, i))
27918 .on("end.style." + name, styleRemoveEnd(name))
27919 : this.styleTween(name, typeof value === "function"
27920 ? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
27921 : styleConstant$1(name, i, value), priority);
27924 function styleTween(name, value, priority) {
27926 var node = this, i = value.apply(node, arguments);
27927 return i && function(t) {
27928 node.style.setProperty(name, i(t), priority);
27931 tween._value = value;
27935 var transition_styleTween = function(name, value, priority) {
27936 var key = "style." + (name += "");
27937 if (arguments.length < 2) return (key = this.tween(key)) && key._value;
27938 if (value == null) return this.tween(key, null);
27939 if (typeof value !== "function") throw new Error;
27940 return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
27943 function textConstant$1(value) {
27944 return function() {
27945 this.textContent = value;
27949 function textFunction$1(value) {
27950 return function() {
27951 var value1 = value(this);
27952 this.textContent = value1 == null ? "" : value1;
27956 var transition_text = function(value) {
27957 return this.tween("text", typeof value === "function"
27958 ? textFunction$1(tweenValue(this, "text", value))
27959 : textConstant$1(value == null ? "" : value + ""));
27962 var transition_transition = function() {
27963 var name = this._name,
27967 for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
27968 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
27969 if (node = group[i]) {
27970 var inherit = get$1(node, id0);
27971 schedule(node, name, id1, i, group, {
27972 time: inherit.time + inherit.delay + inherit.duration,
27974 duration: inherit.duration,
27981 return new Transition(groups, this._parents, name, id1);
27986 function Transition(groups, parents, name, id) {
27987 this._groups = groups;
27988 this._parents = parents;
27993 function transition(name) {
27994 return selection().transition(name);
28001 var selection_prototype = selection.prototype;
28003 Transition.prototype = transition.prototype = {
28004 constructor: Transition,
28005 select: transition_select,
28006 selectAll: transition_selectAll,
28007 filter: transition_filter,
28008 merge: transition_merge,
28009 selection: transition_selection,
28010 transition: transition_transition,
28011 call: selection_prototype.call,
28012 nodes: selection_prototype.nodes,
28013 node: selection_prototype.node,
28014 size: selection_prototype.size,
28015 empty: selection_prototype.empty,
28016 each: selection_prototype.each,
28018 attr: transition_attr,
28019 attrTween: transition_attrTween,
28020 style: transition_style,
28021 styleTween: transition_styleTween,
28022 text: transition_text,
28023 remove: transition_remove,
28024 tween: transition_tween,
28025 delay: transition_delay,
28026 duration: transition_duration,
28027 ease: transition_ease
28030 var defaultTiming = {
28031 time: null, // Set on use.
28037 function inherit(node, id) {
28039 while (!(timing = node.__transition) || !(timing = timing[id])) {
28040 if (!(node = node.parentNode)) {
28041 return defaultTiming.time = now(), defaultTiming;
28047 var selection_transition = function(name) {
28051 if (name instanceof Transition) {
28052 id = name._id, name = name._name;
28054 id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
28057 for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
28058 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
28059 if (node = group[i]) {
28060 schedule(node, name, id, i, group, timing || inherit(node, id));
28065 return new Transition(groups, this._parents, name, id);
28068 selection.prototype.interrupt = selection_interrupt;
28069 selection.prototype.transition = selection_transition;
28071 var root$1 = [null];
28073 var active = function(node, name) {
28074 var schedules = node.__transition,
28079 name = name == null ? null : name + "";
28080 for (i in schedules) {
28081 if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {
28082 return new Transition([[node]], root$1, name, +i);
28090 var slice$4 = Array.prototype.slice;
28092 var identity$5 = function(x) {
28100 var epsilon$2 = 1e-6;
28102 function translateX(scale0, scale1, d) {
28104 return "translate(" + (isFinite(x) ? x : scale1(d)) + ",0)";
28107 function translateY(scale0, scale1, d) {
28109 return "translate(0," + (isFinite(y) ? y : scale1(d)) + ")";
28112 function center(scale) {
28113 var offset = scale.bandwidth() / 2;
28114 if (scale.round()) offset = Math.round(offset);
28115 return function(d) {
28116 return scale(d) + offset;
28120 function entering() {
28121 return !this.__axis;
28124 function axis(orient, scale) {
28125 var tickArguments = [],
28132 function axis(context) {
28133 var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
28134 format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$5) : tickFormat,
28135 spacing = Math.max(tickSizeInner, 0) + tickPadding,
28136 transform = orient === top || orient === bottom ? translateX : translateY,
28137 range = scale.range(),
28138 range0 = range[0] + 0.5,
28139 range1 = range[range.length - 1] + 0.5,
28140 position = (scale.bandwidth ? center : identity$5)(scale.copy()),
28141 selection = context.selection ? context.selection() : context,
28142 path = selection.selectAll(".domain").data([null]),
28143 tick = selection.selectAll(".tick").data(values, scale).order(),
28144 tickExit = tick.exit(),
28145 tickEnter = tick.enter().append("g").attr("class", "tick"),
28146 line = tick.select("line"),
28147 text = tick.select("text"),
28148 k = orient === top || orient === left ? -1 : 1,
28149 x, y = orient === left || orient === right ? (x = "x", "y") : (x = "y", "x");
28151 path = path.merge(path.enter().insert("path", ".tick")
28152 .attr("class", "domain")
28153 .attr("stroke", "#000"));
28155 tick = tick.merge(tickEnter);
28157 line = line.merge(tickEnter.append("line")
28158 .attr("stroke", "#000")
28159 .attr(x + "2", k * tickSizeInner)
28160 .attr(y + "1", 0.5)
28161 .attr(y + "2", 0.5));
28163 text = text.merge(tickEnter.append("text")
28164 .attr("fill", "#000")
28165 .attr(x, k * spacing)
28167 .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
28169 if (context !== selection) {
28170 path = path.transition(context);
28171 tick = tick.transition(context);
28172 line = line.transition(context);
28173 text = text.transition(context);
28175 tickExit = tickExit.transition(context)
28176 .attr("opacity", epsilon$2)
28177 .attr("transform", function(d) { return transform(position, this.parentNode.__axis || position, d); });
28180 .attr("opacity", epsilon$2)
28181 .attr("transform", function(d) { return transform(this.parentNode.__axis || position, position, d); });
28187 .attr("d", orient === left || orient == right
28188 ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
28189 : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
28192 .attr("opacity", 1)
28193 .attr("transform", function(d) { return transform(position, position, d); });
28196 .attr(x + "2", k * tickSizeInner);
28199 .attr(x, k * spacing)
28202 selection.filter(entering)
28203 .attr("fill", "none")
28204 .attr("font-size", 10)
28205 .attr("font-family", "sans-serif")
28206 .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
28209 .each(function() { this.__axis = position; });
28212 axis.scale = function(_) {
28213 return arguments.length ? (scale = _, axis) : scale;
28216 axis.ticks = function() {
28217 return tickArguments = slice$4.call(arguments), axis;
28220 axis.tickArguments = function(_) {
28221 return arguments.length ? (tickArguments = _ == null ? [] : slice$4.call(_), axis) : tickArguments.slice();
28224 axis.tickValues = function(_) {
28225 return arguments.length ? (tickValues = _ == null ? null : slice$4.call(_), axis) : tickValues && tickValues.slice();
28228 axis.tickFormat = function(_) {
28229 return arguments.length ? (tickFormat = _, axis) : tickFormat;
28232 axis.tickSize = function(_) {
28233 return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
28236 axis.tickSizeInner = function(_) {
28237 return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
28240 axis.tickSizeOuter = function(_) {
28241 return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
28244 axis.tickPadding = function(_) {
28245 return arguments.length ? (tickPadding = +_, axis) : tickPadding;
28251 function axisTop(scale) {
28252 return axis(top, scale);
28255 function axisRight(scale) {
28256 return axis(right, scale);
28259 function axisBottom(scale) {
28260 return axis(bottom, scale);
28263 function axisLeft(scale) {
28264 return axis(left, scale);
28267 function defaultSeparation(a, b) {
28268 return a.parent === b.parent ? 1 : 2;
28271 function meanX(children) {
28272 return children.reduce(meanXReduce, 0) / children.length;
28275 function meanXReduce(x, c) {
28279 function maxY(children) {
28280 return 1 + children.reduce(maxYReduce, 0);
28283 function maxYReduce(y, c) {
28284 return Math.max(y, c.y);
28287 function leafLeft(node) {
28289 while (children = node.children) node = children[0];
28293 function leafRight(node) {
28295 while (children = node.children) node = children[children.length - 1];
28299 var cluster = function() {
28300 var separation = defaultSeparation,
28305 function cluster(root) {
28309 // First walk, computing the initial x & y values.
28310 root.eachAfter(function(node) {
28311 var children = node.children;
28313 node.x = meanX(children);
28314 node.y = maxY(children);
28316 node.x = previousNode ? x += separation(node, previousNode) : 0;
28318 previousNode = node;
28322 var left = leafLeft(root),
28323 right = leafRight(root),
28324 x0 = left.x - separation(left, right) / 2,
28325 x1 = right.x + separation(right, left) / 2;
28327 // Second walk, normalizing x & y to the desired size.
28328 return root.eachAfter(nodeSize ? function(node) {
28329 node.x = (node.x - root.x) * dx;
28330 node.y = (root.y - node.y) * dy;
28331 } : function(node) {
28332 node.x = (node.x - x0) / (x1 - x0) * dx;
28333 node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
28337 cluster.separation = function(x) {
28338 return arguments.length ? (separation = x, cluster) : separation;
28341 cluster.size = function(x) {
28342 return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
28345 cluster.nodeSize = function(x) {
28346 return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
28352 var node_each = function(callback) {
28353 var node = this, current, next = [node], children, i, n;
28355 current = next.reverse(), next = [];
28356 while (node = current.pop()) {
28357 callback(node), children = node.children;
28358 if (children) for (i = 0, n = children.length; i < n; ++i) {
28359 next.push(children[i]);
28362 } while (next.length);
28366 var node_eachBefore = function(callback) {
28367 var node = this, nodes = [node], children, i;
28368 while (node = nodes.pop()) {
28369 callback(node), children = node.children;
28370 if (children) for (i = children.length - 1; i >= 0; --i) {
28371 nodes.push(children[i]);
28377 var node_eachAfter = function(callback) {
28378 var node = this, nodes = [node], next = [], children, i, n;
28379 while (node = nodes.pop()) {
28380 next.push(node), children = node.children;
28381 if (children) for (i = 0, n = children.length; i < n; ++i) {
28382 nodes.push(children[i]);
28385 while (node = next.pop()) {
28391 var node_sum = function(value) {
28392 return this.eachAfter(function(node) {
28393 var sum = +value(node.data) || 0,
28394 children = node.children,
28395 i = children && children.length;
28396 while (--i >= 0) sum += children[i].value;
28401 var node_sort = function(compare) {
28402 return this.eachBefore(function(node) {
28403 if (node.children) {
28404 node.children.sort(compare);
28409 var node_path = function(end) {
28411 ancestor = leastCommonAncestor(start, end),
28413 while (start !== ancestor) {
28414 start = start.parent;
28417 var k = nodes.length;
28418 while (end !== ancestor) {
28419 nodes.splice(k, 0, end);
28425 function leastCommonAncestor(a, b) {
28426 if (a === b) return a;
28427 var aNodes = a.ancestors(),
28428 bNodes = b.ancestors(),
28440 var node_ancestors = function() {
28441 var node = this, nodes = [node];
28442 while (node = node.parent) {
28448 var node_descendants = function() {
28450 this.each(function(node) {
28456 var node_leaves = function() {
28458 this.eachBefore(function(node) {
28459 if (!node.children) {
28466 var node_links = function() {
28467 var root = this, links = [];
28468 root.each(function(node) {
28469 if (node !== root) { // Don’t include the root’s parent, if any.
28470 links.push({source: node.parent, target: node});
28476 function hierarchy(data, children) {
28477 var root = new Node(data),
28478 valued = +data.value && (root.value = data.value),
28486 if (children == null) children = defaultChildren;
28488 while (node = nodes.pop()) {
28489 if (valued) node.value = +node.data.value;
28490 if ((childs = children(node.data)) && (n = childs.length)) {
28491 node.children = new Array(n);
28492 for (i = n - 1; i >= 0; --i) {
28493 nodes.push(child = node.children[i] = new Node(childs[i]));
28494 child.parent = node;
28495 child.depth = node.depth + 1;
28500 return root.eachBefore(computeHeight);
28503 function node_copy() {
28504 return hierarchy(this).eachBefore(copyData);
28507 function defaultChildren(d) {
28511 function copyData(node) {
28512 node.data = node.data.data;
28515 function computeHeight(node) {
28517 do node.height = height;
28518 while ((node = node.parent) && (node.height < ++height));
28521 function Node(data) {
28525 this.parent = null;
28528 Node.prototype = hierarchy.prototype = {
28531 eachAfter: node_eachAfter,
28532 eachBefore: node_eachBefore,
28536 ancestors: node_ancestors,
28537 descendants: node_descendants,
28538 leaves: node_leaves,
28543 function Node$2(value) {
28548 var shuffle$1 = function(array) {
28550 n = (array = array.slice()).length,
28555 var next = new Node$2(array[n - 1]);
28556 if (node) node = node.next = next;
28557 else node = head = next;
28558 array[i] = array[--n];
28567 var enclose = function(circles) {
28568 return encloseN(shuffle$1(circles), []);
28571 function encloses(a, b) {
28572 var dx = b.x - a.x,
28575 return dr * dr + 1e-6 > dx * dx + dy * dy;
28578 // Returns the smallest circle that contains circles L and intersects circles B.
28579 function encloseN(L, B) {
28586 switch (B.length) {
28587 case 1: circle = enclose1(B[0]); break;
28588 case 2: circle = enclose2(B[0], B[1]); break;
28589 case 3: circle = enclose3(B[0], B[1], B[2]); break;
28593 p1 = l1._, l2 = l1.next;
28594 if (!circle || !encloses(circle, p1)) {
28596 // Temporarily truncate L before l1.
28597 if (l0) L.tail = l0, l0.next = null;
28598 else L.head = L.tail = null;
28601 circle = encloseN(L, B); // Note: reorders L!
28604 // Move l1 to the front of L and reconnect the truncated list L.
28605 if (L.head) l1.next = L.head, L.head = l1;
28606 else l1.next = null, L.head = L.tail = l1;
28607 l0 = L.tail, l0.next = l2;
28619 function enclose1(a) {
28627 function enclose2(a, b) {
28628 var x1 = a.x, y1 = a.y, r1 = a.r,
28629 x2 = b.x, y2 = b.y, r2 = b.r,
28630 x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
28631 l = Math.sqrt(x21 * x21 + y21 * y21);
28633 x: (x1 + x2 + x21 / l * r21) / 2,
28634 y: (y1 + y2 + y21 / l * r21) / 2,
28635 r: (l + r1 + r2) / 2
28639 function enclose3(a, b, c) {
28640 var x1 = a.x, y1 = a.y, r1 = a.r,
28641 x2 = b.x, y2 = b.y, r2 = b.r,
28642 x3 = c.x, y3 = c.y, r3 = c.r,
28643 a2 = 2 * (x1 - x2),
28644 b2 = 2 * (y1 - y2),
28645 c2 = 2 * (r2 - r1),
28646 d2 = x1 * x1 + y1 * y1 - r1 * r1 - x2 * x2 - y2 * y2 + r2 * r2,
28647 a3 = 2 * (x1 - x3),
28648 b3 = 2 * (y1 - y3),
28649 c3 = 2 * (r3 - r1),
28650 d3 = x1 * x1 + y1 * y1 - r1 * r1 - x3 * x3 - y3 * y3 + r3 * r3,
28651 ab = a3 * b2 - a2 * b3,
28652 xa = (b2 * d3 - b3 * d2) / ab - x1,
28653 xb = (b3 * c2 - b2 * c3) / ab,
28654 ya = (a3 * d2 - a2 * d3) / ab - y1,
28655 yb = (a2 * c3 - a3 * c2) / ab,
28656 A = xb * xb + yb * yb - 1,
28657 B = 2 * (xa * xb + ya * yb + r1),
28658 C = xa * xa + ya * ya - r1 * r1,
28659 r = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A);
28661 x: xa + xb * r + x1,
28662 y: ya + yb * r + y1,
28667 function place(a, b, c) {
28674 dc = dx * dx + dy * dy;
28676 var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
28677 y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
28678 c.x = ax + x * dx + y * dy;
28679 c.y = ay + x * dy - y * dx;
28686 function intersects(a, b) {
28687 var dx = b.x - a.x,
28690 return dr * dr > dx * dx + dy * dy;
28693 function distance2(circle, x, y) {
28694 var dx = circle.x - x,
28696 return dx * dx + dy * dy;
28699 function Node$1(circle) {
28702 this.previous = null;
28705 function packEnclose(circles) {
28706 if (!(n = circles.length)) return 0;
28710 // Place the first circle.
28711 a = circles[0], a.x = 0, a.y = 0;
28712 if (!(n > 1)) return a.r;
28714 // Place the second circle.
28715 b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
28716 if (!(n > 2)) return a.r + b.r;
28718 // Place the third circle.
28719 place(b, a, c = circles[2]);
28721 // Initialize the weighted centroid.
28722 var aa = a.r * a.r,
28726 ox = aa * a.x + ba * b.x + ca * c.x,
28727 oy = aa * a.y + ba * b.y + ca * c.y,
28728 cx, cy, i, j, k, sj, sk;
28730 // Initialize the front-chain using the first three circles a, b and c.
28731 a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
28732 a.next = c.previous = b;
28733 b.next = a.previous = c;
28734 c.next = b.previous = a;
28736 // Attempt to place each remaining circle…
28737 pack: for (i = 3; i < n; ++i) {
28738 place(a._, b._, c = circles[i]), c = new Node$1(c);
28740 // If there are only three elements in the front-chain…
28741 if ((k = a.previous) === (j = b.next)) {
28742 // If the new circle intersects the third circle,
28743 // rotate the front chain to try the next position.
28744 if (intersects(j._, c._)) {
28750 // Find the closest intersecting circle on the front-chain, if any.
28752 sj = j._.r, sk = k._.r;
28755 if (intersects(j._, c._)) {
28756 b = j, a.next = b, b.previous = a, --i;
28759 j = j.next, sj += j._.r;
28761 if (intersects(k._, c._)) {
28762 a = k, a.next = b, b.previous = a, --i;
28765 k = k.previous, sk += k._.r;
28767 } while (j !== k.next);
28770 // Success! Insert the new circle c between a and b.
28771 c.previous = a, c.next = b, a.next = b.previous = b = c;
28773 // Update the weighted centroid.
28774 oa += ca = c._.r * c._.r;
28778 // Compute the new closest circle a to centroid.
28779 aa = distance2(a._, cx = ox / oa, cy = oy / oa);
28780 while ((c = c.next) !== b) {
28781 if ((ca = distance2(c._, cx, cy)) < aa) {
28788 // Compute the enclosing circle of the front chain.
28789 a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
28791 // Translate the circles to put the enclosing circle around the origin.
28792 for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
28797 var siblings = function(circles) {
28798 packEnclose(circles);
28802 function optional(f) {
28803 return f == null ? null : required(f);
28806 function required(f) {
28807 if (typeof f !== "function") throw new Error;
28811 function constantZero() {
28815 var constant$6 = function(x) {
28816 return function() {
28821 function defaultRadius(d) {
28822 return Math.sqrt(d.value);
28825 var index$2 = function() {
28829 padding = constantZero;
28831 function pack(root) {
28832 root.x = dx / 2, root.y = dy / 2;
28834 root.eachBefore(radiusLeaf(radius))
28835 .eachAfter(packChildren(padding, 0.5))
28836 .eachBefore(translateChild(1));
28838 root.eachBefore(radiusLeaf(defaultRadius))
28839 .eachAfter(packChildren(constantZero, 1))
28840 .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
28841 .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
28846 pack.radius = function(x) {
28847 return arguments.length ? (radius = optional(x), pack) : radius;
28850 pack.size = function(x) {
28851 return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
28854 pack.padding = function(x) {
28855 return arguments.length ? (padding = typeof x === "function" ? x : constant$6(+x), pack) : padding;
28861 function radiusLeaf(radius) {
28862 return function(node) {
28863 if (!node.children) {
28864 node.r = Math.max(0, +radius(node) || 0);
28869 function packChildren(padding, k) {
28870 return function(node) {
28871 if (children = node.children) {
28874 n = children.length,
28875 r = padding(node) * k || 0,
28878 if (r) for (i = 0; i < n; ++i) children[i].r += r;
28879 e = packEnclose(children);
28880 if (r) for (i = 0; i < n; ++i) children[i].r -= r;
28886 function translateChild(k) {
28887 return function(node) {
28888 var parent = node.parent;
28891 node.x = parent.x + k * node.x;
28892 node.y = parent.y + k * node.y;
28897 var roundNode = function(node) {
28898 node.x0 = Math.round(node.x0);
28899 node.y0 = Math.round(node.y0);
28900 node.x1 = Math.round(node.x1);
28901 node.y1 = Math.round(node.y1);
28904 var treemapDice = function(parent, x0, y0, x1, y1) {
28905 var nodes = parent.children,
28909 k = parent.value && (x1 - x0) / parent.value;
28912 node = nodes[i], node.y0 = y0, node.y1 = y1;
28913 node.x0 = x0, node.x1 = x0 += node.value * k;
28917 var partition = function() {
28923 function partition(root) {
28924 var n = root.height + 1;
28929 root.eachBefore(positionNode(dy, n));
28930 if (round) root.eachBefore(roundNode);
28934 function positionNode(dy, n) {
28935 return function(node) {
28936 if (node.children) {
28937 treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
28941 x1 = node.x1 - padding,
28942 y1 = node.y1 - padding;
28943 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
28944 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
28952 partition.round = function(x) {
28953 return arguments.length ? (round = !!x, partition) : round;
28956 partition.size = function(x) {
28957 return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
28960 partition.padding = function(x) {
28961 return arguments.length ? (padding = +x, partition) : padding;
28967 var keyPrefix$1 = "$";
28968 var preroot = {depth: -1};
28969 var ambiguous = {};
28971 function defaultId(d) {
28975 function defaultParentId(d) {
28979 var stratify = function() {
28980 var id = defaultId,
28981 parentId = defaultParentId;
28983 function stratify(data) {
28990 nodes = new Array(n),
28995 for (i = 0; i < n; ++i) {
28996 d = data[i], node = nodes[i] = new Node(d);
28997 if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
28998 nodeKey = keyPrefix$1 + (node.id = nodeId);
28999 nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
29003 for (i = 0; i < n; ++i) {
29004 node = nodes[i], nodeId = parentId(data[i], i, data);
29005 if (nodeId == null || !(nodeId += "")) {
29006 if (root) throw new Error("multiple roots");
29009 parent = nodeByKey[keyPrefix$1 + nodeId];
29010 if (!parent) throw new Error("missing: " + nodeId);
29011 if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
29012 if (parent.children) parent.children.push(node);
29013 else parent.children = [node];
29014 node.parent = parent;
29018 if (!root) throw new Error("no root");
29019 root.parent = preroot;
29020 root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
29021 root.parent = null;
29022 if (n > 0) throw new Error("cycle");
29027 stratify.id = function(x) {
29028 return arguments.length ? (id = required(x), stratify) : id;
29031 stratify.parentId = function(x) {
29032 return arguments.length ? (parentId = required(x), stratify) : parentId;
29038 function defaultSeparation$1(a, b) {
29039 return a.parent === b.parent ? 1 : 2;
29042 // function radialSeparation(a, b) {
29043 // return (a.parent === b.parent ? 1 : 2) / a.depth;
29046 // This function is used to traverse the left contour of a subtree (or
29047 // subforest). It returns the successor of v on this contour. This successor is
29048 // either given by the leftmost child of v or by the thread of v. The function
29049 // returns null if and only if v is on the highest level of its subtree.
29050 function nextLeft(v) {
29051 var children = v.children;
29052 return children ? children[0] : v.t;
29055 // This function works analogously to nextLeft.
29056 function nextRight(v) {
29057 var children = v.children;
29058 return children ? children[children.length - 1] : v.t;
29061 // Shifts the current subtree rooted at w+. This is done by increasing
29062 // prelim(w+) and mod(w+) by shift.
29063 function moveSubtree(wm, wp, shift) {
29064 var change = shift / (wp.i - wm.i);
29072 // All other shifts, applied to the smaller subtrees between w- and w+, are
29073 // performed by this function. To prepare the shifts, we have to adjust
29074 // change(w+), shift(w+), and change(w-).
29075 function executeShifts(v) {
29078 children = v.children,
29079 i = children.length,
29085 shift += w.s + (change += w.c);
29089 // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
29090 // returns the specified (default) ancestor.
29091 function nextAncestor(vim, v, ancestor) {
29092 return vim.a.parent === v.parent ? vim.a : ancestor;
29095 function TreeNode(node, i) {
29097 this.parent = null;
29098 this.children = null;
29099 this.A = null; // default ancestor
29100 this.a = this; // ancestor
29101 this.z = 0; // prelim
29103 this.c = 0; // change
29104 this.s = 0; // shift
29105 this.t = null; // thread
29106 this.i = i; // number
29109 TreeNode.prototype = Object.create(Node.prototype);
29111 function treeRoot(root) {
29112 var tree = new TreeNode(root, 0),
29120 while (node = nodes.pop()) {
29121 if (children = node._.children) {
29122 node.children = new Array(n = children.length);
29123 for (i = n - 1; i >= 0; --i) {
29124 nodes.push(child = node.children[i] = new TreeNode(children[i], i));
29125 child.parent = node;
29130 (tree.parent = new TreeNode(null, 0)).children = [tree];
29134 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
29135 var tree = function() {
29136 var separation = defaultSeparation$1,
29141 function tree(root) {
29142 var t = treeRoot(root);
29144 // Compute the layout using Buchheim et al.’s algorithm.
29145 t.eachAfter(firstWalk), t.parent.m = -t.z;
29146 t.eachBefore(secondWalk);
29148 // If a fixed node size is specified, scale x and y.
29149 if (nodeSize) root.eachBefore(sizeNode);
29151 // If a fixed tree size is specified, scale x and y based on the extent.
29152 // Compute the left-most, right-most, and depth-most nodes for extents.
29157 root.eachBefore(function(node) {
29158 if (node.x < left.x) left = node;
29159 if (node.x > right.x) right = node;
29160 if (node.depth > bottom.depth) bottom = node;
29162 var s = left === right ? 1 : separation(left, right) / 2,
29164 kx = dx / (right.x + s + tx),
29165 ky = dy / (bottom.depth || 1);
29166 root.eachBefore(function(node) {
29167 node.x = (node.x + tx) * kx;
29168 node.y = node.depth * ky;
29175 // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
29176 // applied recursively to the children of v, as well as the function
29177 // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
29178 // node v is placed to the midpoint of its outermost children.
29179 function firstWalk(v) {
29180 var children = v.children,
29181 siblings = v.parent.children,
29182 w = v.i ? siblings[v.i - 1] : null;
29185 var midpoint = (children[0].z + children[children.length - 1].z) / 2;
29187 v.z = w.z + separation(v._, w._);
29188 v.m = v.z - midpoint;
29193 v.z = w.z + separation(v._, w._);
29195 v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
29198 // Computes all real x-coordinates by summing up the modifiers recursively.
29199 function secondWalk(v) {
29200 v._.x = v.z + v.parent.m;
29204 // The core of the algorithm. Here, a new subtree is combined with the
29205 // previous subtrees. Threads are used to traverse the inside and outside
29206 // contours of the left and right subtree up to the highest common level. The
29207 // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
29208 // superscript o means outside and i means inside, the subscript - means left
29209 // subtree and + means right subtree. For summing up the modifiers along the
29210 // contour, we use respective variables si+, si-, so-, and so+. Whenever two
29211 // nodes of the inside contours conflict, we compute the left one of the
29212 // greatest uncommon ancestors using the function ANCESTOR and call MOVE
29213 // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
29214 // Finally, we add a new thread (if necessary).
29215 function apportion(v, w, ancestor) {
29220 vom = vip.parent.children[0],
29226 while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
29227 vom = nextLeft(vom);
29228 vop = nextRight(vop);
29230 shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
29232 moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
29241 if (vim && !nextRight(vop)) {
29243 vop.m += sim - sop;
29245 if (vip && !nextLeft(vom)) {
29247 vom.m += sip - som;
29254 function sizeNode(node) {
29256 node.y = node.depth * dy;
29259 tree.separation = function(x) {
29260 return arguments.length ? (separation = x, tree) : separation;
29263 tree.size = function(x) {
29264 return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
29267 tree.nodeSize = function(x) {
29268 return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
29274 var treemapSlice = function(parent, x0, y0, x1, y1) {
29275 var nodes = parent.children,
29279 k = parent.value && (y1 - y0) / parent.value;
29282 node = nodes[i], node.x0 = x0, node.x1 = x1;
29283 node.y0 = y0, node.y1 = y0 += node.value * k;
29287 var phi = (1 + Math.sqrt(5)) / 2;
29289 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
29291 nodes = parent.children,
29298 value = parent.value,
29308 dx = x1 - x0, dy = y1 - y0;
29310 // Find the next non-empty node.
29311 do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
29312 minValue = maxValue = sumValue;
29313 alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
29314 beta = sumValue * sumValue * alpha;
29315 minRatio = Math.max(maxValue / beta, beta / minValue);
29317 // Keep adding nodes while the aspect ratio maintains or improves.
29318 for (; i1 < n; ++i1) {
29319 sumValue += nodeValue = nodes[i1].value;
29320 if (nodeValue < minValue) minValue = nodeValue;
29321 if (nodeValue > maxValue) maxValue = nodeValue;
29322 beta = sumValue * sumValue * alpha;
29323 newRatio = Math.max(maxValue / beta, beta / minValue);
29324 if (newRatio > minRatio) { sumValue -= nodeValue; break; }
29325 minRatio = newRatio;
29328 // Position and record the row orientation.
29329 rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
29330 if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
29331 else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
29332 value -= sumValue, i0 = i1;
29338 var squarify = (function custom(ratio) {
29340 function squarify(parent, x0, y0, x1, y1) {
29341 squarifyRatio(ratio, parent, x0, y0, x1, y1);
29344 squarify.ratio = function(x) {
29345 return custom((x = +x) > 1 ? x : 1);
29351 var index$3 = function() {
29352 var tile = squarify,
29356 paddingStack = [0],
29357 paddingInner = constantZero,
29358 paddingTop = constantZero,
29359 paddingRight = constantZero,
29360 paddingBottom = constantZero,
29361 paddingLeft = constantZero;
29363 function treemap(root) {
29368 root.eachBefore(positionNode);
29369 paddingStack = [0];
29370 if (round) root.eachBefore(roundNode);
29374 function positionNode(node) {
29375 var p = paddingStack[node.depth],
29380 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29381 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29386 if (node.children) {
29387 p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
29388 x0 += paddingLeft(node) - p;
29389 y0 += paddingTop(node) - p;
29390 x1 -= paddingRight(node) - p;
29391 y1 -= paddingBottom(node) - p;
29392 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29393 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29394 tile(node, x0, y0, x1, y1);
29398 treemap.round = function(x) {
29399 return arguments.length ? (round = !!x, treemap) : round;
29402 treemap.size = function(x) {
29403 return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
29406 treemap.tile = function(x) {
29407 return arguments.length ? (tile = required(x), treemap) : tile;
29410 treemap.padding = function(x) {
29411 return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
29414 treemap.paddingInner = function(x) {
29415 return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$6(+x), treemap) : paddingInner;
29418 treemap.paddingOuter = function(x) {
29419 return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
29422 treemap.paddingTop = function(x) {
29423 return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$6(+x), treemap) : paddingTop;
29426 treemap.paddingRight = function(x) {
29427 return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$6(+x), treemap) : paddingRight;
29430 treemap.paddingBottom = function(x) {
29431 return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$6(+x), treemap) : paddingBottom;
29434 treemap.paddingLeft = function(x) {
29435 return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$6(+x), treemap) : paddingLeft;
29441 var binary = function(parent, x0, y0, x1, y1) {
29442 var nodes = parent.children,
29443 i, n = nodes.length,
29444 sum, sums = new Array(n + 1);
29446 for (sums[0] = sum = i = 0; i < n; ++i) {
29447 sums[i + 1] = sum += nodes[i].value;
29450 partition(0, n, parent.value, x0, y0, x1, y1);
29452 function partition(i, j, value, x0, y0, x1, y1) {
29454 var node = nodes[i];
29455 node.x0 = x0, node.y0 = y0;
29456 node.x1 = x1, node.y1 = y1;
29460 var valueOffset = sums[i],
29461 valueTarget = (value / 2) + valueOffset,
29466 var mid = k + hi >>> 1;
29467 if (sums[mid] < valueTarget) k = mid + 1;
29471 var valueLeft = sums[k] - valueOffset,
29472 valueRight = value - valueLeft;
29474 if ((y1 - y0) > (x1 - x0)) {
29475 var yk = (y0 * valueRight + y1 * valueLeft) / value;
29476 partition(i, k, valueLeft, x0, y0, x1, yk);
29477 partition(k, j, valueRight, x0, yk, x1, y1);
29479 var xk = (x0 * valueRight + x1 * valueLeft) / value;
29480 partition(i, k, valueLeft, x0, y0, xk, y1);
29481 partition(k, j, valueRight, xk, y0, x1, y1);
29486 var sliceDice = function(parent, x0, y0, x1, y1) {
29487 (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
29490 var resquarify = (function custom(ratio) {
29492 function resquarify(parent, x0, y0, x1, y1) {
29493 if ((rows = parent._squarify) && (rows.ratio === ratio)) {
29501 value = parent.value;
29504 row = rows[j], nodes = row.children;
29505 for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
29506 if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
29507 else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
29508 value -= row.value;
29511 parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
29512 rows.ratio = ratio;
29516 resquarify.ratio = function(x) {
29517 return custom((x = +x) > 1 ? x : 1);
29523 var center$1 = function(x, y) {
29526 if (x == null) x = 0;
29527 if (y == null) y = 0;
29536 for (i = 0; i < n; ++i) {
29537 node = nodes[i], sx += node.x, sy += node.y;
29540 for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
29541 node = nodes[i], node.x -= sx, node.y -= sy;
29545 force.initialize = function(_) {
29549 force.x = function(_) {
29550 return arguments.length ? (x = +_, force) : x;
29553 force.y = function(_) {
29554 return arguments.length ? (y = +_, force) : y;
29560 var constant$7 = function(x) {
29561 return function() {
29566 var jiggle = function() {
29567 return (Math.random() - 0.5) * 1e-6;
29578 var collide = function(radius) {
29584 if (typeof radius !== "function") radius = constant$7(radius == null ? 1 : +radius);
29587 var i, n = nodes.length,
29595 for (var k = 0; k < iterations; ++k) {
29596 tree = quadtree(nodes, x$1, y$1).visitAfter(prepare);
29597 for (i = 0; i < n; ++i) {
29599 ri = radii[node.index], ri2 = ri * ri;
29600 xi = node.x + node.vx;
29601 yi = node.y + node.vy;
29606 function apply(quad, x0, y0, x1, y1) {
29607 var data = quad.data, rj = quad.r, r = ri + rj;
29609 if (data.index > node.index) {
29610 var x = xi - data.x - data.vx,
29611 y = yi - data.y - data.vy,
29614 if (x === 0) x = jiggle(), l += x * x;
29615 if (y === 0) y = jiggle(), l += y * y;
29616 l = (r - (l = Math.sqrt(l))) / l * strength;
29617 node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
29618 node.vy += (y *= l) * r;
29619 data.vx -= x * (r = 1 - r);
29625 return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
29629 function prepare(quad) {
29630 if (quad.data) return quad.r = radii[quad.data.index];
29631 for (var i = quad.r = 0; i < 4; ++i) {
29632 if (quad[i] && quad[i].r > quad.r) {
29633 quad.r = quad[i].r;
29638 function initialize() {
29639 if (!nodes) return;
29640 var i, n = nodes.length, node;
29641 radii = new Array(n);
29642 for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
29645 force.initialize = function(_) {
29650 force.iterations = function(_) {
29651 return arguments.length ? (iterations = +_, force) : iterations;
29654 force.strength = function(_) {
29655 return arguments.length ? (strength = +_, force) : strength;
29658 force.radius = function(_) {
29659 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : radius;
29665 function index$4(d) {
29669 function find(nodeById, nodeId) {
29670 var node = nodeById.get(nodeId);
29671 if (!node) throw new Error("missing: " + nodeId);
29675 var link = function(links) {
29677 strength = defaultStrength,
29679 distance = constant$7(30),
29686 if (links == null) links = [];
29688 function defaultStrength(link) {
29689 return 1 / Math.min(count[link.source.index], count[link.target.index]);
29692 function force(alpha) {
29693 for (var k = 0, n = links.length; k < iterations; ++k) {
29694 for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
29695 link = links[i], source = link.source, target = link.target;
29696 x = target.x + target.vx - source.x - source.vx || jiggle();
29697 y = target.y + target.vy - source.y - source.vy || jiggle();
29698 l = Math.sqrt(x * x + y * y);
29699 l = (l - distances[i]) / l * alpha * strengths[i];
29701 target.vx -= x * (b = bias[i]);
29702 target.vy -= y * b;
29703 source.vx += x * (b = 1 - b);
29704 source.vy += y * b;
29709 function initialize() {
29710 if (!nodes) return;
29715 nodeById = map$1(nodes, id),
29718 for (i = 0, count = new Array(n); i < m; ++i) {
29719 link = links[i], link.index = i;
29720 if (typeof link.source !== "object") link.source = find(nodeById, link.source);
29721 if (typeof link.target !== "object") link.target = find(nodeById, link.target);
29722 count[link.source.index] = (count[link.source.index] || 0) + 1;
29723 count[link.target.index] = (count[link.target.index] || 0) + 1;
29726 for (i = 0, bias = new Array(m); i < m; ++i) {
29727 link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
29730 strengths = new Array(m), initializeStrength();
29731 distances = new Array(m), initializeDistance();
29734 function initializeStrength() {
29735 if (!nodes) return;
29737 for (var i = 0, n = links.length; i < n; ++i) {
29738 strengths[i] = +strength(links[i], i, links);
29742 function initializeDistance() {
29743 if (!nodes) return;
29745 for (var i = 0, n = links.length; i < n; ++i) {
29746 distances[i] = +distance(links[i], i, links);
29750 force.initialize = function(_) {
29755 force.links = function(_) {
29756 return arguments.length ? (links = _, initialize(), force) : links;
29759 force.id = function(_) {
29760 return arguments.length ? (id = _, force) : id;
29763 force.iterations = function(_) {
29764 return arguments.length ? (iterations = +_, force) : iterations;
29767 force.strength = function(_) {
29768 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initializeStrength(), force) : strength;
29771 force.distance = function(_) {
29772 return arguments.length ? (distance = typeof _ === "function" ? _ : constant$7(+_), initializeDistance(), force) : distance;
29786 var initialRadius = 10;
29787 var initialAngle = Math.PI * (3 - Math.sqrt(5));
29789 var simulation = function(nodes) {
29793 alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
29795 velocityDecay = 0.6,
29797 stepper = timer(step),
29798 event = dispatch("tick", "end");
29800 if (nodes == null) nodes = [];
29804 event.call("tick", simulation);
29805 if (alpha < alphaMin) {
29807 event.call("end", simulation);
29812 var i, n = nodes.length, node;
29814 alpha += (alphaTarget - alpha) * alphaDecay;
29816 forces.each(function(force) {
29820 for (i = 0; i < n; ++i) {
29822 if (node.fx == null) node.x += node.vx *= velocityDecay;
29823 else node.x = node.fx, node.vx = 0;
29824 if (node.fy == null) node.y += node.vy *= velocityDecay;
29825 else node.y = node.fy, node.vy = 0;
29829 function initializeNodes() {
29830 for (var i = 0, n = nodes.length, node; i < n; ++i) {
29831 node = nodes[i], node.index = i;
29832 if (isNaN(node.x) || isNaN(node.y)) {
29833 var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
29834 node.x = radius * Math.cos(angle);
29835 node.y = radius * Math.sin(angle);
29837 if (isNaN(node.vx) || isNaN(node.vy)) {
29838 node.vx = node.vy = 0;
29843 function initializeForce(force) {
29844 if (force.initialize) force.initialize(nodes);
29850 return simulation = {
29853 restart: function() {
29854 return stepper.restart(step), simulation;
29858 return stepper.stop(), simulation;
29861 nodes: function(_) {
29862 return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
29865 alpha: function(_) {
29866 return arguments.length ? (alpha = +_, simulation) : alpha;
29869 alphaMin: function(_) {
29870 return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
29873 alphaDecay: function(_) {
29874 return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
29877 alphaTarget: function(_) {
29878 return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
29881 velocityDecay: function(_) {
29882 return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
29885 force: function(name, _) {
29886 return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
29889 find: function(x, y, radius) {
29898 if (radius == null) radius = Infinity;
29899 else radius *= radius;
29901 for (i = 0; i < n; ++i) {
29905 d2 = dx * dx + dy * dy;
29906 if (d2 < radius) closest = node, radius = d2;
29912 on: function(name, _) {
29913 return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
29918 var manyBody = function() {
29922 strength = constant$7(-30),
29925 distanceMax2 = Infinity,
29928 function force(_) {
29929 var i, n = nodes.length, tree = quadtree(nodes, x$2, y$2).visitAfter(accumulate);
29930 for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
29933 function initialize() {
29934 if (!nodes) return;
29935 var i, n = nodes.length, node;
29936 strengths = new Array(n);
29937 for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
29940 function accumulate(quad) {
29941 var strength = 0, q, c, x$$1, y$$1, i;
29943 // For internal nodes, accumulate forces from child quadrants.
29945 for (x$$1 = y$$1 = i = 0; i < 4; ++i) {
29946 if ((q = quad[i]) && (c = q.value)) {
29947 strength += c, x$$1 += c * q.x, y$$1 += c * q.y;
29950 quad.x = x$$1 / strength;
29951 quad.y = y$$1 / strength;
29954 // For leaf nodes, accumulate forces from coincident quadrants.
29959 do strength += strengths[q.data.index];
29960 while (q = q.next);
29963 quad.value = strength;
29966 function apply(quad, x1, _, x2) {
29967 if (!quad.value) return true;
29969 var x$$1 = quad.x - node.x,
29970 y$$1 = quad.y - node.y,
29972 l = x$$1 * x$$1 + y$$1 * y$$1;
29974 // Apply the Barnes-Hut approximation if possible.
29975 // Limit forces for very close nodes; randomize direction if coincident.
29976 if (w * w / theta2 < l) {
29977 if (l < distanceMax2) {
29978 if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
29979 if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
29980 if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
29981 node.vx += x$$1 * quad.value * alpha / l;
29982 node.vy += y$$1 * quad.value * alpha / l;
29987 // Otherwise, process points directly.
29988 else if (quad.length || l >= distanceMax2) return;
29990 // Limit forces for very close nodes; randomize direction if coincident.
29991 if (quad.data !== node || quad.next) {
29992 if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
29993 if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
29994 if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
29997 do if (quad.data !== node) {
29998 w = strengths[quad.data.index] * alpha / l;
29999 node.vx += x$$1 * w;
30000 node.vy += y$$1 * w;
30001 } while (quad = quad.next);
30004 force.initialize = function(_) {
30009 force.strength = function(_) {
30010 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength;
30013 force.distanceMin = function(_) {
30014 return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
30017 force.distanceMax = function(_) {
30018 return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
30021 force.theta = function(_) {
30022 return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
30028 var x$3 = function(x) {
30029 var strength = constant$7(0.1),
30034 if (typeof x !== "function") x = constant$7(x == null ? 0 : +x);
30036 function force(alpha) {
30037 for (var i = 0, n = nodes.length, node; i < n; ++i) {
30038 node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
30042 function initialize() {
30043 if (!nodes) return;
30044 var i, n = nodes.length;
30045 strengths = new Array(n);
30047 for (i = 0; i < n; ++i) {
30048 strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
30052 force.initialize = function(_) {
30057 force.strength = function(_) {
30058 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength;
30061 force.x = function(_) {
30062 return arguments.length ? (x = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : x;
30068 var y$3 = function(y) {
30069 var strength = constant$7(0.1),
30074 if (typeof y !== "function") y = constant$7(y == null ? 0 : +y);
30076 function force(alpha) {
30077 for (var i = 0, n = nodes.length, node; i < n; ++i) {
30078 node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
30082 function initialize() {
30083 if (!nodes) return;
30084 var i, n = nodes.length;
30085 strengths = new Array(n);
30087 for (i = 0; i < n; ++i) {
30088 strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
30092 force.initialize = function(_) {
30097 force.strength = function(_) {
30098 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : strength;
30101 force.y = function(_) {
30102 return arguments.length ? (y = typeof _ === "function" ? _ : constant$7(+_), initialize(), force) : y;
30108 function nopropagation() {
30109 event.stopImmediatePropagation();
30112 var noevent = function() {
30113 event.preventDefault();
30114 event.stopImmediatePropagation();
30117 var dragDisable = function(view) {
30118 var root = view.document.documentElement,
30119 selection$$1 = select(view).on("dragstart.drag", noevent, true);
30120 if ("onselectstart" in root) {
30121 selection$$1.on("selectstart.drag", noevent, true);
30123 root.__noselect = root.style.MozUserSelect;
30124 root.style.MozUserSelect = "none";
30128 function yesdrag(view, noclick) {
30129 var root = view.document.documentElement,
30130 selection$$1 = select(view).on("dragstart.drag", null);
30132 selection$$1.on("click.drag", noevent, true);
30133 setTimeout(function() { selection$$1.on("click.drag", null); }, 0);
30135 if ("onselectstart" in root) {
30136 selection$$1.on("selectstart.drag", null);
30138 root.style.MozUserSelect = root.__noselect;
30139 delete root.__noselect;
30143 var constant$8 = function(x) {
30144 return function() {
30149 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
30150 this.target = target;
30152 this.subject = subject;
30153 this.identifier = id;
30154 this.active = active;
30162 DragEvent.prototype.on = function() {
30163 var value = this._.on.apply(this._, arguments);
30164 return value === this._ ? this : value;
30167 // Ignore right-click, since that should open the context menu.
30168 function defaultFilter() {
30169 return !event.button;
30172 function defaultContainer() {
30173 return this.parentNode;
30176 function defaultSubject(d) {
30177 return d == null ? {x: event.x, y: event.y} : d;
30180 var drag = function() {
30181 var filter = defaultFilter,
30182 container = defaultContainer,
30183 subject = defaultSubject,
30185 listeners = dispatch("start", "drag", "end"),
30190 function drag(selection$$1) {
30192 .on("mousedown.drag", mousedowned)
30193 .on("touchstart.drag", touchstarted)
30194 .on("touchmove.drag", touchmoved)
30195 .on("touchend.drag touchcancel.drag", touchended)
30196 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
30199 function mousedowned() {
30200 if (touchending || !filter.apply(this, arguments)) return;
30201 var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments);
30202 if (!gesture) return;
30203 select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
30204 dragDisable(event.view);
30206 mousemoving = false;
30210 function mousemoved() {
30212 mousemoving = true;
30213 gestures.mouse("drag");
30216 function mouseupped() {
30217 select(event.view).on("mousemove.drag mouseup.drag", null);
30218 yesdrag(event.view, mousemoving);
30220 gestures.mouse("end");
30223 function touchstarted() {
30224 if (!filter.apply(this, arguments)) return;
30225 var touches$$1 = event.changedTouches,
30226 c = container.apply(this, arguments),
30227 n = touches$$1.length, i, gesture;
30229 for (i = 0; i < n; ++i) {
30230 if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) {
30237 function touchmoved() {
30238 var touches$$1 = event.changedTouches,
30239 n = touches$$1.length, i, gesture;
30241 for (i = 0; i < n; ++i) {
30242 if (gesture = gestures[touches$$1[i].identifier]) {
30249 function touchended() {
30250 var touches$$1 = event.changedTouches,
30251 n = touches$$1.length, i, gesture;
30253 if (touchending) clearTimeout(touchending);
30254 touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
30255 for (i = 0; i < n; ++i) {
30256 if (gesture = gestures[touches$$1[i].identifier]) {
30263 function beforestart(id, container, point, that, args) {
30264 var p = point(container, id), s, dx, dy,
30265 sublisteners = listeners.copy();
30267 if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
30268 if ((event.subject = s = subject.apply(that, args)) == null) return false;
30269 dx = s.x - p[0] || 0;
30270 dy = s.y - p[1] || 0;
30274 return function gesture(type) {
30277 case "start": gestures[id] = gesture, n = active++; break;
30278 case "end": delete gestures[id], --active; // nobreak
30279 case "drag": p = point(container, id), n = active; break;
30281 customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);
30285 drag.filter = function(_) {
30286 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$8(!!_), drag) : filter;
30289 drag.container = function(_) {
30290 return arguments.length ? (container = typeof _ === "function" ? _ : constant$8(_), drag) : container;
30293 drag.subject = function(_) {
30294 return arguments.length ? (subject = typeof _ === "function" ? _ : constant$8(_), drag) : subject;
30297 drag.on = function() {
30298 var value = listeners.on.apply(listeners, arguments);
30299 return value === listeners ? drag : value;
30305 var constant$9 = function(x) {
30306 return function() {
30319 function RedBlackTree() {
30320 this._ = null; // root node
30323 function RedBlackNode(node) {
30324 node.U = // parent node
30325 node.C = // color - true for red, false for black
30326 node.L = // left node
30327 node.R = // right node
30328 node.P = // previous node
30329 node.N = null; // next node
30332 RedBlackTree.prototype = {
30333 constructor: RedBlackTree,
30335 insert: function(after, node) {
30336 var parent, grandpa, uncle;
30341 if (after.N) after.N.P = node;
30345 while (after.L) after = after.L;
30351 } else if (this._) {
30352 after = RedBlackFirst(this._);
30355 after.P = after.L = node;
30358 node.P = node.N = null;
30362 node.L = node.R = null;
30367 while (parent && parent.C) {
30368 grandpa = parent.U;
30369 if (parent === grandpa.L) {
30371 if (uncle && uncle.C) {
30372 parent.C = uncle.C = false;
30376 if (after === parent.R) {
30377 RedBlackRotateLeft(this, parent);
30383 RedBlackRotateRight(this, grandpa);
30387 if (uncle && uncle.C) {
30388 parent.C = uncle.C = false;
30392 if (after === parent.L) {
30393 RedBlackRotateRight(this, parent);
30399 RedBlackRotateLeft(this, grandpa);
30407 remove: function(node) {
30408 if (node.N) node.N.P = node.P;
30409 if (node.P) node.P.N = node.N;
30410 node.N = node.P = null;
30412 var parent = node.U,
30419 if (!left) next = right;
30420 else if (!right) next = left;
30421 else next = RedBlackFirst(right);
30424 if (parent.L === node) parent.L = next;
30425 else parent.R = next;
30430 if (left && right) {
30435 if (next !== right) {
30452 if (node) node.U = parent;
30454 if (node && node.C) { node.C = false; return; }
30457 if (node === this._) break;
30458 if (node === parent.L) {
30459 sibling = parent.R;
30463 RedBlackRotateLeft(this, parent);
30464 sibling = parent.R;
30466 if ((sibling.L && sibling.L.C)
30467 || (sibling.R && sibling.R.C)) {
30468 if (!sibling.R || !sibling.R.C) {
30469 sibling.L.C = false;
30471 RedBlackRotateRight(this, sibling);
30472 sibling = parent.R;
30474 sibling.C = parent.C;
30475 parent.C = sibling.R.C = false;
30476 RedBlackRotateLeft(this, parent);
30481 sibling = parent.L;
30485 RedBlackRotateRight(this, parent);
30486 sibling = parent.L;
30488 if ((sibling.L && sibling.L.C)
30489 || (sibling.R && sibling.R.C)) {
30490 if (!sibling.L || !sibling.L.C) {
30491 sibling.R.C = false;
30493 RedBlackRotateLeft(this, sibling);
30494 sibling = parent.L;
30496 sibling.C = parent.C;
30497 parent.C = sibling.L.C = false;
30498 RedBlackRotateRight(this, parent);
30508 if (node) node.C = false;
30512 function RedBlackRotateLeft(tree, node) {
30518 if (parent.L === p) parent.L = q;
30527 if (p.R) p.R.U = p;
30531 function RedBlackRotateRight(tree, node) {
30537 if (parent.L === p) parent.L = q;
30546 if (p.L) p.L.U = p;
30550 function RedBlackFirst(node) {
30551 while (node.L) node = node.L;
30555 function createEdge(left, right, v0, v1) {
30556 var edge = [null, null],
30557 index = edges.push(edge) - 1;
30559 edge.right = right;
30560 if (v0) setEdgeEnd(edge, left, right, v0);
30561 if (v1) setEdgeEnd(edge, right, left, v1);
30562 cells[left.index].halfedges.push(index);
30563 cells[right.index].halfedges.push(index);
30567 function createBorderEdge(left, v0, v1) {
30568 var edge = [v0, v1];
30573 function setEdgeEnd(edge, left, right, vertex) {
30574 if (!edge[0] && !edge[1]) {
30577 edge.right = right;
30578 } else if (edge.left === right) {
30585 // Liang–Barsky line clipping.
30586 function clipEdge(edge, x0, y0, x1, y1) {
30600 if (!dx && r > 0) return;
30603 if (r < t0) return;
30604 if (r < t1) t1 = r;
30605 } else if (dx > 0) {
30606 if (r > t1) return;
30607 if (r > t0) t0 = r;
30611 if (!dx && r < 0) return;
30614 if (r > t1) return;
30615 if (r > t0) t0 = r;
30616 } else if (dx > 0) {
30617 if (r < t0) return;
30618 if (r < t1) t1 = r;
30622 if (!dy && r > 0) return;
30625 if (r < t0) return;
30626 if (r < t1) t1 = r;
30627 } else if (dy > 0) {
30628 if (r > t1) return;
30629 if (r > t0) t0 = r;
30633 if (!dy && r < 0) return;
30636 if (r > t1) return;
30637 if (r > t0) t0 = r;
30638 } else if (dy > 0) {
30639 if (r < t0) return;
30640 if (r < t1) t1 = r;
30643 if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?
30645 if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
30646 if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
30650 function connectEdge(edge, x0, y0, x1, y1) {
30652 if (v1) return true;
30656 right = edge.right,
30661 fx = (lx + rx) / 2,
30662 fy = (ly + ry) / 2,
30667 if (fx < x0 || fx >= x1) return;
30669 if (!v0) v0 = [fx, y0];
30670 else if (v0[1] >= y1) return;
30673 if (!v0) v0 = [fx, y1];
30674 else if (v0[1] < y0) return;
30678 fm = (lx - rx) / (ry - ly);
30680 if (fm < -1 || fm > 1) {
30682 if (!v0) v0 = [(y0 - fb) / fm, y0];
30683 else if (v0[1] >= y1) return;
30684 v1 = [(y1 - fb) / fm, y1];
30686 if (!v0) v0 = [(y1 - fb) / fm, y1];
30687 else if (v0[1] < y0) return;
30688 v1 = [(y0 - fb) / fm, y0];
30692 if (!v0) v0 = [x0, fm * x0 + fb];
30693 else if (v0[0] >= x1) return;
30694 v1 = [x1, fm * x1 + fb];
30696 if (!v0) v0 = [x1, fm * x1 + fb];
30697 else if (v0[0] < x0) return;
30698 v1 = [x0, fm * x0 + fb];
30708 function clipEdges(x0, y0, x1, y1) {
30709 var i = edges.length,
30713 if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
30714 || !clipEdge(edge, x0, y0, x1, y1)
30715 || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$3
30716 || Math.abs(edge[0][1] - edge[1][1]) > epsilon$3)) {
30722 function createCell(site) {
30723 return cells[site.index] = {
30729 function cellHalfedgeAngle(cell, edge) {
30730 var site = cell.site,
30733 if (site === vb) vb = va, va = site;
30734 if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
30735 if (site === va) va = edge[1], vb = edge[0];
30736 else va = edge[0], vb = edge[1];
30737 return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
30740 function cellHalfedgeStart(cell, edge) {
30741 return edge[+(edge.left !== cell.site)];
30744 function cellHalfedgeEnd(cell, edge) {
30745 return edge[+(edge.left === cell.site)];
30748 function sortCellHalfedges() {
30749 for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
30750 if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
30751 var index = new Array(m),
30752 array = new Array(m);
30753 for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
30754 index.sort(function(i, j) { return array[j] - array[i]; });
30755 for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
30756 for (j = 0; j < m; ++j) halfedges[j] = array[j];
30761 function clipCells(x0, y0, x1, y1) {
30762 var nCells = cells.length,
30777 for (iCell = 0; iCell < nCells; ++iCell) {
30778 if (cell = cells[iCell]) {
30780 halfedges = cell.halfedges;
30781 iHalfedge = halfedges.length;
30783 // Remove any dangling clipped edges.
30784 while (iHalfedge--) {
30785 if (!edges[halfedges[iHalfedge]]) {
30786 halfedges.splice(iHalfedge, 1);
30790 // Insert any border edges as necessary.
30791 iHalfedge = 0, nHalfedges = halfedges.length;
30792 while (iHalfedge < nHalfedges) {
30793 end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
30794 start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
30795 if (Math.abs(endX - startX) > epsilon$3 || Math.abs(endY - startY) > epsilon$3) {
30796 halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
30797 Math.abs(endX - x0) < epsilon$3 && y1 - endY > epsilon$3 ? [x0, Math.abs(startX - x0) < epsilon$3 ? startY : y1]
30798 : Math.abs(endY - y1) < epsilon$3 && x1 - endX > epsilon$3 ? [Math.abs(startY - y1) < epsilon$3 ? startX : x1, y1]
30799 : Math.abs(endX - x1) < epsilon$3 && endY - y0 > epsilon$3 ? [x1, Math.abs(startX - x1) < epsilon$3 ? startY : y0]
30800 : Math.abs(endY - y0) < epsilon$3 && endX - x0 > epsilon$3 ? [Math.abs(startY - y0) < epsilon$3 ? startX : x0, y0]
30806 if (nHalfedges) cover = false;
30810 // If there weren’t any edges, have the closest site cover the extent.
30811 // It doesn’t matter which corner of the extent we measure!
30813 var dx, dy, d2, dc = Infinity;
30815 for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
30816 if (cell = cells[iCell]) {
30820 d2 = dx * dx + dy * dy;
30821 if (d2 < dc) dc = d2, cover = cell;
30826 var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
30827 cover.halfedges.push(
30828 edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
30829 edges.push(createBorderEdge(site, v01, v11)) - 1,
30830 edges.push(createBorderEdge(site, v11, v10)) - 1,
30831 edges.push(createBorderEdge(site, v10, v00)) - 1
30836 // Lastly delete any cells with no edges; these were entirely clipped.
30837 for (iCell = 0; iCell < nCells; ++iCell) {
30838 if (cell = cells[iCell]) {
30839 if (!cell.halfedges.length) {
30840 delete cells[iCell];
30846 var circlePool = [];
30850 function Circle() {
30851 RedBlackNode(this);
30859 function attachCircle(arc) {
30863 if (!lArc || !rArc) return;
30865 var lSite = lArc.site,
30869 if (lSite === rSite) return;
30873 ax = lSite[0] - bx,
30874 ay = lSite[1] - by,
30875 cx = rSite[0] - bx,
30876 cy = rSite[1] - by;
30878 var d = 2 * (ax * cy - ay * cx);
30879 if (d >= -epsilon2$1) return;
30881 var ha = ax * ax + ay * ay,
30882 hc = cx * cx + cy * cy,
30883 x = (cy * ha - ay * hc) / d,
30884 y = (ax * hc - cx * ha) / d;
30886 var circle = circlePool.pop() || new Circle;
30888 circle.site = cSite;
30890 circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
30892 arc.circle = circle;
30898 if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
30899 if (node.L) node = node.L;
30900 else { before = node.P; break; }
30902 if (node.R) node = node.R;
30903 else { before = node; break; }
30907 circles.insert(before, circle);
30908 if (!before) firstCircle = circle;
30911 function detachCircle(arc) {
30912 var circle = arc.circle;
30914 if (!circle.P) firstCircle = circle.N;
30915 circles.remove(circle);
30916 circlePool.push(circle);
30917 RedBlackNode(circle);
30922 var beachPool = [];
30925 RedBlackNode(this);
30928 this.circle = null;
30931 function createBeach(site) {
30932 var beach = beachPool.pop() || new Beach;
30937 function detachBeach(beach) {
30938 detachCircle(beach);
30939 beaches.remove(beach);
30940 beachPool.push(beach);
30941 RedBlackNode(beach);
30944 function removeBeach(beach) {
30945 var circle = beach.circle,
30949 previous = beach.P,
30951 disappearing = [beach];
30953 detachBeach(beach);
30955 var lArc = previous;
30957 && Math.abs(x - lArc.circle.x) < epsilon$3
30958 && Math.abs(y - lArc.circle.cy) < epsilon$3) {
30960 disappearing.unshift(lArc);
30965 disappearing.unshift(lArc);
30966 detachCircle(lArc);
30970 && Math.abs(x - rArc.circle.x) < epsilon$3
30971 && Math.abs(y - rArc.circle.cy) < epsilon$3) {
30973 disappearing.push(rArc);
30978 disappearing.push(rArc);
30979 detachCircle(rArc);
30981 var nArcs = disappearing.length,
30983 for (iArc = 1; iArc < nArcs; ++iArc) {
30984 rArc = disappearing[iArc];
30985 lArc = disappearing[iArc - 1];
30986 setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
30989 lArc = disappearing[0];
30990 rArc = disappearing[nArcs - 1];
30991 rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
30993 attachCircle(lArc);
30994 attachCircle(rArc);
30997 function addBeach(site) {
30999 directrix = site[1],
31007 dxl = leftBreakPoint(node, directrix) - x;
31008 if (dxl > epsilon$3) node = node.L; else {
31009 dxr = x - rightBreakPoint(node, directrix);
31010 if (dxr > epsilon$3) {
31017 if (dxl > -epsilon$3) {
31020 } else if (dxr > -epsilon$3) {
31024 lArc = rArc = node;
31032 var newArc = createBeach(site);
31033 beaches.insert(lArc, newArc);
31035 if (!lArc && !rArc) return;
31037 if (lArc === rArc) {
31038 detachCircle(lArc);
31039 rArc = createBeach(lArc.site);
31040 beaches.insert(newArc, rArc);
31041 newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
31042 attachCircle(lArc);
31043 attachCircle(rArc);
31047 if (!rArc) { // && lArc
31048 newArc.edge = createEdge(lArc.site, newArc.site);
31052 // else lArc !== rArc
31053 detachCircle(lArc);
31054 detachCircle(rArc);
31056 var lSite = lArc.site,
31062 cx = rSite[0] - ax,
31063 cy = rSite[1] - ay,
31064 d = 2 * (bx * cy - by * cx),
31065 hb = bx * bx + by * by,
31066 hc = cx * cx + cy * cy,
31067 vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
31069 setEdgeEnd(rArc.edge, lSite, rSite, vertex);
31070 newArc.edge = createEdge(lSite, site, null, vertex);
31071 rArc.edge = createEdge(site, rSite, null, vertex);
31072 attachCircle(lArc);
31073 attachCircle(rArc);
31076 function leftBreakPoint(arc, directrix) {
31077 var site = arc.site,
31080 pby2 = rfocy - directrix;
31082 if (!pby2) return rfocx;
31085 if (!lArc) return -Infinity;
31088 var lfocx = site[0],
31090 plby2 = lfocy - directrix;
31092 if (!plby2) return lfocx;
31094 var hl = lfocx - rfocx,
31095 aby2 = 1 / pby2 - 1 / plby2,
31098 if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
31100 return (rfocx + lfocx) / 2;
31103 function rightBreakPoint(arc, directrix) {
31105 if (rArc) return leftBreakPoint(rArc, directrix);
31106 var site = arc.site;
31107 return site[1] === directrix ? site[0] : Infinity;
31110 var epsilon$3 = 1e-6;
31111 var epsilon2$1 = 1e-12;
31117 function triangleArea(a, b, c) {
31118 return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
31121 function lexicographic(a, b) {
31126 function Diagram(sites, extent) {
31127 var site = sites.sort(lexicographic).pop(),
31133 cells = new Array(sites.length);
31134 beaches = new RedBlackTree;
31135 circles = new RedBlackTree;
31138 circle = firstCircle;
31139 if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
31140 if (site[0] !== x || site[1] !== y) {
31142 x = site[0], y = site[1];
31144 site = sites.pop();
31145 } else if (circle) {
31146 removeBeach(circle.arc);
31152 sortCellHalfedges();
31155 var x0 = +extent[0][0],
31156 y0 = +extent[0][1],
31157 x1 = +extent[1][0],
31158 y1 = +extent[1][1];
31159 clipEdges(x0, y0, x1, y1);
31160 clipCells(x0, y0, x1, y1);
31163 this.edges = edges;
31164 this.cells = cells;
31172 Diagram.prototype = {
31173 constructor: Diagram,
31175 polygons: function() {
31176 var edges = this.edges;
31178 return this.cells.map(function(cell) {
31179 var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
31180 polygon.data = cell.site.data;
31185 triangles: function() {
31186 var triangles = [],
31187 edges = this.edges;
31189 this.cells.forEach(function(cell, i) {
31190 var site = cell.site,
31191 halfedges = cell.halfedges,
31193 m = halfedges.length,
31195 e1 = edges[halfedges[m - 1]],
31196 s1 = e1.left === site ? e1.right : e1.left;
31200 e1 = edges[halfedges[j]];
31201 s1 = e1.left === site ? e1.right : e1.left;
31202 if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
31203 triangles.push([site.data, s0.data, s1.data]);
31211 links: function() {
31212 return this.edges.filter(function(edge) {
31214 }).map(function(edge) {
31216 source: edge.left.data,
31217 target: edge.right.data
31222 find: function(x, y, radius) {
31224 i0, i1 = that._found || 0,
31225 cell = that.cells[i1] || that.cells[i1 = 0],
31226 dx = x - cell.site[0],
31227 dy = y - cell.site[1],
31228 d2 = dx * dx + dy * dy;
31231 cell = that.cells[i0 = i1], i1 = null;
31232 cell.halfedges.forEach(function(e) {
31233 var edge = that.edges[e], v = edge.left;
31234 if ((v === cell.site || !v) && !(v = edge.right)) return;
31237 v2 = vx * vx + vy * vy;
31238 if (v2 < d2) d2 = v2, i1 = v.index;
31240 } while (i1 !== null);
31244 return radius == null || d2 <= radius * radius ? cell.site : null;
31248 var voronoi = function() {
31253 function voronoi(data) {
31254 return new Diagram(data.map(function(d, i) {
31255 var s = [Math.round(x$$1(d, i, data) / epsilon$3) * epsilon$3, Math.round(y$$1(d, i, data) / epsilon$3) * epsilon$3];
31262 voronoi.polygons = function(data) {
31263 return voronoi(data).polygons();
31266 voronoi.links = function(data) {
31267 return voronoi(data).links();
31270 voronoi.triangles = function(data) {
31271 return voronoi(data).triangles();
31274 voronoi.x = function(_) {
31275 return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$9(+_), voronoi) : x$$1;
31278 voronoi.y = function(_) {
31279 return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$9(+_), voronoi) : y$$1;
31282 voronoi.extent = function(_) {
31283 return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]];
31286 voronoi.size = function(_) {
31287 return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
31293 var constant$10 = function(x) {
31294 return function() {
31299 function ZoomEvent(target, type, transform) {
31300 this.target = target;
31302 this.transform = transform;
31305 function Transform(k, x, y) {
31311 Transform.prototype = {
31312 constructor: Transform,
31313 scale: function(k) {
31314 return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
31316 translate: function(x, y) {
31317 return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
31319 apply: function(point) {
31320 return [point[0] * this.k + this.x, point[1] * this.k + this.y];
31322 applyX: function(x) {
31323 return x * this.k + this.x;
31325 applyY: function(y) {
31326 return y * this.k + this.y;
31328 invert: function(location) {
31329 return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
31331 invertX: function(x) {
31332 return (x - this.x) / this.k;
31334 invertY: function(y) {
31335 return (y - this.y) / this.k;
31337 rescaleX: function(x) {
31338 return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
31340 rescaleY: function(y) {
31341 return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
31343 toString: function() {
31344 return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
31348 var identity$6 = new Transform(1, 0, 0);
31350 transform.prototype = Transform.prototype;
31352 function transform(node) {
31353 return node.__zoom || identity$6;
31356 function nopropagation$1() {
31357 event.stopImmediatePropagation();
31360 var noevent$1 = function() {
31361 event.preventDefault();
31362 event.stopImmediatePropagation();
31365 // Ignore right-click, since that should open the context menu.
31366 function defaultFilter$1() {
31367 return !event.button;
31370 function defaultExtent() {
31371 var e = this, w, h;
31372 if (e instanceof SVGElement) {
31373 e = e.ownerSVGElement || e;
31374 w = e.width.baseVal.value;
31375 h = e.height.baseVal.value;
31378 h = e.clientHeight;
31380 return [[0, 0], [w, h]];
31383 function defaultTransform() {
31384 return this.__zoom || identity$6;
31387 var zoom = function() {
31388 var filter = defaultFilter$1,
31389 extent = defaultExtent,
31397 interpolate$$1 = interpolateZoom,
31399 listeners = dispatch("start", "zoom", "end"),
31405 function zoom(selection$$1) {
31407 .on("wheel.zoom", wheeled)
31408 .on("mousedown.zoom", mousedowned)
31409 .on("dblclick.zoom", dblclicked)
31410 .on("touchstart.zoom", touchstarted)
31411 .on("touchmove.zoom", touchmoved)
31412 .on("touchend.zoom touchcancel.zoom", touchended)
31413 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
31414 .property("__zoom", defaultTransform);
31417 zoom.transform = function(collection, transform) {
31418 var selection$$1 = collection.selection ? collection.selection() : collection;
31419 selection$$1.property("__zoom", defaultTransform);
31420 if (collection !== selection$$1) {
31421 schedule(collection, transform);
31423 selection$$1.interrupt().each(function() {
31424 gesture(this, arguments)
31426 .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform)
31432 zoom.scaleBy = function(selection$$1, k) {
31433 zoom.scaleTo(selection$$1, function() {
31434 var k0 = this.__zoom.k,
31435 k1 = typeof k === "function" ? k.apply(this, arguments) : k;
31440 zoom.scaleTo = function(selection$$1, k) {
31441 zoom.transform(selection$$1, function() {
31442 var e = extent.apply(this, arguments),
31445 p1 = t0.invert(p0),
31446 k1 = typeof k === "function" ? k.apply(this, arguments) : k;
31447 return constrain(translate(scale(t0, k1), p0, p1), e);
31451 zoom.translateBy = function(selection$$1, x, y) {
31452 zoom.transform(selection$$1, function() {
31453 return constrain(this.__zoom.translate(
31454 typeof x === "function" ? x.apply(this, arguments) : x,
31455 typeof y === "function" ? y.apply(this, arguments) : y
31456 ), extent.apply(this, arguments));
31460 function scale(transform, k) {
31461 k = Math.max(k0, Math.min(k1, k));
31462 return k === transform.k ? transform : new Transform(k, transform.x, transform.y);
31465 function translate(transform, p0, p1) {
31466 var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k;
31467 return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y);
31470 function constrain(transform, extent) {
31471 var dx0 = transform.invertX(extent[0][0]) - x0,
31472 dx1 = transform.invertX(extent[1][0]) - x1,
31473 dy0 = transform.invertY(extent[0][1]) - y0,
31474 dy1 = transform.invertY(extent[1][1]) - y1;
31475 return transform.translate(
31476 dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
31477 dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
31481 function centroid(extent) {
31482 return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
31485 function schedule(transition$$1, transform, center) {
31487 .on("start.zoom", function() { gesture(this, arguments).start(); })
31488 .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
31489 .tween("zoom", function() {
31492 g = gesture(that, args),
31493 e = extent.apply(that, args),
31494 p = center || centroid(e),
31495 w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
31497 b = typeof transform === "function" ? transform.apply(that, args) : transform,
31498 i = interpolate$$1(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
31499 return function(t) {
31500 if (t === 1) t = b; // Avoid rounding error on end.
31501 else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
31507 function gesture(that, args) {
31508 for (var i = 0, n = gestures.length, g; i < n; ++i) {
31509 if ((g = gestures[i]).that === that) {
31513 return new Gesture(that, args);
31516 function Gesture(that, args) {
31521 this.extent = extent.apply(that, args);
31524 Gesture.prototype = {
31525 start: function() {
31526 if (++this.active === 1) {
31527 this.index = gestures.push(this) - 1;
31528 this.emit("start");
31532 zoom: function(key, transform) {
31533 if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]);
31534 if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]);
31535 if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]);
31536 this.that.__zoom = transform;
31541 if (--this.active === 0) {
31542 gestures.splice(this.index, 1);
31548 emit: function(type) {
31549 customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
31553 function wheeled() {
31554 if (!filter.apply(this, arguments)) return;
31555 var g = gesture(this, arguments),
31557 k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -event.deltaY * (event.deltaMode ? 120 : 1) / 500))),
31560 // If the mouse is in the same location as before, reuse it.
31561 // If there were recent wheel events, reset the wheel idle timeout.
31563 if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
31564 g.mouse[1] = t.invert(g.mouse[0] = p);
31566 clearTimeout(g.wheel);
31569 // If this wheel event won’t trigger a transform change, ignore it.
31570 else if (t.k === k) return;
31572 // Otherwise, capture the mouse point and location at the start.
31574 g.mouse = [p, t.invert(p)];
31580 g.wheel = setTimeout(wheelidled, wheelDelay);
31581 g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent));
31583 function wheelidled() {
31589 function mousedowned() {
31590 if (touchending || !filter.apply(this, arguments)) return;
31591 var g = gesture(this, arguments),
31592 v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
31595 dragDisable(event.view);
31597 g.mouse = [p, this.__zoom.invert(p)];
31601 function mousemoved() {
31604 g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent));
31607 function mouseupped() {
31608 v.on("mousemove.zoom mouseup.zoom", null);
31609 yesdrag(event.view, g.moved);
31615 function dblclicked() {
31616 if (!filter.apply(this, arguments)) return;
31617 var t0 = this.__zoom,
31619 p1 = t0.invert(p0),
31620 k1 = t0.k * (event.shiftKey ? 0.5 : 2),
31621 t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments));
31624 if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);
31625 else select(this).call(zoom.transform, t1);
31628 function touchstarted() {
31629 if (!filter.apply(this, arguments)) return;
31630 var g = gesture(this, arguments),
31631 touches$$1 = event.changedTouches,
31632 n = touches$$1.length, i, t, p;
31635 for (i = 0; i < n; ++i) {
31636 t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
31637 p = [p, this.__zoom.invert(p), t.identifier];
31638 if (!g.touch0) g.touch0 = p;
31639 else if (!g.touch1) g.touch1 = p;
31642 // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
31643 if (touchstarting) {
31644 touchstarting = clearTimeout(touchstarting);
31647 p = select(this).on("dblclick.zoom");
31648 if (p) p.apply(this, arguments);
31653 if (event.touches.length === n) {
31654 touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
31660 function touchmoved() {
31661 var g = gesture(this, arguments),
31662 touches$$1 = event.changedTouches,
31663 n = touches$$1.length, i, t, p, l;
31666 if (touchstarting) touchstarting = clearTimeout(touchstarting);
31667 for (i = 0; i < n; ++i) {
31668 t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
31669 if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
31670 else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
31674 var p0 = g.touch0[0], l0 = g.touch0[1],
31675 p1 = g.touch1[0], l1 = g.touch1[1],
31676 dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
31677 dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
31678 t = scale(t, Math.sqrt(dp / dl));
31679 p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
31680 l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
31682 else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
31684 g.zoom("touch", constrain(translate(t, p, l), g.extent));
31687 function touchended() {
31688 var g = gesture(this, arguments),
31689 touches$$1 = event.changedTouches,
31690 n = touches$$1.length, i, t;
31693 if (touchending) clearTimeout(touchending);
31694 touchending = setTimeout(function() { touchending = null; }, touchDelay);
31695 for (i = 0; i < n; ++i) {
31697 if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
31698 else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
31700 if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
31701 if (!g.touch0) g.end();
31704 zoom.filter = function(_) {
31705 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$10(!!_), zoom) : filter;
31708 zoom.extent = function(_) {
31709 return arguments.length ? (extent = typeof _ === "function" ? _ : constant$10([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
31712 zoom.scaleExtent = function(_) {
31713 return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1];
31716 zoom.translateExtent = function(_) {
31717 return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]];
31720 zoom.duration = function(_) {
31721 return arguments.length ? (duration = +_, zoom) : duration;
31724 zoom.interpolate = function(_) {
31725 return arguments.length ? (interpolate$$1 = _, zoom) : interpolate$$1;
31728 zoom.on = function() {
31729 var value = listeners.on.apply(listeners, arguments);
31730 return value === listeners ? zoom : value;
31736 var constant$11 = function(x) {
31737 return function() {
31742 var BrushEvent = function(target, type, selection) {
31743 this.target = target;
31745 this.selection = selection;
31748 function nopropagation$2() {
31749 event.stopImmediatePropagation();
31752 var noevent$2 = function() {
31753 event.preventDefault();
31754 event.stopImmediatePropagation();
31757 var MODE_DRAG = {name: "drag"};
31758 var MODE_SPACE = {name: "space"};
31759 var MODE_HANDLE = {name: "handle"};
31760 var MODE_CENTER = {name: "center"};
31764 handles: ["e", "w"].map(type$3),
31765 input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
31766 output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
31771 handles: ["n", "s"].map(type$3),
31772 input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
31773 output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
31778 handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type$3),
31779 input: function(xy) { return xy; },
31780 output: function(xy) { return xy; }
31784 overlay: "crosshair",
31840 function type$3(t) {
31844 // Ignore right-click, since that should open the context menu.
31845 function defaultFilter$2() {
31846 return !event.button;
31849 function defaultExtent$1() {
31850 var svg = this.ownerSVGElement || this;
31851 return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
31854 // Like d3.local, but with the name “__brush” rather than auto-generated.
31855 function local$1(node) {
31856 while (!node.__brush) if (!(node = node.parentNode)) return;
31857 return node.__brush;
31860 function empty$1(extent) {
31861 return extent[0][0] === extent[1][0]
31862 || extent[0][1] === extent[1][1];
31865 function brushSelection(node) {
31866 var state = node.__brush;
31867 return state ? state.dim.output(state.selection) : null;
31870 function brushX() {
31874 function brushY() {
31878 var brush = function() {
31879 return brush$1(XY);
31882 function brush$1(dim) {
31883 var extent = defaultExtent$1,
31884 filter = defaultFilter$2,
31885 listeners = dispatch(brush, "start", "brush", "end"),
31889 function brush(group) {
31890 var overlay = group
31891 .property("__brush", initialize)
31892 .selectAll(".overlay")
31893 .data([type$3("overlay")]);
31895 overlay.enter().append("rect")
31896 .attr("class", "overlay")
31897 .attr("pointer-events", "all")
31898 .attr("cursor", cursors.overlay)
31901 var extent = local$1(this).extent;
31903 .attr("x", extent[0][0])
31904 .attr("y", extent[0][1])
31905 .attr("width", extent[1][0] - extent[0][0])
31906 .attr("height", extent[1][1] - extent[0][1]);
31909 group.selectAll(".selection")
31910 .data([type$3("selection")])
31911 .enter().append("rect")
31912 .attr("class", "selection")
31913 .attr("cursor", cursors.selection)
31914 .attr("fill", "#777")
31915 .attr("fill-opacity", 0.3)
31916 .attr("stroke", "#fff")
31917 .attr("shape-rendering", "crispEdges");
31919 var handle = group.selectAll(".handle")
31920 .data(dim.handles, function(d) { return d.type; });
31922 handle.exit().remove();
31924 handle.enter().append("rect")
31925 .attr("class", function(d) { return "handle handle--" + d.type; })
31926 .attr("cursor", function(d) { return cursors[d.type]; });
31930 .attr("fill", "none")
31931 .attr("pointer-events", "all")
31932 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
31933 .on("mousedown.brush touchstart.brush", started);
31936 brush.move = function(group, selection$$1) {
31937 if (group.selection) {
31939 .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
31940 .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
31941 .tween("brush", function() {
31943 state = that.__brush,
31944 emit = emitter(that, arguments),
31945 selection0 = state.selection,
31946 selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(this, arguments) : selection$$1, state.extent),
31947 i = interpolate(selection0, selection1);
31949 function tween(t) {
31950 state.selection = t === 1 && empty$1(selection1) ? null : i(t);
31955 return selection0 && selection1 ? tween : tween(1);
31962 state = that.__brush,
31963 selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(that, args) : selection$$1, state.extent),
31964 emit = emitter(that, args).beforestart();
31967 state.selection = selection1 == null || empty$1(selection1) ? null : selection1;
31969 emit.start().brush().end();
31974 function redraw() {
31975 var group = select(this),
31976 selection$$1 = local$1(this).selection;
31978 if (selection$$1) {
31979 group.selectAll(".selection")
31980 .style("display", null)
31981 .attr("x", selection$$1[0][0])
31982 .attr("y", selection$$1[0][1])
31983 .attr("width", selection$$1[1][0] - selection$$1[0][0])
31984 .attr("height", selection$$1[1][1] - selection$$1[0][1]);
31986 group.selectAll(".handle")
31987 .style("display", null)
31988 .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; })
31989 .attr("y", function(d) { return d.type[0] === "s" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; })
31990 .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; })
31991 .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; });
31995 group.selectAll(".selection,.handle")
31996 .style("display", "none")
31999 .attr("width", null)
32000 .attr("height", null);
32004 function emitter(that, args) {
32005 return that.__brush.emitter || new Emitter(that, args);
32008 function Emitter(that, args) {
32011 this.state = that.__brush;
32015 Emitter.prototype = {
32016 beforestart: function() {
32017 if (++this.active === 1) this.state.emitter = this, this.starting = true;
32020 start: function() {
32021 if (this.starting) this.starting = false, this.emit("start");
32024 brush: function() {
32025 this.emit("brush");
32029 if (--this.active === 0) delete this.state.emitter, this.emit("end");
32032 emit: function(type) {
32033 customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
32037 function started() {
32038 if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$2(); }
32039 else if (touchending) return;
32040 if (!filter.apply(this, arguments)) return;
32043 type = event.target.__data__.type,
32044 mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
32045 signX = dim === Y ? null : signsX[type],
32046 signY = dim === X ? null : signsY[type],
32047 state = local$1(that),
32048 extent = state.extent,
32049 selection$$1 = state.selection,
32050 W = extent[0][0], w0, w1,
32051 N = extent[0][1], n0, n1,
32052 E = extent[1][0], e0, e1,
32053 S = extent[1][1], s0, s1,
32057 shifting = signX && signY && event.shiftKey,
32060 point0 = mouse(that),
32062 emit = emitter(that, arguments).beforestart();
32064 if (type === "overlay") {
32065 state.selection = selection$$1 = [
32066 [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
32067 [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
32070 w0 = selection$$1[0][0];
32071 n0 = selection$$1[0][1];
32072 e0 = selection$$1[1][0];
32073 s0 = selection$$1[1][1];
32081 var group = select(that)
32082 .attr("pointer-events", "none");
32084 var overlay = group.selectAll(".overlay")
32085 .attr("cursor", cursors[type]);
32087 if (event.touches) {
32089 .on("touchmove.brush", moved, true)
32090 .on("touchend.brush touchcancel.brush", ended, true);
32092 var view = select(event.view)
32093 .on("keydown.brush", keydowned, true)
32094 .on("keyup.brush", keyupped, true)
32095 .on("mousemove.brush", moved, true)
32096 .on("mouseup.brush", ended, true);
32098 dragDisable(event.view);
32107 var point1 = mouse(that);
32108 if (shifting && !lockX && !lockY) {
32109 if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
32121 dx = point[0] - point0[0];
32122 dy = point[1] - point0[1];
32127 if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
32128 if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
32131 case MODE_HANDLE: {
32132 if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
32133 else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
32134 if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
32135 else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
32138 case MODE_CENTER: {
32139 if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
32140 if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
32147 t = w0, w0 = e0, e0 = t;
32148 t = w1, w1 = e1, e1 = t;
32149 if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
32154 t = n0, n0 = s0, s0 = t;
32155 t = n1, n1 = s1, s1 = t;
32156 if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
32159 if (state.selection) selection$$1 = state.selection; // May be set by brush.move!
32160 if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0];
32161 if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1];
32163 if (selection$$1[0][0] !== w1
32164 || selection$$1[0][1] !== n1
32165 || selection$$1[1][0] !== e1
32166 || selection$$1[1][1] !== s1) {
32167 state.selection = [[w1, n1], [e1, s1]];
32175 if (event.touches) {
32176 if (event.touches.length) return;
32177 if (touchending) clearTimeout(touchending);
32178 touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
32179 group.on("touchmove.brush touchend.brush touchcancel.brush", null);
32181 yesdrag(event.view, moving);
32182 view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
32184 group.attr("pointer-events", "all");
32185 overlay.attr("cursor", cursors.overlay);
32186 if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)!
32187 if (empty$1(selection$$1)) state.selection = null, redraw.call(that);
32191 function keydowned() {
32192 switch (event.keyCode) {
32193 case 16: { // SHIFT
32194 shifting = signX && signY;
32198 if (mode === MODE_HANDLE) {
32199 if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
32200 if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
32201 mode = MODE_CENTER;
32206 case 32: { // SPACE; takes priority over ALT
32207 if (mode === MODE_HANDLE || mode === MODE_CENTER) {
32208 if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
32209 if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
32211 overlay.attr("cursor", cursors.selection);
32221 function keyupped() {
32222 switch (event.keyCode) {
32223 case 16: { // SHIFT
32225 lockX = lockY = shifting = false;
32231 if (mode === MODE_CENTER) {
32232 if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
32233 if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
32234 mode = MODE_HANDLE;
32239 case 32: { // SPACE
32240 if (mode === MODE_SPACE) {
32241 if (event.altKey) {
32242 if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
32243 if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
32244 mode = MODE_CENTER;
32246 if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
32247 if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
32248 mode = MODE_HANDLE;
32250 overlay.attr("cursor", cursors[type]);
32261 function initialize() {
32262 var state = this.__brush || {selection: null};
32263 state.extent = extent.apply(this, arguments);
32268 brush.extent = function(_) {
32269 return arguments.length ? (extent = typeof _ === "function" ? _ : constant$11([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
32272 brush.filter = function(_) {
32273 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$11(!!_), brush) : filter;
32276 brush.handleSize = function(_) {
32277 return arguments.length ? (handleSize = +_, brush) : handleSize;
32280 brush.on = function() {
32281 var value = listeners.on.apply(listeners, arguments);
32282 return value === listeners ? brush : value;
32288 var cos = Math.cos;
32289 var sin = Math.sin;
32290 var pi$3 = Math.PI;
32291 var halfPi$2 = pi$3 / 2;
32292 var tau$3 = pi$3 * 2;
32293 var max$1 = Math.max;
32295 function compareValue(compare) {
32296 return function(a, b) {
32298 a.source.value + a.target.value,
32299 b.source.value + b.target.value
32304 var chord = function() {
32307 sortSubgroups = null,
32310 function chord(matrix) {
32311 var n = matrix.length,
32313 groupIndex = range(n),
32314 subgroupIndex = [],
32316 groups = chords.groups = new Array(n),
32317 subgroups = new Array(n * n),
32325 // Compute the sum.
32326 k = 0, i = -1; while (++i < n) {
32327 x = 0, j = -1; while (++j < n) {
32331 subgroupIndex.push(range(n));
32336 if (sortGroups) groupIndex.sort(function(a, b) {
32337 return sortGroups(groupSums[a], groupSums[b]);
32341 if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
32342 d.sort(function(a, b) {
32343 return sortSubgroups(matrix[i][a], matrix[i][b]);
32347 // Convert the sum to scaling factor for [0, 2pi].
32348 // TODO Allow start and end angle to be specified?
32349 // TODO Allow padding to be specified as percentage?
32350 k = max$1(0, tau$3 - padAngle * n) / k;
32351 dx = k ? padAngle : tau$3 / n;
32353 // Compute the start and end angle for each group and subgroup.
32354 // Note: Opera has a bug reordering object literal properties!
32355 x = 0, i = -1; while (++i < n) {
32356 x0 = x, j = -1; while (++j < n) {
32357 var di = groupIndex[i],
32358 dj = subgroupIndex[di][j],
32359 v = matrix[di][dj],
32362 subgroups[dj * n + di] = {
32374 value: groupSums[di]
32379 // Generate chords for each (non-empty) subgroup-subgroup link.
32380 i = -1; while (++i < n) {
32381 j = i - 1; while (++j < n) {
32382 var source = subgroups[j * n + i],
32383 target = subgroups[i * n + j];
32384 if (source.value || target.value) {
32385 chords.push(source.value < target.value
32386 ? {source: target, target: source}
32387 : {source: source, target: target});
32392 return sortChords ? chords.sort(sortChords) : chords;
32395 chord.padAngle = function(_) {
32396 return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
32399 chord.sortGroups = function(_) {
32400 return arguments.length ? (sortGroups = _, chord) : sortGroups;
32403 chord.sortSubgroups = function(_) {
32404 return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
32407 chord.sortChords = function(_) {
32408 return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
32414 var slice$5 = Array.prototype.slice;
32416 var constant$12 = function(x) {
32417 return function() {
32422 function defaultSource(d) {
32426 function defaultTarget(d) {
32430 function defaultRadius$1(d) {
32434 function defaultStartAngle(d) {
32435 return d.startAngle;
32438 function defaultEndAngle(d) {
32442 var ribbon = function() {
32443 var source = defaultSource,
32444 target = defaultTarget,
32445 radius = defaultRadius$1,
32446 startAngle = defaultStartAngle,
32447 endAngle = defaultEndAngle,
32450 function ribbon() {
32452 argv = slice$5.call(arguments),
32453 s = source.apply(this, argv),
32454 t = target.apply(this, argv),
32455 sr = +radius.apply(this, (argv[0] = s, argv)),
32456 sa0 = startAngle.apply(this, argv) - halfPi$2,
32457 sa1 = endAngle.apply(this, argv) - halfPi$2,
32458 sx0 = sr * cos(sa0),
32459 sy0 = sr * sin(sa0),
32460 tr = +radius.apply(this, (argv[0] = t, argv)),
32461 ta0 = startAngle.apply(this, argv) - halfPi$2,
32462 ta1 = endAngle.apply(this, argv) - halfPi$2;
32464 if (!context) context = buffer = path();
32466 context.moveTo(sx0, sy0);
32467 context.arc(0, 0, sr, sa0, sa1);
32468 if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
32469 context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
32470 context.arc(0, 0, tr, ta0, ta1);
32472 context.quadraticCurveTo(0, 0, sx0, sy0);
32473 context.closePath();
32475 if (buffer) return context = null, buffer + "" || null;
32478 ribbon.radius = function(_) {
32479 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$12(+_), ribbon) : radius;
32482 ribbon.startAngle = function(_) {
32483 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$12(+_), ribbon) : startAngle;
32486 ribbon.endAngle = function(_) {
32487 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$12(+_), ribbon) : endAngle;
32490 ribbon.source = function(_) {
32491 return arguments.length ? (source = _, ribbon) : source;
32494 ribbon.target = function(_) {
32495 return arguments.length ? (target = _, ribbon) : target;
32498 ribbon.context = function(_) {
32499 return arguments.length ? ((context = _ == null ? null : _), ribbon) : context;
32505 // Adds floating point numbers with twice the normal precision.
32506 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
32507 // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
32509 // Code adapted from GeographicLib by Charles F. F. Karney,
32510 // http://geographiclib.sourceforge.net/
32512 var adder = function() {
32520 Adder.prototype = {
32521 constructor: Adder,
32522 reset: function() {
32523 this.s = // rounded value
32524 this.t = 0; // exact error
32527 add$1(temp, y, this.t);
32528 add$1(this, temp.s, this.s);
32529 if (this.s) this.t += temp.t;
32530 else this.s = temp.t;
32532 valueOf: function() {
32537 var temp = new Adder;
32539 function add$1(adder, a, b) {
32540 var x = adder.s = a + b,
32543 adder.t = (a - av) + (b - bv);
32546 var epsilon$4 = 1e-6;
32547 var epsilon2$2 = 1e-12;
32548 var pi$4 = Math.PI;
32549 var halfPi$3 = pi$4 / 2;
32550 var quarterPi = pi$4 / 4;
32551 var tau$4 = pi$4 * 2;
32553 var degrees$1 = 180 / pi$4;
32554 var radians = pi$4 / 180;
32556 var abs = Math.abs;
32557 var atan = Math.atan;
32558 var atan2 = Math.atan2;
32559 var cos$1 = Math.cos;
32560 var ceil = Math.ceil;
32561 var exp = Math.exp;
32563 var log$1 = Math.log;
32564 var pow$1 = Math.pow;
32565 var sin$1 = Math.sin;
32566 var sign$1 = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
32567 var sqrt$1 = Math.sqrt;
32568 var tan = Math.tan;
32571 return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
32574 function asin$1(x) {
32575 return x > 1 ? halfPi$3 : x < -1 ? -halfPi$3 : Math.asin(x);
32578 function haversin(x) {
32579 return (x = sin$1(x / 2)) * x;
32582 function noop$2() {}
32584 function streamGeometry(geometry, stream) {
32585 if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
32586 streamGeometryType[geometry.type](geometry, stream);
32590 var streamObjectType = {
32591 Feature: function(feature, stream) {
32592 streamGeometry(feature.geometry, stream);
32594 FeatureCollection: function(object, stream) {
32595 var features = object.features, i = -1, n = features.length;
32596 while (++i < n) streamGeometry(features[i].geometry, stream);
32600 var streamGeometryType = {
32601 Sphere: function(object, stream) {
32604 Point: function(object, stream) {
32605 object = object.coordinates;
32606 stream.point(object[0], object[1], object[2]);
32608 MultiPoint: function(object, stream) {
32609 var coordinates = object.coordinates, i = -1, n = coordinates.length;
32610 while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
32612 LineString: function(object, stream) {
32613 streamLine(object.coordinates, stream, 0);
32615 MultiLineString: function(object, stream) {
32616 var coordinates = object.coordinates, i = -1, n = coordinates.length;
32617 while (++i < n) streamLine(coordinates[i], stream, 0);
32619 Polygon: function(object, stream) {
32620 streamPolygon(object.coordinates, stream);
32622 MultiPolygon: function(object, stream) {
32623 var coordinates = object.coordinates, i = -1, n = coordinates.length;
32624 while (++i < n) streamPolygon(coordinates[i], stream);
32626 GeometryCollection: function(object, stream) {
32627 var geometries = object.geometries, i = -1, n = geometries.length;
32628 while (++i < n) streamGeometry(geometries[i], stream);
32632 function streamLine(coordinates, stream, closed) {
32633 var i = -1, n = coordinates.length - closed, coordinate;
32634 stream.lineStart();
32635 while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
32639 function streamPolygon(coordinates, stream) {
32640 var i = -1, n = coordinates.length;
32641 stream.polygonStart();
32642 while (++i < n) streamLine(coordinates[i], stream, 1);
32643 stream.polygonEnd();
32646 var geoStream = function(object, stream) {
32647 if (object && streamObjectType.hasOwnProperty(object.type)) {
32648 streamObjectType[object.type](object, stream);
32650 streamGeometry(object, stream);
32654 var areaRingSum = adder();
32656 var areaSum = adder();
32667 polygonStart: function() {
32668 areaRingSum.reset();
32669 areaStream.lineStart = areaRingStart;
32670 areaStream.lineEnd = areaRingEnd;
32672 polygonEnd: function() {
32673 var areaRing = +areaRingSum;
32674 areaSum.add(areaRing < 0 ? tau$4 + areaRing : areaRing);
32675 this.lineStart = this.lineEnd = this.point = noop$2;
32677 sphere: function() {
32678 areaSum.add(tau$4);
32682 function areaRingStart() {
32683 areaStream.point = areaPointFirst;
32686 function areaRingEnd() {
32687 areaPoint(lambda00, phi00);
32690 function areaPointFirst(lambda, phi) {
32691 areaStream.point = areaPoint;
32692 lambda00 = lambda, phi00 = phi;
32693 lambda *= radians, phi *= radians;
32694 lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
32697 function areaPoint(lambda, phi) {
32698 lambda *= radians, phi *= radians;
32699 phi = phi / 2 + quarterPi; // half the angular distance from south pole
32701 // Spherical excess E for a spherical triangle with vertices: south pole,
32702 // previous point, current point. Uses a formula derived from Cagnoli’s
32703 // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
32704 var dLambda = lambda - lambda0,
32705 sdLambda = dLambda >= 0 ? 1 : -1,
32706 adLambda = sdLambda * dLambda,
32707 cosPhi = cos$1(phi),
32708 sinPhi = sin$1(phi),
32709 k = sinPhi0 * sinPhi,
32710 u = cosPhi0 * cosPhi + k * cos$1(adLambda),
32711 v = k * sdLambda * sin$1(adLambda);
32712 areaRingSum.add(atan2(v, u));
32714 // Advance the previous points.
32715 lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
32718 var area$1 = function(object) {
32720 geoStream(object, areaStream);
32721 return areaSum * 2;
32724 function spherical(cartesian) {
32725 return [atan2(cartesian[1], cartesian[0]), asin$1(cartesian[2])];
32728 function cartesian(spherical) {
32729 var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
32730 return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
32733 function cartesianDot(a, b) {
32734 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
32737 function cartesianCross(a, b) {
32738 return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
32742 function cartesianAddInPlace(a, b) {
32743 a[0] += b[0], a[1] += b[1], a[2] += b[2];
32746 function cartesianScale(vector, k) {
32747 return [vector[0] * k, vector[1] * k, vector[2] * k];
32751 function cartesianNormalizeInPlace(d) {
32752 var l = sqrt$1(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
32753 d[0] /= l, d[1] /= l, d[2] /= l;
32764 var deltaSum = adder();
32768 var boundsStream = {
32769 point: boundsPoint,
32770 lineStart: boundsLineStart,
32771 lineEnd: boundsLineEnd,
32772 polygonStart: function() {
32773 boundsStream.point = boundsRingPoint;
32774 boundsStream.lineStart = boundsRingStart;
32775 boundsStream.lineEnd = boundsRingEnd;
32777 areaStream.polygonStart();
32779 polygonEnd: function() {
32780 areaStream.polygonEnd();
32781 boundsStream.point = boundsPoint;
32782 boundsStream.lineStart = boundsLineStart;
32783 boundsStream.lineEnd = boundsLineEnd;
32784 if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
32785 else if (deltaSum > epsilon$4) phi1 = 90;
32786 else if (deltaSum < -epsilon$4) phi0 = -90;
32787 range$1[0] = lambda0$1, range$1[1] = lambda1;
32791 function boundsPoint(lambda, phi) {
32792 ranges.push(range$1 = [lambda0$1 = lambda, lambda1 = lambda]);
32793 if (phi < phi0) phi0 = phi;
32794 if (phi > phi1) phi1 = phi;
32797 function linePoint(lambda, phi) {
32798 var p = cartesian([lambda * radians, phi * radians]);
32800 var normal = cartesianCross(p0, p),
32801 equatorial = [normal[1], -normal[0], 0],
32802 inflection = cartesianCross(equatorial, normal);
32803 cartesianNormalizeInPlace(inflection);
32804 inflection = spherical(inflection);
32805 var delta = lambda - lambda2,
32806 sign$$1 = delta > 0 ? 1 : -1,
32807 lambdai = inflection[0] * degrees$1 * sign$$1,
32809 antimeridian = abs(delta) > 180;
32810 if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
32811 phii = inflection[1] * degrees$1;
32812 if (phii > phi1) phi1 = phii;
32813 } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
32814 phii = -inflection[1] * degrees$1;
32815 if (phii < phi0) phi0 = phii;
32817 if (phi < phi0) phi0 = phi;
32818 if (phi > phi1) phi1 = phi;
32820 if (antimeridian) {
32821 if (lambda < lambda2) {
32822 if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
32824 if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
32827 if (lambda1 >= lambda0$1) {
32828 if (lambda < lambda0$1) lambda0$1 = lambda;
32829 if (lambda > lambda1) lambda1 = lambda;
32831 if (lambda > lambda2) {
32832 if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
32834 if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
32839 boundsPoint(lambda, phi);
32841 p0 = p, lambda2 = lambda;
32844 function boundsLineStart() {
32845 boundsStream.point = linePoint;
32848 function boundsLineEnd() {
32849 range$1[0] = lambda0$1, range$1[1] = lambda1;
32850 boundsStream.point = boundsPoint;
32854 function boundsRingPoint(lambda, phi) {
32856 var delta = lambda - lambda2;
32857 deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
32859 lambda00$1 = lambda, phi00$1 = phi;
32861 areaStream.point(lambda, phi);
32862 linePoint(lambda, phi);
32865 function boundsRingStart() {
32866 areaStream.lineStart();
32869 function boundsRingEnd() {
32870 boundsRingPoint(lambda00$1, phi00$1);
32871 areaStream.lineEnd();
32872 if (abs(deltaSum) > epsilon$4) lambda0$1 = -(lambda1 = 180);
32873 range$1[0] = lambda0$1, range$1[1] = lambda1;
32877 // Finds the left-right distance between two longitudes.
32878 // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
32879 // the distance between ±180° to be 360°.
32880 function angle(lambda0, lambda1) {
32881 return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
32884 function rangeCompare(a, b) {
32885 return a[0] - b[0];
32888 function rangeContains(range, x) {
32889 return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
32892 var bounds = function(feature) {
32893 var i, n, a, b, merged, deltaMax, delta;
32895 phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
32897 geoStream(feature, boundsStream);
32899 // First, sort ranges by their minimum longitudes.
32900 if (n = ranges.length) {
32901 ranges.sort(rangeCompare);
32903 // Then, merge any ranges that overlap.
32904 for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
32906 if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
32907 if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
32908 if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
32910 merged.push(a = b);
32914 // Finally, find the largest gap between the merged ranges.
32915 // The final bounding box will be the inverse of this gap.
32916 for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
32918 if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
32922 ranges = range$1 = null;
32924 return lambda0$1 === Infinity || phi0 === Infinity
32925 ? [[NaN, NaN], [NaN, NaN]]
32926 : [[lambda0$1, phi0], [lambda1, phi1]];
32944 var z0; // previous point
32946 var centroidStream = {
32948 point: centroidPoint,
32949 lineStart: centroidLineStart,
32950 lineEnd: centroidLineEnd,
32951 polygonStart: function() {
32952 centroidStream.lineStart = centroidRingStart;
32953 centroidStream.lineEnd = centroidRingEnd;
32955 polygonEnd: function() {
32956 centroidStream.lineStart = centroidLineStart;
32957 centroidStream.lineEnd = centroidLineEnd;
32961 // Arithmetic mean of Cartesian vectors.
32962 function centroidPoint(lambda, phi) {
32963 lambda *= radians, phi *= radians;
32964 var cosPhi = cos$1(phi);
32965 centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
32968 function centroidPointCartesian(x, y, z) {
32970 X0 += (x - X0) / W0;
32971 Y0 += (y - Y0) / W0;
32972 Z0 += (z - Z0) / W0;
32975 function centroidLineStart() {
32976 centroidStream.point = centroidLinePointFirst;
32979 function centroidLinePointFirst(lambda, phi) {
32980 lambda *= radians, phi *= radians;
32981 var cosPhi = cos$1(phi);
32982 x0 = cosPhi * cos$1(lambda);
32983 y0 = cosPhi * sin$1(lambda);
32985 centroidStream.point = centroidLinePoint;
32986 centroidPointCartesian(x0, y0, z0);
32989 function centroidLinePoint(lambda, phi) {
32990 lambda *= radians, phi *= radians;
32991 var cosPhi = cos$1(phi),
32992 x = cosPhi * cos$1(lambda),
32993 y = cosPhi * sin$1(lambda),
32995 w = atan2(sqrt$1((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
32997 X1 += w * (x0 + (x0 = x));
32998 Y1 += w * (y0 + (y0 = y));
32999 Z1 += w * (z0 + (z0 = z));
33000 centroidPointCartesian(x0, y0, z0);
33003 function centroidLineEnd() {
33004 centroidStream.point = centroidPoint;
33007 // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
33008 // J. Applied Mechanics 42, 239 (1975).
33009 function centroidRingStart() {
33010 centroidStream.point = centroidRingPointFirst;
33013 function centroidRingEnd() {
33014 centroidRingPoint(lambda00$2, phi00$2);
33015 centroidStream.point = centroidPoint;
33018 function centroidRingPointFirst(lambda, phi) {
33019 lambda00$2 = lambda, phi00$2 = phi;
33020 lambda *= radians, phi *= radians;
33021 centroidStream.point = centroidRingPoint;
33022 var cosPhi = cos$1(phi);
33023 x0 = cosPhi * cos$1(lambda);
33024 y0 = cosPhi * sin$1(lambda);
33026 centroidPointCartesian(x0, y0, z0);
33029 function centroidRingPoint(lambda, phi) {
33030 lambda *= radians, phi *= radians;
33031 var cosPhi = cos$1(phi),
33032 x = cosPhi * cos$1(lambda),
33033 y = cosPhi * sin$1(lambda),
33035 cx = y0 * z - z0 * y,
33036 cy = z0 * x - x0 * z,
33037 cz = x0 * y - y0 * x,
33038 m = sqrt$1(cx * cx + cy * cy + cz * cz),
33039 u = x0 * x + y0 * y + z0 * z,
33040 v = m && -acos(u) / m, // area weight
33041 w = atan2(m, u); // line weight
33046 X1 += w * (x0 + (x0 = x));
33047 Y1 += w * (y0 + (y0 = y));
33048 Z1 += w * (z0 + (z0 = z));
33049 centroidPointCartesian(x0, y0, z0);
33052 var d3GeoCentroid = function(object) {
33057 geoStream(object, centroidStream);
33062 m = x * x + y * y + z * z;
33064 // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
33065 if (m < epsilon2$2) {
33066 x = X1, y = Y1, z = Z1;
33067 // If the feature has zero length, fall back to arithmetic mean of point vectors.
33068 if (W1 < epsilon$4) x = X0, y = Y0, z = Z0;
33069 m = x * x + y * y + z * z;
33070 // If the feature still has an undefined ccentroid, then return.
33071 if (m < epsilon2$2) return [NaN, NaN];
33074 return [atan2(y, x) * degrees$1, asin$1(z / sqrt$1(m)) * degrees$1];
33077 var constant$13 = function(x) {
33078 return function() {
33083 var compose = function(a, b) {
33085 function compose(x, y) {
33086 return x = a(x, y), b(x[0], x[1]);
33089 if (a.invert && b.invert) compose.invert = function(x, y) {
33090 return x = b.invert(x, y), x && a.invert(x[0], x[1]);
33096 function rotationIdentity(lambda, phi) {
33097 return [lambda > pi$4 ? lambda - tau$4 : lambda < -pi$4 ? lambda + tau$4 : lambda, phi];
33100 rotationIdentity.invert = rotationIdentity;
33102 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
33103 return (deltaLambda %= tau$4) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
33104 : rotationLambda(deltaLambda))
33105 : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
33106 : rotationIdentity);
33109 function forwardRotationLambda(deltaLambda) {
33110 return function(lambda, phi) {
33111 return lambda += deltaLambda, [lambda > pi$4 ? lambda - tau$4 : lambda < -pi$4 ? lambda + tau$4 : lambda, phi];
33115 function rotationLambda(deltaLambda) {
33116 var rotation = forwardRotationLambda(deltaLambda);
33117 rotation.invert = forwardRotationLambda(-deltaLambda);
33121 function rotationPhiGamma(deltaPhi, deltaGamma) {
33122 var cosDeltaPhi = cos$1(deltaPhi),
33123 sinDeltaPhi = sin$1(deltaPhi),
33124 cosDeltaGamma = cos$1(deltaGamma),
33125 sinDeltaGamma = sin$1(deltaGamma);
33127 function rotation(lambda, phi) {
33128 var cosPhi = cos$1(phi),
33129 x = cos$1(lambda) * cosPhi,
33130 y = sin$1(lambda) * cosPhi,
33132 k = z * cosDeltaPhi + x * sinDeltaPhi;
33134 atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
33135 asin$1(k * cosDeltaGamma + y * sinDeltaGamma)
33139 rotation.invert = function(lambda, phi) {
33140 var cosPhi = cos$1(phi),
33141 x = cos$1(lambda) * cosPhi,
33142 y = sin$1(lambda) * cosPhi,
33144 k = z * cosDeltaGamma - y * sinDeltaGamma;
33146 atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
33147 asin$1(k * cosDeltaPhi - x * sinDeltaPhi)
33154 var rotation = function(rotate) {
33155 rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
33157 function forward(coordinates) {
33158 coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
33159 return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
33162 forward.invert = function(coordinates) {
33163 coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
33164 return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
33170 // Generates a circle centered at [0°, 0°], with a given radius and precision.
33171 function circleStream(stream, radius, delta, direction, t0, t1) {
33172 if (!delta) return;
33173 var cosRadius = cos$1(radius),
33174 sinRadius = sin$1(radius),
33175 step = direction * delta;
33177 t0 = radius + direction * tau$4;
33178 t1 = radius - step / 2;
33180 t0 = circleRadius(cosRadius, t0);
33181 t1 = circleRadius(cosRadius, t1);
33182 if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$4;
33184 for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
33185 point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
33186 stream.point(point[0], point[1]);
33190 // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
33191 function circleRadius(cosRadius, point) {
33192 point = cartesian(point), point[0] -= cosRadius;
33193 cartesianNormalizeInPlace(point);
33194 var radius = acos(-point[1]);
33195 return ((-point[2] < 0 ? -radius : radius) + tau$4 - epsilon$4) % tau$4;
33198 var circle$1 = function() {
33199 var center = constant$13([0, 0]),
33200 radius = constant$13(90),
33201 precision = constant$13(6),
33204 stream = {point: point};
33206 function point(x, y) {
33207 ring.push(x = rotate(x, y));
33208 x[0] *= degrees$1, x[1] *= degrees$1;
33211 function circle() {
33212 var c = center.apply(this, arguments),
33213 r = radius.apply(this, arguments) * radians,
33214 p = precision.apply(this, arguments) * radians;
33216 rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
33217 circleStream(stream, r, p, 1);
33218 c = {type: "Polygon", coordinates: [ring]};
33219 ring = rotate = null;
33223 circle.center = function(_) {
33224 return arguments.length ? (center = typeof _ === "function" ? _ : constant$13([+_[0], +_[1]]), circle) : center;
33227 circle.radius = function(_) {
33228 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$13(+_), circle) : radius;
33231 circle.precision = function(_) {
33232 return arguments.length ? (precision = typeof _ === "function" ? _ : constant$13(+_), circle) : precision;
33238 var clipBuffer = function() {
33242 point: function(x, y) {
33245 lineStart: function() {
33246 lines.push(line = []);
33249 rejoin: function() {
33250 if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
33252 result: function() {
33253 var result = lines;
33261 var clipLine = function(a, b, x0, y0, x1, y1) {
33273 if (!dx && r > 0) return;
33276 if (r < t0) return;
33277 if (r < t1) t1 = r;
33278 } else if (dx > 0) {
33279 if (r > t1) return;
33280 if (r > t0) t0 = r;
33284 if (!dx && r < 0) return;
33287 if (r > t1) return;
33288 if (r > t0) t0 = r;
33289 } else if (dx > 0) {
33290 if (r < t0) return;
33291 if (r < t1) t1 = r;
33295 if (!dy && r > 0) return;
33298 if (r < t0) return;
33299 if (r < t1) t1 = r;
33300 } else if (dy > 0) {
33301 if (r > t1) return;
33302 if (r > t0) t0 = r;
33306 if (!dy && r < 0) return;
33309 if (r > t1) return;
33310 if (r > t0) t0 = r;
33311 } else if (dy > 0) {
33312 if (r < t0) return;
33313 if (r < t1) t1 = r;
33316 if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
33317 if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
33321 var pointEqual = function(a, b) {
33322 return abs(a[0] - b[0]) < epsilon$4 && abs(a[1] - b[1]) < epsilon$4;
33325 function Intersection(point, points, other, entry) {
33328 this.o = other; // another intersection
33329 this.e = entry; // is an entry?
33330 this.v = false; // visited
33331 this.n = this.p = null; // next & previous
33334 // A generalized polygon clipping algorithm: given a polygon that has been cut
33335 // into its visible line segments, and rejoins the segments by interpolating
33336 // along the clip edge.
33337 var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) {
33343 segments.forEach(function(segment) {
33344 if ((n = segment.length - 1) <= 0) return;
33345 var n, p0 = segment[0], p1 = segment[n], x;
33347 // If the first and last points of a segment are coincident, then treat as a
33348 // closed ring. TODO if all rings are closed, then the winding order of the
33349 // exterior ring should be checked.
33350 if (pointEqual(p0, p1)) {
33351 stream.lineStart();
33352 for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
33357 subject.push(x = new Intersection(p0, segment, null, true));
33358 clip.push(x.o = new Intersection(p0, null, x, false));
33359 subject.push(x = new Intersection(p1, segment, null, false));
33360 clip.push(x.o = new Intersection(p1, null, x, true));
33363 if (!subject.length) return;
33365 clip.sort(compareIntersection);
33369 for (i = 0, n = clip.length; i < n; ++i) {
33370 clip[i].e = startInside = !startInside;
33373 var start = subject[0],
33378 // Find first unvisited intersection.
33379 var current = start,
33381 while (current.v) if ((current = current.n) === start) return;
33382 points = current.z;
33383 stream.lineStart();
33385 current.v = current.o.v = true;
33388 for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
33390 interpolate(current.x, current.n.x, 1, stream);
33392 current = current.n;
33395 points = current.p.z;
33396 for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
33398 interpolate(current.x, current.p.x, -1, stream);
33400 current = current.p;
33402 current = current.o;
33403 points = current.z;
33404 isSubject = !isSubject;
33405 } while (!current.v);
33410 function link$1(array) {
33411 if (!(n = array.length)) return;
33417 a.n = b = array[i];
33421 a.n = b = array[0];
33426 var clipMin = -clipMax;
33428 // TODO Use d3-polygon’s polygonContains here for the ring check?
33429 // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
33431 function clipExtent(x0, y0, x1, y1) {
33433 function visible(x, y) {
33434 return x0 <= x && x <= x1 && y0 <= y && y <= y1;
33437 function interpolate(from, to, direction, stream) {
33440 || (a = corner(from, direction)) !== (a1 = corner(to, direction))
33441 || comparePoint(from, to) < 0 ^ direction > 0) {
33442 do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
33443 while ((a = (a + direction + 4) % 4) !== a1);
33445 stream.point(to[0], to[1]);
33449 function corner(p, direction) {
33450 return abs(p[0] - x0) < epsilon$4 ? direction > 0 ? 0 : 3
33451 : abs(p[0] - x1) < epsilon$4 ? direction > 0 ? 2 : 1
33452 : abs(p[1] - y0) < epsilon$4 ? direction > 0 ? 1 : 0
33453 : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
33456 function compareIntersection(a, b) {
33457 return comparePoint(a.x, b.x);
33460 function comparePoint(a, b) {
33461 var ca = corner(a, 1),
33463 return ca !== cb ? ca - cb
33464 : ca === 0 ? b[1] - a[1]
33465 : ca === 1 ? a[0] - b[0]
33466 : ca === 2 ? a[1] - b[1]
33470 return function(stream) {
33471 var activeStream = stream,
33472 bufferStream = clipBuffer(),
33476 x__, y__, v__, // first point
33477 x_, y_, v_, // previous point
33483 lineStart: lineStart,
33485 polygonStart: polygonStart,
33486 polygonEnd: polygonEnd
33489 function point(x, y) {
33490 if (visible(x, y)) activeStream.point(x, y);
33493 function polygonInside() {
33496 for (var i = 0, n = polygon.length; i < n; ++i) {
33497 for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
33498 a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
33499 if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
33500 else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
33507 // Buffer geometry within a polygon and then clip it en masse.
33508 function polygonStart() {
33509 activeStream = bufferStream, segments = [], polygon = [], clean = true;
33512 function polygonEnd() {
33513 var startInside = polygonInside(),
33514 cleanInside = clean && startInside,
33515 visible = (segments = merge(segments)).length;
33516 if (cleanInside || visible) {
33517 stream.polygonStart();
33519 stream.lineStart();
33520 interpolate(null, null, 1, stream);
33524 clipPolygon(segments, compareIntersection, startInside, interpolate, stream);
33526 stream.polygonEnd();
33528 activeStream = stream, segments = polygon = ring = null;
33531 function lineStart() {
33532 clipStream.point = linePoint;
33533 if (polygon) polygon.push(ring = []);
33539 // TODO rather than special-case polygons, simply handle them separately.
33540 // Ideally, coincident intersection points should be jittered to avoid
33541 // clipping issues.
33542 function lineEnd() {
33544 linePoint(x__, y__);
33545 if (v__ && v_) bufferStream.rejoin();
33546 segments.push(bufferStream.result());
33548 clipStream.point = point;
33549 if (v_) activeStream.lineEnd();
33552 function linePoint(x, y) {
33553 var v = visible(x, y);
33554 if (polygon) ring.push([x, y]);
33556 x__ = x, y__ = y, v__ = v;
33559 activeStream.lineStart();
33560 activeStream.point(x, y);
33563 if (v && v_) activeStream.point(x, y);
33565 var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
33566 b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
33567 if (clipLine(a, b, x0, y0, x1, y1)) {
33569 activeStream.lineStart();
33570 activeStream.point(a[0], a[1]);
33572 activeStream.point(b[0], b[1]);
33573 if (!v) activeStream.lineEnd();
33576 activeStream.lineStart();
33577 activeStream.point(x, y);
33582 x_ = x, y_ = y, v_ = v;
33589 var extent$1 = function() {
33599 stream: function(stream) {
33600 return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream);
33602 extent: function(_) {
33603 return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
33608 var lengthSum = adder();
33613 var lengthStream = {
33616 lineStart: lengthLineStart,
33618 polygonStart: noop$2,
33622 function lengthLineStart() {
33623 lengthStream.point = lengthPointFirst;
33624 lengthStream.lineEnd = lengthLineEnd;
33627 function lengthLineEnd() {
33628 lengthStream.point = lengthStream.lineEnd = noop$2;
33631 function lengthPointFirst(lambda, phi) {
33632 lambda *= radians, phi *= radians;
33633 lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
33634 lengthStream.point = lengthPoint;
33637 function lengthPoint(lambda, phi) {
33638 lambda *= radians, phi *= radians;
33639 var sinPhi = sin$1(phi),
33640 cosPhi = cos$1(phi),
33641 delta = abs(lambda - lambda0$2),
33642 cosDelta = cos$1(delta),
33643 sinDelta = sin$1(delta),
33644 x = cosPhi * sinDelta,
33645 y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
33646 z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
33647 lengthSum.add(atan2(sqrt$1(x * x + y * y), z));
33648 lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
33651 var d3GeoLength = function(object) {
33653 geoStream(object, lengthStream);
33657 var coordinates = [null, null];
33658 var object$1 = {type: "LineString", coordinates: coordinates};
33660 var distance = function(a, b) {
33661 coordinates[0] = a;
33662 coordinates[1] = b;
33663 return d3GeoLength(object$1);
33666 function graticuleX(y0, y1, dy) {
33667 var y = range(y0, y1 - epsilon$4, dy).concat(y1);
33668 return function(x) { return y.map(function(y) { return [x, y]; }); };
33671 function graticuleY(x0, x1, dx) {
33672 var x = range(x0, x1 - epsilon$4, dx).concat(x1);
33673 return function(y) { return x.map(function(x) { return [x, y]; }); };
33676 function graticule() {
33677 var x1, x0, X1, X0,
33679 dx = 10, dy = dx, DX = 90, DY = 360,
33683 function graticule() {
33684 return {type: "MultiLineString", coordinates: lines()};
33688 return range(ceil(X0 / DX) * DX, X1, DX).map(X)
33689 .concat(range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
33690 .concat(range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$4; }).map(x))
33691 .concat(range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$4; }).map(y));
33694 graticule.lines = function() {
33695 return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
33698 graticule.outline = function() {
33704 X(X1).reverse().slice(1),
33705 Y(Y0).reverse().slice(1))
33710 graticule.extent = function(_) {
33711 if (!arguments.length) return graticule.extentMinor();
33712 return graticule.extentMajor(_).extentMinor(_);
33715 graticule.extentMajor = function(_) {
33716 if (!arguments.length) return [[X0, Y0], [X1, Y1]];
33717 X0 = +_[0][0], X1 = +_[1][0];
33718 Y0 = +_[0][1], Y1 = +_[1][1];
33719 if (X0 > X1) _ = X0, X0 = X1, X1 = _;
33720 if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
33721 return graticule.precision(precision);
33724 graticule.extentMinor = function(_) {
33725 if (!arguments.length) return [[x0, y0], [x1, y1]];
33726 x0 = +_[0][0], x1 = +_[1][0];
33727 y0 = +_[0][1], y1 = +_[1][1];
33728 if (x0 > x1) _ = x0, x0 = x1, x1 = _;
33729 if (y0 > y1) _ = y0, y0 = y1, y1 = _;
33730 return graticule.precision(precision);
33733 graticule.step = function(_) {
33734 if (!arguments.length) return graticule.stepMinor();
33735 return graticule.stepMajor(_).stepMinor(_);
33738 graticule.stepMajor = function(_) {
33739 if (!arguments.length) return [DX, DY];
33740 DX = +_[0], DY = +_[1];
33744 graticule.stepMinor = function(_) {
33745 if (!arguments.length) return [dx, dy];
33746 dx = +_[0], dy = +_[1];
33750 graticule.precision = function(_) {
33751 if (!arguments.length) return precision;
33753 x = graticuleX(y0, y1, 90);
33754 y = graticuleY(x0, x1, precision);
33755 X = graticuleX(Y0, Y1, 90);
33756 Y = graticuleY(X0, X1, precision);
33761 .extentMajor([[-180, -90 + epsilon$4], [180, 90 - epsilon$4]])
33762 .extentMinor([[-180, -80 - epsilon$4], [180, 80 + epsilon$4]]);
33765 function graticule10() {
33766 return graticule()();
33769 var interpolate$2 = function(a, b) {
33770 var x0 = a[0] * radians,
33771 y0 = a[1] * radians,
33772 x1 = b[0] * radians,
33773 y1 = b[1] * radians,
33778 kx0 = cy0 * cos$1(x0),
33779 ky0 = cy0 * sin$1(x0),
33780 kx1 = cy1 * cos$1(x1),
33781 ky1 = cy1 * sin$1(x1),
33782 d = 2 * asin$1(sqrt$1(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
33785 var interpolate = d ? function(t) {
33786 var B = sin$1(t *= d) / k,
33787 A = sin$1(d - t) / k,
33788 x = A * kx0 + B * kx1,
33789 y = A * ky0 + B * ky1,
33790 z = A * sy0 + B * sy1;
33792 atan2(y, x) * degrees$1,
33793 atan2(z, sqrt$1(x * x + y * y)) * degrees$1
33796 return [x0 * degrees$1, y0 * degrees$1];
33799 interpolate.distance = d;
33801 return interpolate;
33804 var identity$7 = function(x) {
33808 var areaSum$1 = adder();
33809 var areaRingSum$1 = adder();
33815 var areaStream$1 = {
33819 polygonStart: function() {
33820 areaStream$1.lineStart = areaRingStart$1;
33821 areaStream$1.lineEnd = areaRingEnd$1;
33823 polygonEnd: function() {
33824 areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$2;
33825 areaSum$1.add(abs(areaRingSum$1));
33826 areaRingSum$1.reset();
33828 result: function() {
33829 var area = areaSum$1 / 2;
33835 function areaRingStart$1() {
33836 areaStream$1.point = areaPointFirst$1;
33839 function areaPointFirst$1(x, y) {
33840 areaStream$1.point = areaPoint$1;
33841 x00 = x0$1 = x, y00 = y0$1 = y;
33844 function areaPoint$1(x, y) {
33845 areaRingSum$1.add(y0$1 * x - x0$1 * y);
33846 x0$1 = x, y0$1 = y;
33849 function areaRingEnd$1() {
33850 areaPoint$1(x00, y00);
33853 var x0$2 = Infinity;
33858 var boundsStream$1 = {
33859 point: boundsPoint$1,
33862 polygonStart: noop$2,
33863 polygonEnd: noop$2,
33864 result: function() {
33865 var bounds = [[x0$2, y0$2], [x1, y1]];
33866 x1 = y1 = -(y0$2 = x0$2 = Infinity);
33871 function boundsPoint$1(x, y) {
33872 if (x < x0$2) x0$2 = x;
33873 if (x > x1) x1 = x;
33874 if (y < y0$2) y0$2 = y;
33875 if (y > y1) y1 = y;
33878 // TODO Enforce positive area for exterior, negative area for interior?
33894 var centroidStream$1 = {
33895 point: centroidPoint$1,
33896 lineStart: centroidLineStart$1,
33897 lineEnd: centroidLineEnd$1,
33898 polygonStart: function() {
33899 centroidStream$1.lineStart = centroidRingStart$1;
33900 centroidStream$1.lineEnd = centroidRingEnd$1;
33902 polygonEnd: function() {
33903 centroidStream$1.point = centroidPoint$1;
33904 centroidStream$1.lineStart = centroidLineStart$1;
33905 centroidStream$1.lineEnd = centroidLineEnd$1;
33907 result: function() {
33908 var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
33909 : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
33910 : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
33912 X0$1 = Y0$1 = Z0$1 =
33913 X1$1 = Y1$1 = Z1$1 =
33914 X2$1 = Y2$1 = Z2$1 = 0;
33919 function centroidPoint$1(x, y) {
33925 function centroidLineStart$1() {
33926 centroidStream$1.point = centroidPointFirstLine;
33929 function centroidPointFirstLine(x, y) {
33930 centroidStream$1.point = centroidPointLine;
33931 centroidPoint$1(x0$3 = x, y0$3 = y);
33934 function centroidPointLine(x, y) {
33935 var dx = x - x0$3, dy = y - y0$3, z = sqrt$1(dx * dx + dy * dy);
33936 X1$1 += z * (x0$3 + x) / 2;
33937 Y1$1 += z * (y0$3 + y) / 2;
33939 centroidPoint$1(x0$3 = x, y0$3 = y);
33942 function centroidLineEnd$1() {
33943 centroidStream$1.point = centroidPoint$1;
33946 function centroidRingStart$1() {
33947 centroidStream$1.point = centroidPointFirstRing;
33950 function centroidRingEnd$1() {
33951 centroidPointRing(x00$1, y00$1);
33954 function centroidPointFirstRing(x, y) {
33955 centroidStream$1.point = centroidPointRing;
33956 centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
33959 function centroidPointRing(x, y) {
33962 z = sqrt$1(dx * dx + dy * dy);
33964 X1$1 += z * (x0$3 + x) / 2;
33965 Y1$1 += z * (y0$3 + y) / 2;
33968 z = y0$3 * x - x0$3 * y;
33969 X2$1 += z * (x0$3 + x);
33970 Y2$1 += z * (y0$3 + y);
33972 centroidPoint$1(x0$3 = x, y0$3 = y);
33975 function PathContext(context) {
33976 this._context = context;
33979 PathContext.prototype = {
33981 pointRadius: function(_) {
33982 return this._radius = _, this;
33984 polygonStart: function() {
33987 polygonEnd: function() {
33990 lineStart: function() {
33993 lineEnd: function() {
33994 if (this._line === 0) this._context.closePath();
33997 point: function(x, y) {
33998 switch (this._point) {
34000 this._context.moveTo(x, y);
34005 this._context.lineTo(x, y);
34009 this._context.moveTo(x + this._radius, y);
34010 this._context.arc(x, y, this._radius, 0, tau$4);
34018 function PathString() {
34022 PathString.prototype = {
34023 _circle: circle$2(4.5),
34024 pointRadius: function(_) {
34025 return this._circle = circle$2(_), this;
34027 polygonStart: function() {
34030 polygonEnd: function() {
34033 lineStart: function() {
34036 lineEnd: function() {
34037 if (this._line === 0) this._string.push("Z");
34040 point: function(x, y) {
34041 switch (this._point) {
34043 this._string.push("M", x, ",", y);
34048 this._string.push("L", x, ",", y);
34052 this._string.push("M", x, ",", y, this._circle);
34057 result: function() {
34058 if (this._string.length) {
34059 var result = this._string.join("");
34066 function circle$2(radius) {
34067 return "m0," + radius
34068 + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
34069 + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
34073 var index$5 = function(projection, context) {
34074 var pointRadius = 4.5,
34078 function path(object) {
34080 if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
34081 geoStream(object, projectionStream(contextStream));
34083 return contextStream.result();
34086 path.area = function(object) {
34087 geoStream(object, projectionStream(areaStream$1));
34088 return areaStream$1.result();
34091 path.bounds = function(object) {
34092 geoStream(object, projectionStream(boundsStream$1));
34093 return boundsStream$1.result();
34096 path.centroid = function(object) {
34097 geoStream(object, projectionStream(centroidStream$1));
34098 return centroidStream$1.result();
34101 path.projection = function(_) {
34102 return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$7) : (projection = _).stream, path) : projection;
34105 path.context = function(_) {
34106 if (!arguments.length) return context;
34107 contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
34108 if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
34112 path.pointRadius = function(_) {
34113 if (!arguments.length) return pointRadius;
34114 pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
34118 return path.projection(projection).context(context);
34121 var sum$2 = adder();
34123 var polygonContains = function(polygon, point) {
34124 var lambda = point[0],
34126 normal = [sin$1(lambda), -cos$1(lambda), 0],
34132 for (var i = 0, n = polygon.length; i < n; ++i) {
34133 if (!(m = (ring = polygon[i]).length)) continue;
34136 point0 = ring[m - 1],
34137 lambda0 = point0[0],
34138 phi0 = point0[1] / 2 + quarterPi,
34139 sinPhi0 = sin$1(phi0),
34140 cosPhi0 = cos$1(phi0);
34142 for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
34143 var point1 = ring[j],
34144 lambda1 = point1[0],
34145 phi1 = point1[1] / 2 + quarterPi,
34146 sinPhi1 = sin$1(phi1),
34147 cosPhi1 = cos$1(phi1),
34148 delta = lambda1 - lambda0,
34149 sign$$1 = delta >= 0 ? 1 : -1,
34150 absDelta = sign$$1 * delta,
34151 antimeridian = absDelta > pi$4,
34152 k = sinPhi0 * sinPhi1;
34154 sum$2.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
34155 angle += antimeridian ? delta + sign$$1 * tau$4 : delta;
34157 // Are the longitudes either side of the point’s meridian (lambda),
34158 // and are the latitudes smaller than the parallel (phi)?
34159 if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
34160 var arc = cartesianCross(cartesian(point0), cartesian(point1));
34161 cartesianNormalizeInPlace(arc);
34162 var intersection = cartesianCross(normal, arc);
34163 cartesianNormalizeInPlace(intersection);
34164 var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin$1(intersection[2]);
34165 if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
34166 winding += antimeridian ^ delta >= 0 ? 1 : -1;
34172 // First, determine whether the South pole is inside or outside:
34174 // It is inside if:
34175 // * the polygon winds around it in a clockwise direction.
34176 // * the polygon does not (cumulatively) wind around it, but has a negative
34177 // (counter-clockwise) area.
34179 // Second, count the (signed) number of times a segment crosses a lambda
34180 // from the point to the South pole. If it is zero, then the point is the
34181 // same side as the South pole.
34183 return (angle < -epsilon$4 || angle < epsilon$4 && sum$2 < -epsilon$4) ^ (winding & 1);
34186 var clip = function(pointVisible, clipLine, interpolate, start) {
34187 return function(rotate, sink) {
34188 var line = clipLine(sink),
34189 rotatedStart = rotate.invert(start[0], start[1]),
34190 ringBuffer = clipBuffer(),
34191 ringSink = clipLine(ringBuffer),
34192 polygonStarted = false,
34199 lineStart: lineStart,
34201 polygonStart: function() {
34202 clip.point = pointRing;
34203 clip.lineStart = ringStart;
34204 clip.lineEnd = ringEnd;
34208 polygonEnd: function() {
34209 clip.point = point;
34210 clip.lineStart = lineStart;
34211 clip.lineEnd = lineEnd;
34212 segments = merge(segments);
34213 var startInside = polygonContains(polygon, rotatedStart);
34214 if (segments.length) {
34215 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
34216 clipPolygon(segments, compareIntersection, startInside, interpolate, sink);
34217 } else if (startInside) {
34218 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
34220 interpolate(null, null, 1, sink);
34223 if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
34224 segments = polygon = null;
34226 sphere: function() {
34227 sink.polygonStart();
34229 interpolate(null, null, 1, sink);
34235 function point(lambda, phi) {
34236 var point = rotate(lambda, phi);
34237 if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);
34240 function pointLine(lambda, phi) {
34241 var point = rotate(lambda, phi);
34242 line.point(point[0], point[1]);
34245 function lineStart() {
34246 clip.point = pointLine;
34250 function lineEnd() {
34251 clip.point = point;
34255 function pointRing(lambda, phi) {
34256 ring.push([lambda, phi]);
34257 var point = rotate(lambda, phi);
34258 ringSink.point(point[0], point[1]);
34261 function ringStart() {
34262 ringSink.lineStart();
34266 function ringEnd() {
34267 pointRing(ring[0][0], ring[0][1]);
34268 ringSink.lineEnd();
34270 var clean = ringSink.clean(),
34271 ringSegments = ringBuffer.result(),
34272 i, n = ringSegments.length, m,
34277 polygon.push(ring);
34282 // No intersections.
34284 segment = ringSegments[0];
34285 if ((m = segment.length - 1) > 0) {
34286 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
34288 for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
34294 // Rejoin connected segments.
34295 // TODO reuse ringBuffer.rejoin()?
34296 if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
34298 segments.push(ringSegments.filter(validSegment));
34305 function validSegment(segment) {
34306 return segment.length > 1;
34309 // Intersections are sorted along the clip edge. For both antimeridian cutting
34310 // and circle clipping, the same comparison is used.
34311 function compareIntersection(a, b) {
34312 return ((a = a.x)[0] < 0 ? a[1] - halfPi$3 - epsilon$4 : halfPi$3 - a[1])
34313 - ((b = b.x)[0] < 0 ? b[1] - halfPi$3 - epsilon$4 : halfPi$3 - b[1]);
34316 var clipAntimeridian = clip(
34317 function() { return true; },
34318 clipAntimeridianLine,
34319 clipAntimeridianInterpolate,
34323 // Takes a line and cuts into visible segments. Return values: 0 - there were
34324 // intersections or the line was empty; 1 - no intersections; 2 - there were
34325 // intersections, and the first and last segments should be rejoined.
34326 function clipAntimeridianLine(stream) {
34330 clean; // no intersections
34333 lineStart: function() {
34334 stream.lineStart();
34337 point: function(lambda1, phi1) {
34338 var sign1 = lambda1 > 0 ? pi$4 : -pi$4,
34339 delta = abs(lambda1 - lambda0);
34340 if (abs(delta - pi$4) < epsilon$4) { // line crosses a pole
34341 stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$3 : -halfPi$3);
34342 stream.point(sign0, phi0);
34344 stream.lineStart();
34345 stream.point(sign1, phi0);
34346 stream.point(lambda1, phi0);
34348 } else if (sign0 !== sign1 && delta >= pi$4) { // line crosses antimeridian
34349 if (abs(lambda0 - sign0) < epsilon$4) lambda0 -= sign0 * epsilon$4; // handle degeneracies
34350 if (abs(lambda1 - sign1) < epsilon$4) lambda1 -= sign1 * epsilon$4;
34351 phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
34352 stream.point(sign0, phi0);
34354 stream.lineStart();
34355 stream.point(sign1, phi0);
34358 stream.point(lambda0 = lambda1, phi0 = phi1);
34361 lineEnd: function() {
34363 lambda0 = phi0 = NaN;
34365 clean: function() {
34366 return 2 - clean; // if intersections, rejoin first and last segments
34371 function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
34374 sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
34375 return abs(sinLambda0Lambda1) > epsilon$4
34376 ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
34377 - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
34378 / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
34379 : (phi0 + phi1) / 2;
34382 function clipAntimeridianInterpolate(from, to, direction, stream) {
34384 if (from == null) {
34385 phi = direction * halfPi$3;
34386 stream.point(-pi$4, phi);
34387 stream.point(0, phi);
34388 stream.point(pi$4, phi);
34389 stream.point(pi$4, 0);
34390 stream.point(pi$4, -phi);
34391 stream.point(0, -phi);
34392 stream.point(-pi$4, -phi);
34393 stream.point(-pi$4, 0);
34394 stream.point(-pi$4, phi);
34395 } else if (abs(from[0] - to[0]) > epsilon$4) {
34396 var lambda = from[0] < to[0] ? pi$4 : -pi$4;
34397 phi = direction * lambda / 2;
34398 stream.point(-lambda, phi);
34399 stream.point(0, phi);
34400 stream.point(lambda, phi);
34402 stream.point(to[0], to[1]);
34406 var clipCircle = function(radius, delta) {
34407 var cr = cos$1(radius),
34408 smallRadius = cr > 0,
34409 notHemisphere = abs(cr) > epsilon$4; // TODO optimise for this common case
34411 function interpolate(from, to, direction, stream) {
34412 circleStream(stream, radius, delta, direction, from, to);
34415 function visible(lambda, phi) {
34416 return cos$1(lambda) * cos$1(phi) > cr;
34419 // Takes a line and cuts into visible segments. Return values used for polygon
34420 // clipping: 0 - there were intersections or the line was empty; 1 - no
34421 // intersections 2 - there were intersections, and the first and last segments
34422 // should be rejoined.
34423 function clipLine(stream) {
34424 var point0, // previous point
34425 c0, // code for previous point
34426 v0, // visibility of previous point
34427 v00, // visibility of first point
34428 clean; // no intersections
34430 lineStart: function() {
34434 point: function(lambda, phi) {
34435 var point1 = [lambda, phi],
34437 v = visible(lambda, phi),
34439 ? v ? 0 : code(lambda, phi)
34440 : v ? code(lambda + (lambda < 0 ? pi$4 : -pi$4), phi) : 0;
34441 if (!point0 && (v00 = v0 = v)) stream.lineStart();
34442 // Handle degeneracies.
34443 // TODO ignore if not clipping polygons.
34445 point2 = intersect(point0, point1);
34446 if (pointEqual(point0, point2) || pointEqual(point1, point2)) {
34447 point1[0] += epsilon$4;
34448 point1[1] += epsilon$4;
34449 v = visible(point1[0], point1[1]);
34455 // outside going in
34456 stream.lineStart();
34457 point2 = intersect(point1, point0);
34458 stream.point(point2[0], point2[1]);
34460 // inside going out
34461 point2 = intersect(point0, point1);
34462 stream.point(point2[0], point2[1]);
34466 } else if (notHemisphere && point0 && smallRadius ^ v) {
34468 // If the codes for two points are different, or are both zero,
34469 // and there this segment intersects with the small circle.
34470 if (!(c & c0) && (t = intersect(point1, point0, true))) {
34473 stream.lineStart();
34474 stream.point(t[0][0], t[0][1]);
34475 stream.point(t[1][0], t[1][1]);
34478 stream.point(t[1][0], t[1][1]);
34480 stream.lineStart();
34481 stream.point(t[0][0], t[0][1]);
34485 if (v && (!point0 || !pointEqual(point0, point1))) {
34486 stream.point(point1[0], point1[1]);
34488 point0 = point1, v0 = v, c0 = c;
34490 lineEnd: function() {
34491 if (v0) stream.lineEnd();
34494 // Rejoin first and last segments if there were intersections and the first
34495 // and last points were visible.
34496 clean: function() {
34497 return clean | ((v00 && v0) << 1);
34502 // Intersects the great circle between a and b with the clip circle.
34503 function intersect(a, b, two) {
34504 var pa = cartesian(a),
34507 // We have two planes, n1.p = d1 and n2.p = d2.
34508 // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
34509 var n1 = [1, 0, 0], // normal
34510 n2 = cartesianCross(pa, pb),
34511 n2n2 = cartesianDot(n2, n2),
34512 n1n2 = n2[0], // cartesianDot(n1, n2),
34513 determinant = n2n2 - n1n2 * n1n2;
34515 // Two polar points.
34516 if (!determinant) return !two && a;
34518 var c1 = cr * n2n2 / determinant,
34519 c2 = -cr * n1n2 / determinant,
34520 n1xn2 = cartesianCross(n1, n2),
34521 A = cartesianScale(n1, c1),
34522 B = cartesianScale(n2, c2);
34523 cartesianAddInPlace(A, B);
34525 // Solve |p(t)|^2 = 1.
34527 w = cartesianDot(A, u),
34528 uu = cartesianDot(u, u),
34529 t2 = w * w - uu * (cartesianDot(A, A) - 1);
34531 if (t2 < 0) return;
34533 var t = sqrt$1(t2),
34534 q = cartesianScale(u, (-w - t) / uu);
34535 cartesianAddInPlace(q, A);
34538 if (!two) return q;
34540 // Two intersection points.
34541 var lambda0 = a[0],
34547 if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
34549 var delta = lambda1 - lambda0,
34550 polar = abs(delta - pi$4) < epsilon$4,
34551 meridian = polar || delta < epsilon$4;
34553 if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
34555 // Check that the first point is between a and b.
34558 ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$4 ? phi0 : phi1)
34559 : phi0 <= q[1] && q[1] <= phi1
34560 : delta > pi$4 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
34561 var q1 = cartesianScale(u, (-w + t) / uu);
34562 cartesianAddInPlace(q1, A);
34563 return [q, spherical(q1)];
34567 // Generates a 4-bit vector representing the location of a point relative to
34568 // the small circle's bounding box.
34569 function code(lambda, phi) {
34570 var r = smallRadius ? radius : pi$4 - radius,
34572 if (lambda < -r) code |= 1; // left
34573 else if (lambda > r) code |= 2; // right
34574 if (phi < -r) code |= 4; // below
34575 else if (phi > r) code |= 8; // above
34579 return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$4, radius - pi$4]);
34582 var transform$1 = function(methods) {
34584 stream: transformer(methods)
34588 function transformer(methods) {
34589 return function(stream) {
34590 var s = new TransformStream;
34591 for (var key in methods) s[key] = methods[key];
34597 function TransformStream() {}
34599 TransformStream.prototype = {
34600 constructor: TransformStream,
34601 point: function(x, y) { this.stream.point(x, y); },
34602 sphere: function() { this.stream.sphere(); },
34603 lineStart: function() { this.stream.lineStart(); },
34604 lineEnd: function() { this.stream.lineEnd(); },
34605 polygonStart: function() { this.stream.polygonStart(); },
34606 polygonEnd: function() { this.stream.polygonEnd(); }
34609 function fitExtent(projection, extent, object) {
34610 var w = extent[1][0] - extent[0][0],
34611 h = extent[1][1] - extent[0][1],
34612 clip = projection.clipExtent && projection.clipExtent();
34616 .translate([0, 0]);
34618 if (clip != null) projection.clipExtent(null);
34620 geoStream(object, projection.stream(boundsStream$1));
34622 var b = boundsStream$1.result(),
34623 k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
34624 x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
34625 y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
34627 if (clip != null) projection.clipExtent(clip);
34631 .translate([x, y]);
34634 function fitSize(projection, size, object) {
34635 return fitExtent(projection, [[0, 0], size], object);
34639 var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
34641 var resample = function(project, delta2) {
34642 return +delta2 ? resample$1(project, delta2) : resampleNone(project);
34645 function resampleNone(project) {
34646 return transformer({
34647 point: function(x, y) {
34649 this.stream.point(x[0], x[1]);
34654 function resample$1(project, delta2) {
34656 function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
34659 d2 = dx * dx + dy * dy;
34660 if (d2 > 4 * delta2 && depth--) {
34664 m = sqrt$1(a * a + b * b + c * c),
34665 phi2 = asin$1(c /= m),
34666 lambda2 = abs(abs(c) - 1) < epsilon$4 || abs(lambda0 - lambda1) < epsilon$4 ? (lambda0 + lambda1) / 2 : atan2(b, a),
34667 p = project(lambda2, phi2),
34672 dz = dy * dx2 - dx * dy2;
34673 if (dz * dz / d2 > delta2 // perpendicular projected distance
34674 || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
34675 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
34676 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
34677 stream.point(x2, y2);
34678 resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
34682 return function(stream) {
34683 var lambda00, x00, y00, a00, b00, c00, // first point
34684 lambda0, x0, y0, a0, b0, c0; // previous point
34686 var resampleStream = {
34688 lineStart: lineStart,
34690 polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
34691 polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
34694 function point(x, y) {
34696 stream.point(x[0], x[1]);
34699 function lineStart() {
34701 resampleStream.point = linePoint;
34702 stream.lineStart();
34705 function linePoint(lambda, phi) {
34706 var c = cartesian([lambda, phi]), p = project(lambda, phi);
34707 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
34708 stream.point(x0, y0);
34711 function lineEnd() {
34712 resampleStream.point = point;
34716 function ringStart() {
34718 resampleStream.point = ringPoint;
34719 resampleStream.lineEnd = ringEnd;
34722 function ringPoint(lambda, phi) {
34723 linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
34724 resampleStream.point = linePoint;
34727 function ringEnd() {
34728 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
34729 resampleStream.lineEnd = lineEnd;
34733 return resampleStream;
34737 var transformRadians = transformer({
34738 point: function(x, y) {
34739 this.stream.point(x * radians, y * radians);
34743 function projection(project) {
34744 return projectionMutator(function() { return project; })();
34747 function projectionMutator(projectAt) {
34750 x = 480, y = 250, // translate
34751 dx, dy, lambda = 0, phi = 0, // center
34752 deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
34753 theta = null, preclip = clipAntimeridian, // clip angle
34754 x0 = null, y0, x1, y1, postclip = identity$7, // clip extent
34755 delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
34759 function projection(point) {
34760 point = projectRotate(point[0] * radians, point[1] * radians);
34761 return [point[0] * k + dx, dy - point[1] * k];
34764 function invert(point) {
34765 point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
34766 return point && [point[0] * degrees$1, point[1] * degrees$1];
34769 function projectTransform(x, y) {
34770 return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
34773 projection.stream = function(stream) {
34774 return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));
34777 projection.clipAngle = function(_) {
34778 return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
34781 projection.clipExtent = function(_) {
34782 return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$7) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
34785 projection.scale = function(_) {
34786 return arguments.length ? (k = +_, recenter()) : k;
34789 projection.translate = function(_) {
34790 return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
34793 projection.center = function(_) {
34794 return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
34797 projection.rotate = function(_) {
34798 return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1];
34801 projection.precision = function(_) {
34802 return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt$1(delta2);
34805 projection.fitExtent = function(extent, object) {
34806 return fitExtent(projection, extent, object);
34809 projection.fitSize = function(size, object) {
34810 return fitSize(projection, size, object);
34813 function recenter() {
34814 projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
34815 var center = project(lambda, phi);
34816 dx = x - center[0] * k;
34817 dy = y + center[1] * k;
34822 cache = cacheStream = null;
34826 return function() {
34827 project = projectAt.apply(this, arguments);
34828 projection.invert = project.invert && invert;
34833 function conicProjection(projectAt) {
34836 m = projectionMutator(projectAt),
34839 p.parallels = function(_) {
34840 return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
34846 function cylindricalEqualAreaRaw(phi0) {
34847 var cosPhi0 = cos$1(phi0);
34849 function forward(lambda, phi) {
34850 return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
34853 forward.invert = function(x, y) {
34854 return [x / cosPhi0, asin$1(y * cosPhi0)];
34860 function conicEqualAreaRaw(y0, y1) {
34861 var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
34863 // Are the parallels symmetrical around the Equator?
34864 if (abs(n) < epsilon$4) return cylindricalEqualAreaRaw(y0);
34866 var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt$1(c) / n;
34868 function project(x, y) {
34869 var r = sqrt$1(c - 2 * n * sin$1(y)) / n;
34870 return [r * sin$1(x *= n), r0 - r * cos$1(x)];
34873 project.invert = function(x, y) {
34875 return [atan2(x, abs(r0y)) / n * sign$1(r0y), asin$1((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
34881 var conicEqualArea = function() {
34882 return conicProjection(conicEqualAreaRaw)
34884 .center([0, 33.6442]);
34887 var albers = function() {
34888 return conicEqualArea()
34889 .parallels([29.5, 45.5])
34891 .translate([480, 250])
34893 .center([-0.6, 38.7]);
34896 // The projections must have mutually exclusive clip regions on the sphere,
34897 // as this will avoid emitting interleaving lines and polygons.
34898 function multiplex(streams) {
34899 var n = streams.length;
34901 point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
34902 sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
34903 lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
34904 lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
34905 polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
34906 polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
34910 // A composite projection for the United States, configured by default for
34911 // 960×500. The projection also works quite well at 960×600 if you change the
34912 // scale to 1285 and adjust the translate accordingly. The set of standard
34913 // parallels for each region comes from USGS, which is published here:
34914 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
34915 var albersUsa = function() {
34918 lower48 = albers(), lower48Point,
34919 alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
34920 hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
34921 point, pointStream = {point: function(x, y) { point = [x, y]; }};
34923 function albersUsa(coordinates) {
34924 var x = coordinates[0], y = coordinates[1];
34925 return point = null,
34926 (lower48Point.point(x, y), point)
34927 || (alaskaPoint.point(x, y), point)
34928 || (hawaiiPoint.point(x, y), point);
34931 albersUsa.invert = function(coordinates) {
34932 var k = lower48.scale(),
34933 t = lower48.translate(),
34934 x = (coordinates[0] - t[0]) / k,
34935 y = (coordinates[1] - t[1]) / k;
34936 return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
34937 : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
34938 : lower48).invert(coordinates);
34941 albersUsa.stream = function(stream) {
34942 return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
34945 albersUsa.precision = function(_) {
34946 if (!arguments.length) return lower48.precision();
34947 lower48.precision(_), alaska.precision(_), hawaii.precision(_);
34951 albersUsa.scale = function(_) {
34952 if (!arguments.length) return lower48.scale();
34953 lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
34954 return albersUsa.translate(lower48.translate());
34957 albersUsa.translate = function(_) {
34958 if (!arguments.length) return lower48.translate();
34959 var k = lower48.scale(), x = +_[0], y = +_[1];
34961 lower48Point = lower48
34963 .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
34964 .stream(pointStream);
34966 alaskaPoint = alaska
34967 .translate([x - 0.307 * k, y + 0.201 * k])
34968 .clipExtent([[x - 0.425 * k + epsilon$4, y + 0.120 * k + epsilon$4], [x - 0.214 * k - epsilon$4, y + 0.234 * k - epsilon$4]])
34969 .stream(pointStream);
34971 hawaiiPoint = hawaii
34972 .translate([x - 0.205 * k, y + 0.212 * k])
34973 .clipExtent([[x - 0.214 * k + epsilon$4, y + 0.166 * k + epsilon$4], [x - 0.115 * k - epsilon$4, y + 0.234 * k - epsilon$4]])
34974 .stream(pointStream);
34979 albersUsa.fitExtent = function(extent, object) {
34980 return fitExtent(albersUsa, extent, object);
34983 albersUsa.fitSize = function(size, object) {
34984 return fitSize(albersUsa, size, object);
34988 cache = cacheStream = null;
34992 return albersUsa.scale(1070);
34995 function azimuthalRaw(scale) {
34996 return function(x, y) {
34999 k = scale(cx * cy);
35007 function azimuthalInvert(angle) {
35008 return function(x, y) {
35009 var z = sqrt$1(x * x + y * y),
35014 atan2(x * sc, z * cc),
35015 asin$1(z && y * sc / z)
35020 var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
35021 return sqrt$1(2 / (1 + cxcy));
35024 azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
35025 return 2 * asin$1(z / 2);
35028 var azimuthalEqualArea = function() {
35029 return projection(azimuthalEqualAreaRaw)
35031 .clipAngle(180 - 1e-3);
35034 var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
35035 return (c = acos(c)) && c / sin$1(c);
35038 azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
35042 var azimuthalEquidistant = function() {
35043 return projection(azimuthalEquidistantRaw)
35045 .clipAngle(180 - 1e-3);
35048 function mercatorRaw(lambda, phi) {
35049 return [lambda, log$1(tan((halfPi$3 + phi) / 2))];
35052 mercatorRaw.invert = function(x, y) {
35053 return [x, 2 * atan(exp(y)) - halfPi$3];
35056 var mercator = function() {
35057 return mercatorProjection(mercatorRaw)
35058 .scale(961 / tau$4);
35061 function mercatorProjection(project) {
35062 var m = projection(project),
35064 translate = m.translate,
35065 clipExtent = m.clipExtent,
35068 m.scale = function(_) {
35069 return arguments.length ? (scale(_), clipAuto && m.clipExtent(null), m) : scale();
35072 m.translate = function(_) {
35073 return arguments.length ? (translate(_), clipAuto && m.clipExtent(null), m) : translate();
35076 m.clipExtent = function(_) {
35077 if (!arguments.length) return clipAuto ? null : clipExtent();
35078 if (clipAuto = _ == null) {
35079 var k = pi$4 * scale(),
35081 _ = [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]];
35087 return m.clipExtent(null);
35091 return tan((halfPi$3 + y) / 2);
35094 function conicConformalRaw(y0, y1) {
35095 var cy0 = cos$1(y0),
35096 n = y0 === y1 ? sin$1(y0) : log$1(cy0 / cos$1(y1)) / log$1(tany(y1) / tany(y0)),
35097 f = cy0 * pow$1(tany(y0), n) / n;
35099 if (!n) return mercatorRaw;
35101 function project(x, y) {
35102 if (f > 0) { if (y < -halfPi$3 + epsilon$4) y = -halfPi$3 + epsilon$4; }
35103 else { if (y > halfPi$3 - epsilon$4) y = halfPi$3 - epsilon$4; }
35104 var r = f / pow$1(tany(y), n);
35105 return [r * sin$1(n * x), f - r * cos$1(n * x)];
35108 project.invert = function(x, y) {
35109 var fy = f - y, r = sign$1(n) * sqrt$1(x * x + fy * fy);
35110 return [atan2(x, abs(fy)) / n * sign$1(fy), 2 * atan(pow$1(f / r, 1 / n)) - halfPi$3];
35116 var conicConformal = function() {
35117 return conicProjection(conicConformalRaw)
35119 .parallels([30, 30]);
35122 function equirectangularRaw(lambda, phi) {
35123 return [lambda, phi];
35126 equirectangularRaw.invert = equirectangularRaw;
35128 var equirectangular = function() {
35129 return projection(equirectangularRaw)
35133 function conicEquidistantRaw(y0, y1) {
35134 var cy0 = cos$1(y0),
35135 n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
35138 if (abs(n) < epsilon$4) return equirectangularRaw;
35140 function project(x, y) {
35141 var gy = g - y, nx = n * x;
35142 return [gy * sin$1(nx), g - gy * cos$1(nx)];
35145 project.invert = function(x, y) {
35147 return [atan2(x, abs(gy)) / n * sign$1(gy), g - sign$1(n) * sqrt$1(x * x + gy * gy)];
35153 var conicEquidistant = function() {
35154 return conicProjection(conicEquidistantRaw)
35156 .center([0, 13.9389]);
35159 function gnomonicRaw(x, y) {
35160 var cy = cos$1(y), k = cos$1(x) * cy;
35161 return [cy * sin$1(x) / k, sin$1(y) / k];
35164 gnomonicRaw.invert = azimuthalInvert(atan);
35166 var gnomonic = function() {
35167 return projection(gnomonicRaw)
35172 function scaleTranslate(kx, ky, tx, ty) {
35173 return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$7 : transformer({
35174 point: function(x, y) {
35175 this.stream.point(x * kx + tx, y * ky + ty);
35180 var identity$8 = function() {
35181 var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$7, // scale, translate and reflect
35182 x0 = null, y0, x1, y1, clip = identity$7, // clip extent
35188 cache = cacheStream = null;
35192 return projection = {
35193 stream: function(stream) {
35194 return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream));
35196 clipExtent: function(_) {
35197 return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$7) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
35199 scale: function(_) {
35200 return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;
35202 translate: function(_) {
35203 return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
35205 reflectX: function(_) {
35206 return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
35208 reflectY: function(_) {
35209 return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;
35211 fitExtent: function(extent, object) {
35212 return fitExtent(projection, extent, object);
35214 fitSize: function(size, object) {
35215 return fitSize(projection, size, object);
35220 function orthographicRaw(x, y) {
35221 return [cos$1(y) * sin$1(x), sin$1(y)];
35224 orthographicRaw.invert = azimuthalInvert(asin$1);
35226 var orthographic = function() {
35227 return projection(orthographicRaw)
35229 .clipAngle(90 + epsilon$4);
35232 function stereographicRaw(x, y) {
35233 var cy = cos$1(y), k = 1 + cos$1(x) * cy;
35234 return [cy * sin$1(x) / k, sin$1(y) / k];
35237 stereographicRaw.invert = azimuthalInvert(function(z) {
35238 return 2 * atan(z);
35241 var stereographic = function() {
35242 return projection(stereographicRaw)
35247 function transverseMercatorRaw(lambda, phi) {
35248 return [log$1(tan((halfPi$3 + phi) / 2)), -lambda];
35251 transverseMercatorRaw.invert = function(x, y) {
35252 return [-y, 2 * atan(exp(x)) - halfPi$3];
35255 var transverseMercator = function() {
35256 var m = mercatorProjection(transverseMercatorRaw),
35260 m.center = function(_) {
35261 return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
35264 m.rotate = function(_) {
35265 return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
35268 return rotate([0, 0, 90])
35274 var index$1 = Object.freeze({
35276 bisect: bisectRight,
35277 bisectRight: bisectRight,
35278 bisectLeft: bisectLeft,
35279 ascending: ascending,
35280 bisector: bisector,
35281 descending: descending,
35282 deviation: deviation,
35284 histogram: histogram,
35285 thresholdFreedmanDiaconis: freedmanDiaconis,
35286 thresholdScott: scott,
35287 thresholdSturges: sturges,
35295 quantile: threshold,
35301 tickStep: tickStep,
35302 transpose: transpose,
35303 variance: variance,
35311 randomUniform: uniform,
35312 randomNormal: normal,
35313 randomLogNormal: logNormal,
35314 randomBates: bates,
35315 randomIrwinHall: irwinHall,
35316 randomExponential: exponential,
35317 easeLinear: linear,
35318 easeQuad: quadInOut,
35319 easeQuadIn: quadIn,
35320 easeQuadOut: quadOut,
35321 easeQuadInOut: quadInOut,
35322 easeCubic: cubicInOut,
35323 easeCubicIn: cubicIn,
35324 easeCubicOut: cubicOut,
35325 easeCubicInOut: cubicInOut,
35326 easePoly: polyInOut,
35327 easePolyIn: polyIn,
35328 easePolyOut: polyOut,
35329 easePolyInOut: polyInOut,
35332 easeSinOut: sinOut,
35333 easeSinInOut: sinInOut,
35336 easeExpOut: expOut,
35337 easeExpInOut: expInOut,
35338 easeCircle: circleInOut,
35339 easeCircleIn: circleIn,
35340 easeCircleOut: circleOut,
35341 easeCircleInOut: circleInOut,
35342 easeBounce: bounceOut,
35343 easeBounceIn: bounceIn,
35344 easeBounceOut: bounceOut,
35345 easeBounceInOut: bounceInOut,
35346 easeBack: backInOut,
35347 easeBackIn: backIn,
35348 easeBackOut: backOut,
35349 easeBackInOut: backInOut,
35350 easeElastic: elasticOut,
35351 easeElasticIn: elasticIn,
35352 easeElasticOut: elasticOut,
35353 easeElasticInOut: elasticInOut,
35354 polygonArea: d3polygonArea,
35355 polygonCentroid: d3polygonCentroid,
35356 polygonHull: d3polygonHull,
35357 polygonContains: contains,
35358 polygonLength: length$1,
35360 quadtree: quadtree,
35366 radialArea: radialArea,
35367 radialLine: radialLine$1,
35370 symbolCircle: circle,
35371 symbolCross: cross$1,
35372 symbolDiamond: diamond,
35373 symbolSquare: square,
35375 symbolTriangle: triangle,
35377 curveBasisClosed: basisClosed,
35378 curveBasisOpen: basisOpen,
35380 curveBundle: bundle,
35381 curveCardinalClosed: cardinalClosed,
35382 curveCardinalOpen: cardinalOpen,
35383 curveCardinal: cardinal,
35384 curveCatmullRomClosed: catmullRomClosed,
35385 curveCatmullRomOpen: catmullRomOpen,
35386 curveCatmullRom: catmullRom,
35387 curveLinearClosed: linearClosed,
35388 curveLinear: curveLinear,
35389 curveMonotoneX: monotoneX,
35390 curveMonotoneY: monotoneY,
35391 curveNatural: natural,
35393 curveStepAfter: stepAfter,
35394 curveStepBefore: stepBefore,
35396 stackOffsetExpand: expand,
35397 stackOffsetNone: none,
35398 stackOffsetSilhouette: silhouette,
35399 stackOffsetWiggle: wiggle,
35400 stackOrderAscending: ascending$1,
35401 stackOrderDescending: descending$2,
35402 stackOrderInsideOut: insideOut,
35403 stackOrderNone: none$1,
35404 stackOrderReverse: reverse,
35410 cubehelix: cubehelix,
35411 interpolate: interpolate,
35412 interpolateArray: array$1,
35413 interpolateDate: date,
35414 interpolateNumber: interpolateNumber,
35415 interpolateObject: object,
35416 interpolateRound: interpolateRound,
35417 interpolateString: interpolateString,
35418 interpolateTransformCss: interpolateTransformCss,
35419 interpolateTransformSvg: interpolateTransformSvg,
35420 interpolateZoom: interpolateZoom,
35421 interpolateRgb: interpolateRgb,
35422 interpolateRgbBasis: rgbBasis,
35423 interpolateRgbBasisClosed: rgbBasisClosed,
35424 interpolateHsl: hsl$2,
35425 interpolateHslLong: hslLong,
35426 interpolateLab: lab$1,
35427 interpolateHcl: hcl$2,
35428 interpolateHclLong: hclLong,
35429 interpolateCubehelix: cubehelix$2,
35430 interpolateCubehelixLong: cubehelixLong,
35431 interpolateBasis: basis$2,
35432 interpolateBasisClosed: basisClosed$1,
35433 quantize: quantize,
35434 dispatch: dispatch,
35436 csvParse: csvParse,
35437 csvParseRows: csvParseRows,
35438 csvFormat: csvFormat,
35439 csvFormatRows: csvFormatRows,
35440 tsvParse: tsvParse,
35441 tsvParseRows: tsvParseRows,
35442 tsvFormat: tsvFormat,
35443 tsvFormatRows: tsvFormatRows,
35453 timerFlush: timerFlush,
35454 timeout: timeout$1,
35455 interval: interval$1,
35456 timeInterval: newInterval,
35457 timeMillisecond: millisecond,
35458 timeMilliseconds: milliseconds,
35459 timeSecond: second,
35460 timeSeconds: seconds,
35461 timeMinute: minute,
35462 timeMinutes: minutes,
35468 timeWeeks: sundays,
35469 timeSunday: sunday,
35470 timeSundays: sundays,
35471 timeMonday: monday,
35472 timeMondays: mondays,
35473 timeTuesday: tuesday,
35474 timeTuesdays: tuesdays,
35475 timeWednesday: wednesday,
35476 timeWednesdays: wednesdays,
35477 timeThursday: thursday,
35478 timeThursdays: thursdays,
35479 timeFriday: friday,
35480 timeFridays: fridays,
35481 timeSaturday: saturday,
35482 timeSaturdays: saturdays,
35484 timeMonths: months,
35487 utcMillisecond: millisecond,
35488 utcMilliseconds: milliseconds,
35490 utcSeconds: seconds,
35491 utcMinute: utcMinute,
35492 utcMinutes: utcMinutes,
35494 utcHours: utcHours,
35497 utcWeek: utcSunday,
35498 utcWeeks: utcSundays,
35499 utcSunday: utcSunday,
35500 utcSundays: utcSundays,
35501 utcMonday: utcMonday,
35502 utcMondays: utcMondays,
35503 utcTuesday: utcTuesday,
35504 utcTuesdays: utcTuesdays,
35505 utcWednesday: utcWednesday,
35506 utcWednesdays: utcWednesdays,
35507 utcThursday: utcThursday,
35508 utcThursdays: utcThursdays,
35509 utcFriday: utcFriday,
35510 utcFridays: utcFridays,
35511 utcSaturday: utcSaturday,
35512 utcSaturdays: utcSaturdays,
35513 utcMonth: utcMonth,
35514 utcMonths: utcMonths,
35516 utcYears: utcYears,
35517 get format () { return format; },
35518 get formatPrefix () { return formatPrefix; },
35519 formatLocale: formatLocale,
35520 formatDefaultLocale: defaultLocale,
35521 formatSpecifier: formatSpecifier,
35522 precisionFixed: precisionFixed,
35523 precisionPrefix: precisionPrefix,
35524 precisionRound: precisionRound,
35525 get timeFormat () { return timeFormat; },
35526 get timeParse () { return timeParse; },
35527 get utcFormat () { return utcFormat; },
35528 get utcParse () { return utcParse; },
35529 isoFormat: formatIso,
35530 isoParse: parseIso,
35531 timeFormatLocale: formatLocale$1,
35532 timeFormatDefaultLocale: defaultLocale$1,
35534 scalePoint: point$4,
35535 scaleIdentity: identity$4,
35536 scaleLinear: linear$2,
35538 scaleOrdinal: ordinal,
35539 scaleImplicit: implicit,
35542 scaleQuantile: quantile$$1,
35543 scaleQuantize: quantize$1,
35544 scaleThreshold: threshold$1,
35547 schemeCategory10: category10,
35548 schemeCategory20b: category20b,
35549 schemeCategory20c: category20c,
35550 schemeCategory20: category20,
35551 scaleSequential: sequential,
35552 interpolateCubehelixDefault: cubehelix$3,
35553 interpolateRainbow: rainbow$1,
35554 interpolateWarm: warm,
35555 interpolateCool: cool,
35556 interpolateViridis: viridis,
35557 interpolateMagma: magma,
35558 interpolateInferno: inferno,
35559 interpolatePlasma: plasma,
35561 customEvent: customEvent,
35562 get event () { return event; },
35564 matcher: matcher$1,
35566 namespace: namespace,
35567 namespaces: namespaces,
35569 selectAll: selectAll,
35570 selection: selection,
35571 selector: selector,
35572 selectorAll: selectorAll,
35577 interrupt: interrupt,
35578 transition: transition,
35580 axisRight: axisRight,
35581 axisBottom: axisBottom,
35582 axisLeft: axisLeft,
35584 hierarchy: hierarchy,
35586 packSiblings: siblings,
35587 packEnclose: enclose,
35588 partition: partition,
35589 stratify: stratify,
35592 treemapBinary: binary,
35593 treemapDice: treemapDice,
35594 treemapSlice: treemapSlice,
35595 treemapSliceDice: sliceDice,
35596 treemapSquarify: squarify,
35597 treemapResquarify: resquarify,
35598 forceCenter: center$1,
35599 forceCollide: collide,
35601 forceManyBody: manyBody,
35602 forceSimulation: simulation,
35606 dragDisable: dragDisable,
35607 dragEnable: yesdrag,
35610 zoomIdentity: identity$6,
35611 zoomTransform: transform,
35615 brushSelection: brushSelection,
35619 geoAlbersUsa: albersUsa,
35621 geoAzimuthalEqualArea: azimuthalEqualArea,
35622 geoAzimuthalEqualAreaRaw: azimuthalEqualAreaRaw,
35623 geoAzimuthalEquidistant: azimuthalEquidistant,
35624 geoAzimuthalEquidistantRaw: azimuthalEquidistantRaw,
35626 geoCentroid: d3GeoCentroid,
35627 geoCircle: circle$1,
35628 geoClipExtent: extent$1,
35629 geoConicConformal: conicConformal,
35630 geoConicConformalRaw: conicConformalRaw,
35631 geoConicEqualArea: conicEqualArea,
35632 geoConicEqualAreaRaw: conicEqualAreaRaw,
35633 geoConicEquidistant: conicEquidistant,
35634 geoConicEquidistantRaw: conicEquidistantRaw,
35635 geoDistance: distance,
35636 geoEquirectangular: equirectangular,
35637 geoEquirectangularRaw: equirectangularRaw,
35638 geoGnomonic: gnomonic,
35639 geoGnomonicRaw: gnomonicRaw,
35640 geoGraticule: graticule,
35641 geoGraticule10: graticule10,
35642 geoIdentity: identity$8,
35643 geoInterpolate: interpolate$2,
35644 geoLength: d3GeoLength,
35645 geoMercator: mercator,
35646 geoMercatorRaw: mercatorRaw,
35647 geoOrthographic: orthographic,
35648 geoOrthographicRaw: orthographicRaw,
35650 geoProjection: projection,
35651 geoProjectionMutator: projectionMutator,
35652 geoRotation: rotation,
35653 geoStereographic: stereographic,
35654 geoStereographicRaw: stereographicRaw,
35655 geoStream: geoStream,
35656 geoTransform: transform$1,
35657 geoTransverseMercator: transverseMercator,
35658 geoTransverseMercatorRaw: transverseMercatorRaw
35662 Bypasses features of D3's default projection stream pipeline that are unnecessary:
35663 * Antimeridian clipping
35664 * Spherical rotation
35667 function geoRawMercator() {
35668 var project = mercatorRaw,
35669 k = 512 / Math.PI, // scale
35670 x = 0, y = 0, // translate
35671 clipExtent = [[0, 0], [0, 0]];
35674 function projection(point) {
35675 point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
35676 return [point[0] * k + x, y - point[1] * k];
35680 projection.invert = function(point) {
35681 point = project.invert((point[0] - x) / k, (y - point[1]) / k);
35682 return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
35686 projection.scale = function(_) {
35687 if (!arguments.length) return k;
35693 projection.translate = function(_) {
35694 if (!arguments.length) return [x, y];
35701 projection.clipExtent = function(_) {
35702 if (!arguments.length) return clipExtent;
35708 projection.transform = function(_) {
35709 if (!arguments.length) return identity$6.translate(x, y).scale(k);
35717 projection.stream = transform$1({
35718 point: function(x, y) {
35719 x = projection([x, y]);
35720 this.stream.point(x[0], x[1]);
35728 function geoRoundCoords(c) {
35729 return [Math.floor(c[0]), Math.floor(c[1])];
35733 function geoInterp(p1, p2, t) {
35734 return [p1[0] + (p2[0] - p1[0]) * t,
35735 p1[1] + (p2[1] - p1[1]) * t];
35739 // 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
35740 // Returns a positive value, if OAB makes a counter-clockwise turn,
35741 // negative for clockwise turn, and zero if the points are collinear.
35742 function geoCross(o, a, b) {
35743 return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
35747 // http://jsperf.com/id-dist-optimization
35748 function geoEuclideanDistance(a, b) {
35749 var x = a[0] - b[0], y = a[1] - b[1];
35750 return Math.sqrt((x * x) + (y * y));
35754 // using WGS84 polar radius (6356752.314245179 m)
35755 // const = 2 * PI * r / 360
35756 function geoLatToMeters(dLat) {
35757 return dLat * 110946.257617;
35761 // using WGS84 equatorial radius (6378137.0 m)
35762 // const = 2 * PI * r / 360
35763 function geoLonToMeters(dLon, atLat) {
35764 return Math.abs(atLat) >= 90 ? 0 :
35765 dLon * 111319.490793 * Math.abs(Math.cos(atLat * (Math.PI/180)));
35769 // using WGS84 polar radius (6356752.314245179 m)
35770 // const = 2 * PI * r / 360
35771 function geoMetersToLat(m) {
35772 return m / 110946.257617;
35776 // using WGS84 equatorial radius (6378137.0 m)
35777 // const = 2 * PI * r / 360
35778 function geoMetersToLon(m, atLat) {
35779 return Math.abs(atLat) >= 90 ? 0 :
35780 m / 111319.490793 / Math.abs(Math.cos(atLat * (Math.PI/180)));
35784 function geoOffsetToMeters(offset) {
35785 var equatRadius = 6356752.314245179,
35786 polarRadius = 6378137.0,
35790 offset[0] * 2 * Math.PI * equatRadius / tileSize,
35791 -offset[1] * 2 * Math.PI * polarRadius / tileSize
35796 function geoMetersToOffset(meters) {
35797 var equatRadius = 6356752.314245179,
35798 polarRadius = 6378137.0,
35802 meters[0] * tileSize / (2 * Math.PI * equatRadius),
35803 -meters[1] * tileSize / (2 * Math.PI * polarRadius)
35808 // Equirectangular approximation of spherical distances on Earth
35809 function geoSphericalDistance(a, b) {
35810 var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2),
35811 y = geoLatToMeters(a[1] - b[1]);
35812 return Math.sqrt((x * x) + (y * y));
35816 function geoEdgeEqual(a, b) {
35817 return (a[0] === b[0] && a[1] === b[1]) ||
35818 (a[0] === b[1] && a[1] === b[0]);
35822 // Return the counterclockwise angle in the range (-pi, pi)
35823 // between the positive X axis and the line intersecting a and b.
35824 function geoAngle(a, b, projection) {
35825 a = projection(a.loc);
35826 b = projection(b.loc);
35827 return Math.atan2(b[1] - a[1], b[0] - a[0]);
35831 // Choose the edge with the minimal distance from `point` to its orthogonal
35832 // projection onto that edge, if such a projection exists, or the distance to
35833 // the closest vertex on that edge. Returns an object with the `index` of the
35834 // chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
35835 function geoChooseEdge(nodes, point, projection) {
35836 var dist = geoEuclideanDistance,
35837 points = nodes.map(function(n) { return projection(n.loc); }),
35841 function dot(p, q) {
35842 return p[0] * q[0] + p[1] * q[1];
35845 for (var i = 0; i < points.length - 1; i++) {
35847 s = [points[i + 1][0] - o[0],
35848 points[i + 1][1] - o[1]],
35849 v = [point[0] - o[0],
35851 proj = dot(v, s) / dot(s, s),
35856 } else if (proj > 1) {
35859 p = [o[0] + proj * s[0], o[1] + proj * s[1]];
35862 var d = dist(p, point);
35866 loc = projection.invert(p);
35878 // Return the intersection point of 2 line segments.
35879 // From https://github.com/pgkelley4/line-segments-intersect
35880 // This uses the vector cross product approach described below:
35881 // http://stackoverflow.com/a/565282/786339
35882 function geoLineIntersection(a, b) {
35883 function subtractPoints(point1, point2) {
35884 return [point1[0] - point2[0], point1[1] - point2[1]];
35886 function crossProduct(point1, point2) {
35887 return point1[0] * point2[1] - point1[1] * point2[0];
35890 var p = [a[0][0], a[0][1]],
35891 p2 = [a[1][0], a[1][1]],
35892 q = [b[0][0], b[0][1]],
35893 q2 = [b[1][0], b[1][1]],
35894 r = subtractPoints(p2, p),
35895 s = subtractPoints(q2, q),
35896 uNumerator = crossProduct(subtractPoints(q, p), r),
35897 denominator = crossProduct(r, s);
35899 if (uNumerator && denominator) {
35900 var u = uNumerator / denominator,
35901 t = crossProduct(subtractPoints(q, p), s) / denominator;
35903 if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
35904 return geoInterp(p, p2, t);
35912 function geoPathIntersections(path1, path2) {
35913 var intersections = [];
35914 for (var i = 0; i < path1.length - 1; i++) {
35915 for (var j = 0; j < path2.length - 1; j++) {
35916 var a = [ path1[i], path1[i+1] ],
35917 b = [ path2[j], path2[j+1] ],
35918 hit = geoLineIntersection(a, b);
35919 if (hit) intersections.push(hit);
35922 return intersections;
35926 // Return whether point is contained in polygon.
35928 // `point` should be a 2-item array of coordinates.
35929 // `polygon` should be an array of 2-item arrays of coordinates.
35931 // From https://github.com/substack/point-in-polygon.
35932 // ray-casting algorithm based on
35933 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
35935 function geoPointInPolygon(point, polygon) {
35940 for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
35941 var xi = polygon[i][0], yi = polygon[i][1];
35942 var xj = polygon[j][0], yj = polygon[j][1];
35944 var intersect = ((yi > y) !== (yj > y)) &&
35945 (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
35946 if (intersect) inside = !inside;
35953 function geoPolygonContainsPolygon(outer, inner) {
35954 return lodash.every(inner, function(point) {
35955 return geoPointInPolygon(point, outer);
35960 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
35961 function testSegments(outer, inner) {
35962 for (var i = 0; i < outer.length - 1; i++) {
35963 for (var j = 0; j < inner.length - 1; j++) {
35964 var a = [ outer[i], outer[i+1] ],
35965 b = [ inner[j], inner[j+1] ];
35966 if (geoLineIntersection(a, b)) return true;
35972 function testPoints(outer, inner) {
35973 return lodash.some(inner, function(point) {
35974 return geoPointInPolygon(point, outer);
35978 return testPoints(outer, inner) || (!!checkSegments && testSegments(outer, inner));
35982 function geoPathLength(path) {
35984 for (var i = 0; i < path.length - 1; i++) {
35985 length += geoEuclideanDistance(path[i], path[i + 1]);
35990 function osmNode() {
35991 if (!(this instanceof osmNode)) {
35992 return (new osmNode()).initialize(arguments);
35993 } else if (arguments.length) {
35994 this.initialize(arguments);
35998 osmEntity$$1.node = osmNode;
36000 osmNode.prototype = Object.create(osmEntity$$1.prototype);
36002 lodash.extend(osmNode.prototype, {
36007 extent: function() {
36008 return new geoExtent$$1(this.loc);
36012 geometry: function(graph) {
36013 return graph.transient(this, 'geometry', function() {
36014 return graph.isPoi(this) ? 'point' : 'vertex';
36019 move: function(loc) {
36020 return this.update({loc: loc});
36024 isIntersection: function(resolver) {
36025 return resolver.transient(this, 'isIntersection', function() {
36026 return resolver.parentWays(this).filter(function(parent) {
36027 return (parent.tags.highway ||
36028 parent.tags.waterway ||
36029 parent.tags.railway ||
36030 parent.tags.aeroway) &&
36031 parent.geometry(resolver) === 'line';
36037 isHighwayIntersection: function(resolver) {
36038 return resolver.transient(this, 'isHighwayIntersection', function() {
36039 return resolver.parentWays(this).filter(function(parent) {
36040 return parent.tags.highway && parent.geometry(resolver) === 'line';
36046 isOnAddressLine: function(resolver) {
36047 return resolver.transient(this, 'isOnAddressLine', function() {
36048 return resolver.parentWays(this).filter(function(parent) {
36049 return parent.tags.hasOwnProperty('addr:interpolation') &&
36050 parent.geometry(resolver) === 'line';
36056 asJXON: function(changeset_id) {
36059 '@id': this.osmId(),
36060 '@lon': this.loc[0],
36061 '@lat': this.loc[1],
36062 '@version': (this.version || 0),
36063 tag: lodash.map(this.tags, function(v, k) {
36064 return { keyAttributes: { k: k, v: v } };
36068 if (changeset_id) r.node['@changeset'] = changeset_id;
36073 asGeoJSON: function() {
36076 coordinates: this.loc
36082 Order the nodes of a way in reverse order and reverse any direction dependent tags
36083 other than `oneway`. (We assume that correcting a backwards oneway is the primary
36084 reason for reversing a way.)
36086 The following transforms are performed:
36089 *:right=* ⟺ *:left=*
36090 *:forward=* ⟺ *:backward=*
36091 direction=up ⟺ direction=down
36092 incline=up ⟺ incline=down
36096 role=forward ⟺ role=backward
36097 role=north ⟺ role=south
36098 role=east ⟺ role=west
36100 In addition, numeric-valued `incline` tags are negated.
36102 The JOSM implementation was used as a guide, but transformations that were of unclear benefit
36103 or adjusted tags that don't seem to be used in practice were omitted.
36105 Also, each node on the way is examined for its own tags and the following transformations are performed
36106 in order to ensure associated nodes (eg a Stop Sign) is also reversed
36109 direction=forward ⟺ direction=backward
36110 direction=left ⟺ direction=right
36111 *:forward=* ⟺ *:backward=*
36112 *:left=* ⟺ *:right=*
36115 http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
36116 http://wiki.openstreetmap.org/wiki/Key:direction#Steps
36117 http://wiki.openstreetmap.org/wiki/Key:incline
36118 http://wiki.openstreetmap.org/wiki/Route#Members
36119 http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
36120 http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
36121 http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
36123 function actionReverse(wayId, options) {
36124 var replacements = [
36125 [/:right$/, ':left'], [/:left$/, ':right'],
36126 [/:forward$/, ':backward'], [/:backward$/, ':forward']
36128 numeric = /^([+\-]?)(?=[\d.])/,
36130 forward: 'backward',
36131 backward: 'forward',
36139 function reverseKey(key) {
36140 for (var i = 0; i < replacements.length; ++i) {
36141 var replacement = replacements[i];
36142 if (replacement[0].test(key)) {
36143 return key.replace(replacement[0], replacement[1]);
36150 function reverseValue(key, value) {
36151 if (key === 'incline' && numeric.test(value)) {
36152 return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
36153 } else if (key === 'incline' || key === 'direction') {
36154 return {up: 'down', down: 'up'}[value] || value;
36155 } else if (options && options.reverseOneway && key === 'oneway') {
36156 return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
36158 return {left: 'right', right: 'left'}[value] || value;
36163 function reverseDirectionTags(node) {
36164 // Update the direction based tags as appropriate then return an updated node
36165 return node.update({tags: lodash.transform(node.tags, function(acc, tagValue, tagKey) {
36166 // See if this is a direction tag and reverse (or use existing value if not recognised)
36167 if (tagKey === 'direction') {
36168 acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
36170 // Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
36171 // This will pass through other tags unchanged
36172 acc[reverseKey(tagKey)] = tagValue;
36179 function reverseTagsOnNodes(graph, nodeIds) {
36180 // Reverse the direction of appropriate tags attached to the nodes (#3076)
36181 return lodash(nodeIds)
36182 // Get each node from the graph
36183 .map(function(nodeId) { return graph.entity(nodeId);})
36184 // Check tags on the node, if there aren't any, we can skip
36185 .filter(function(existingNode) { return existingNode.tags !== undefined;})
36186 // Get a new version of each node with the appropriate tags reversed
36187 .map(function(existingNode) { return reverseDirectionTags(existingNode);})
36188 // Chain together consecutive updates to the graph for each updated node and return
36189 .reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
36193 return function(graph) {
36194 var way = graph.entity(wayId),
36195 nodes = way.nodes.slice().reverse(),
36196 tags = {}, key, role;
36198 for (key in way.tags) {
36199 tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
36202 graph.parentRelations(way).forEach(function(relation) {
36203 relation.members.forEach(function(member, index) {
36204 if (member.id === way.id && (role = roleReversals[member.role])) {
36205 relation = relation.updateMember({role: role}, index);
36206 graph = graph.replace(relation);
36211 // Reverse any associated directions on nodes on the way and then replace
36212 // the way itself with the reversed node ids and updated way tags
36213 return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
36217 // For fixing up rendering of multipolygons with tags on the outer member.
36218 // https://github.com/openstreetmap/iD/issues/613
36219 function osmIsSimpleMultipolygonOuterMember(entity, graph) {
36220 if (entity.type !== 'way')
36223 var parents = graph.parentRelations(entity);
36224 if (parents.length !== 1)
36227 var parent = parents[0];
36228 if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
36231 var members = parent.members, member;
36232 for (var i = 0; i < members.length; i++) {
36233 member = members[i];
36234 if (member.id === entity.id && member.role && member.role !== 'outer')
36235 return false; // Not outer member
36236 if (member.id !== entity.id && (!member.role || member.role === 'outer'))
36237 return false; // Not a simple multipolygon
36244 function osmSimpleMultipolygonOuterMember(entity, graph) {
36245 if (entity.type !== 'way')
36248 var parents = graph.parentRelations(entity);
36249 if (parents.length !== 1)
36252 var parent = parents[0];
36253 if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
36256 var members = parent.members, member, outerMember;
36257 for (var i = 0; i < members.length; i++) {
36258 member = members[i];
36259 if (!member.role || member.role === 'outer') {
36261 return false; // Not a simple multipolygon
36262 outerMember = member;
36266 return outerMember && graph.hasEntity(outerMember.id);
36270 // Join `array` into sequences of connecting ways.
36272 // Segments which share identical start/end nodes will, as much as possible,
36273 // be connected with each other.
36275 // The return value is a nested array. Each constituent array contains elements
36276 // of `array` which have been determined to connect. Each consitituent array
36277 // also has a `nodes` property whose value is an ordered array of member nodes,
36278 // with appropriate order reversal and start/end coordinate de-duplication.
36280 // Members of `array` must have, at minimum, `type` and `id` properties.
36281 // Thus either an array of `osmWay`s or a relation member array may be
36284 // If an member has a `tags` property, its tags will be reversed via
36285 // `actionReverse` in the output.
36287 // Incomplete members (those for which `graph.hasEntity(element.id)` returns
36288 // false) and non-way members are ignored.
36290 function osmJoinWays(array, graph) {
36291 var joined = [], member, current, nodes, first, last, i, how, what;
36293 array = array.filter(function(member) {
36294 return member.type === 'way' && graph.hasEntity(member.id);
36297 function resolve(member) {
36298 return graph.childNodes(graph.entity(member.id));
36301 function reverse(member) {
36302 return member.tags ? actionReverse(member.id, { reverseOneway: true })(graph).entity(member.id) : member;
36305 while (array.length) {
36306 member = array.shift();
36307 current = [member];
36308 current.nodes = nodes = resolve(member).slice();
36309 joined.push(current);
36311 while (array.length && lodash.first(nodes) !== lodash.last(nodes)) {
36312 first = lodash.first(nodes);
36313 last = lodash.last(nodes);
36315 for (i = 0; i < array.length; i++) {
36317 what = resolve(member);
36319 if (last === lodash.first(what)) {
36321 what = what.slice(1);
36323 } else if (last === lodash.last(what)) {
36325 what = what.slice(0, -1).reverse();
36326 member = reverse(member);
36328 } else if (first === lodash.last(what)) {
36329 how = nodes.unshift;
36330 what = what.slice(0, -1);
36332 } else if (first === lodash.first(what)) {
36333 how = nodes.unshift;
36334 what = what.slice(1).reverse();
36335 member = reverse(member);
36343 break; // No more joinable ways.
36345 how.apply(current, [member]);
36346 how.apply(nodes, what);
36348 array.splice(i, 1);
36355 function osmRelation() {
36356 if (!(this instanceof osmRelation)) {
36357 return (new osmRelation()).initialize(arguments);
36358 } else if (arguments.length) {
36359 this.initialize(arguments);
36364 osmEntity$$1.relation = osmRelation;
36366 osmRelation.prototype = Object.create(osmEntity$$1.prototype);
36369 osmRelation.creationOrder = function(a, b) {
36370 var aId = parseInt(osmEntity$$1.id.toOSM(a.id), 10);
36371 var bId = parseInt(osmEntity$$1.id.toOSM(b.id), 10);
36373 if (aId < 0 || bId < 0) return aId - bId;
36378 lodash.extend(osmRelation.prototype, {
36383 copy: function(resolver, copies) {
36384 if (copies[this.id])
36385 return copies[this.id];
36387 var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
36389 var members = this.members.map(function(member) {
36390 return lodash.extend({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
36393 copy = copy.update({members: members});
36394 copies[this.id] = copy;
36400 extent: function(resolver, memo) {
36401 return resolver.transient(this, 'extent', function() {
36402 if (memo && memo[this.id]) return geoExtent$$1();
36404 memo[this.id] = true;
36406 var extent$$1 = geoExtent$$1();
36407 for (var i = 0; i < this.members.length; i++) {
36408 var member = resolver.hasEntity(this.members[i].id);
36410 extent$$1._extend(member.extent(resolver, memo));
36418 geometry: function(graph) {
36419 return graph.transient(this, 'geometry', function() {
36420 return this.isMultipolygon() ? 'area' : 'relation';
36425 isDegenerate: function() {
36426 return this.members.length === 0;
36430 // Return an array of members, each extended with an 'index' property whose value
36431 // is the member index.
36432 indexedMembers: function() {
36433 var result = new Array(this.members.length);
36434 for (var i = 0; i < this.members.length; i++) {
36435 result[i] = lodash.extend({}, this.members[i], {index: i});
36441 // Return the first member with the given role. A copy of the member object
36442 // is returned, extended with an 'index' property whose value is the member index.
36443 memberByRole: function(role) {
36444 for (var i = 0; i < this.members.length; i++) {
36445 if (this.members[i].role === role) {
36446 return lodash.extend({}, this.members[i], {index: i});
36452 // Return the first member with the given id. A copy of the member object
36453 // is returned, extended with an 'index' property whose value is the member index.
36454 memberById: function(id) {
36455 for (var i = 0; i < this.members.length; i++) {
36456 if (this.members[i].id === id) {
36457 return lodash.extend({}, this.members[i], {index: i});
36463 // Return the first member with the given id and role. A copy of the member object
36464 // is returned, extended with an 'index' property whose value is the member index.
36465 memberByIdAndRole: function(id, role) {
36466 for (var i = 0; i < this.members.length; i++) {
36467 if (this.members[i].id === id && this.members[i].role === role) {
36468 return lodash.extend({}, this.members[i], {index: i});
36474 addMember: function(member, index) {
36475 var members = this.members.slice();
36476 members.splice(index === undefined ? members.length : index, 0, member);
36477 return this.update({members: members});
36481 updateMember: function(member, index) {
36482 var members = this.members.slice();
36483 members.splice(index, 1, lodash.extend({}, members[index], member));
36484 return this.update({members: members});
36488 removeMember: function(index) {
36489 var members = this.members.slice();
36490 members.splice(index, 1);
36491 return this.update({members: members});
36495 removeMembersWithID: function(id) {
36496 var members = lodash.reject(this.members, function(m) { return m.id === id; });
36497 return this.update({members: members});
36501 // Wherever a member appears with id `needle.id`, replace it with a member
36502 // with id `replacement.id`, type `replacement.type`, and the original role,
36503 // unless a member already exists with that id and role. Return an updated
36505 replaceMember: function(needle, replacement) {
36506 if (!this.memberById(needle.id))
36511 for (var i = 0; i < this.members.length; i++) {
36512 var member = this.members[i];
36513 if (member.id !== needle.id) {
36514 members.push(member);
36515 } else if (!this.memberByIdAndRole(replacement.id, member.role)) {
36516 members.push({id: replacement.id, type: replacement.type, role: member.role});
36520 return this.update({members: members});
36524 asJXON: function(changeset_id) {
36527 '@id': this.osmId(),
36528 '@version': this.version || 0,
36529 member: lodash.map(this.members, function(member) {
36534 ref: osmEntity$$1.id.toOSM(member.id)
36538 tag: lodash.map(this.tags, function(v, k) {
36539 return { keyAttributes: { k: k, v: v } };
36543 if (changeset_id) r.relation['@changeset'] = changeset_id;
36548 asGeoJSON: function(resolver) {
36549 return resolver.transient(this, 'GeoJSON', function () {
36550 if (this.isMultipolygon()) {
36552 type: 'MultiPolygon',
36553 coordinates: this.multipolygon(resolver)
36557 type: 'FeatureCollection',
36558 properties: this.tags,
36559 features: this.members.map(function (member) {
36560 return lodash.extend({role: member.role}, resolver.entity(member.id).asGeoJSON(resolver));
36568 area: function(resolver) {
36569 return resolver.transient(this, 'area', function() {
36570 return area$1(this.asGeoJSON(resolver));
36575 isMultipolygon: function() {
36576 return this.tags.type === 'multipolygon';
36580 isComplete: function(resolver) {
36581 for (var i = 0; i < this.members.length; i++) {
36582 if (!resolver.hasEntity(this.members[i].id)) {
36590 isRestriction: function() {
36591 return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
36595 // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
36596 // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
36598 // This corresponds to the structure needed for rendering a multipolygon path using a
36599 // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
36601 // In the case of invalid geometries, this function will still return a result which
36602 // includes the nodes of all way members, but some Nds may be unclosed and some inner
36603 // rings not matched with the intended outer ring.
36605 multipolygon: function(resolver) {
36606 var outers = this.members.filter(function(m) { return 'outer' === (m.role || 'outer'); }),
36607 inners = this.members.filter(function(m) { return 'inner' === m.role; });
36609 outers = osmJoinWays(outers, resolver);
36610 inners = osmJoinWays(inners, resolver);
36612 outers = outers.map(function(outer) { return lodash.map(outer.nodes, 'loc'); });
36613 inners = inners.map(function(inner) { return lodash.map(inner.nodes, 'loc'); });
36615 var result = outers.map(function(o) {
36616 // Heuristic for detecting counterclockwise winding order. Assumes
36617 // that OpenStreetMap polygons are not hemisphere-spanning.
36618 return [area$1({ type: 'Polygon', coordinates: [o] }) > 2 * Math.PI ? o.reverse() : o];
36621 function findOuter(inner) {
36624 for (o = 0; o < outers.length; o++) {
36626 if (geoPolygonContainsPolygon(outer, inner))
36630 for (o = 0; o < outers.length; o++) {
36632 if (geoPolygonIntersectsPolygon(outer, inner, false))
36637 for (var i = 0; i < inners.length; i++) {
36638 var inner = inners[i];
36640 if (area$1({ type: 'Polygon', coordinates: [inner] }) < 2 * Math.PI) {
36641 inner = inner.reverse();
36644 var o = findOuter(inners[i]);
36645 if (o !== undefined)
36646 result[o].push(inners[i]);
36648 result.push([inners[i]]); // Invalid geometry
36655 function osmLanes(entity) {
36656 if (entity.type !== 'way') return null;
36657 if (!entity.tags.highway) return null;
36659 var tags = entity.tags;
36660 var isOneWay = entity.isOneWay();
36661 var laneCount = getLaneCount(tags, isOneWay);
36662 var maxspeed = parseMaxspeed(tags);
36664 var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
36665 var forward = laneDirections.forward;
36666 var backward = laneDirections.backward;
36667 var bothways = laneDirections.bothways;
36669 // parse the piped string 'x|y|z' format
36670 var turnLanes = {};
36671 turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
36672 turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
36673 turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
36675 var maxspeedLanes = {};
36676 maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
36677 maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
36678 maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
36681 psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
36682 psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
36683 psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
36686 busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
36687 busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
36688 busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
36690 var taxiLanes = {};
36691 taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
36692 taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
36693 taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
36696 hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
36697 hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
36698 hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
36701 hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
36702 hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
36703 hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
36705 var bicyclewayLanes = {};
36706 bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
36707 bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
36708 bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
36716 // map forward/backward/unspecified of each lane type to lanesObj
36717 mapToLanesObj(lanesObj, turnLanes, 'turnLane');
36718 mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
36719 mapToLanesObj(lanesObj, psvLanes, 'psv');
36720 mapToLanesObj(lanesObj, busLanes, 'bus');
36721 mapToLanesObj(lanesObj, taxiLanes, 'taxi');
36722 mapToLanesObj(lanesObj, hovLanes, 'hov');
36723 mapToLanesObj(lanesObj, hgvLanes, 'hgv');
36724 mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
36731 backward: backward,
36732 bothways: bothways,
36733 turnLanes: turnLanes,
36734 maxspeed: maxspeed,
36735 maxspeedLanes: maxspeedLanes,
36736 psvLanes: psvLanes,
36737 busLanes: busLanes,
36738 taxiLanes: taxiLanes,
36739 hovLanes: hovLanes,
36740 hgvLanes: hgvLanes,
36741 bicyclewayLanes: bicyclewayLanes
36748 function getLaneCount(tags, isOneWay) {
36751 count = parseInt(tags.lanes, 10);
36758 switch (tags.highway) {
36761 count = isOneWay ? 2 : 4;
36764 count = isOneWay ? 1 : 2;
36772 function parseMaxspeed(tags) {
36773 var maxspeed = tags.maxspeed;
36774 if (lodash.isNumber(maxspeed)) return maxspeed;
36775 if (lodash.isString(maxspeed)) {
36776 maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g);
36777 if (!maxspeed) return;
36778 return parseInt(maxspeed, 10);
36783 function parseLaneDirections(tags, isOneWay, laneCount) {
36784 var forward = parseInt(tags['lanes:forward'], 10);
36785 var backward = parseInt(tags['lanes:backward'], 10);
36786 var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
36788 if (parseInt(tags.oneway, 10) === -1) {
36791 backward = laneCount;
36793 else if (isOneWay) {
36794 forward = laneCount;
36798 else if (lodash.isNaN(forward) && lodash.isNaN(backward)) {
36799 backward = Math.floor((laneCount - bothways) / 2);
36800 forward = laneCount - bothways - backward;
36802 else if (lodash.isNaN(forward)) {
36803 if (backward > laneCount - bothways) {
36804 backward = laneCount - bothways;
36806 forward = laneCount - bothways - backward;
36808 else if (lodash.isNaN(backward)) {
36809 if (forward > laneCount - bothways) {
36810 forward = laneCount - bothways;
36812 backward = laneCount - bothways - forward;
36816 backward: backward,
36822 function parseTurnLanes(tag){
36825 var validValues = [
36826 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
36827 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
36830 return tag.split('|')
36831 .map(function (s) {
36832 if (s === '') s = 'none';
36833 return s.split(';')
36834 .map(function (d) {
36835 return validValues.indexOf(d) === -1 ? 'unknown': d;
36841 function parseMaxspeedLanes(tag, maxspeed) {
36844 return tag.split('|')
36845 .map(function (s) {
36846 if (s === 'none') return s;
36847 var m = parseInt(s, 10);
36848 if (s === '' || m === maxspeed) return null;
36849 return lodash.isNaN(m) ? 'unknown': m;
36854 function parseMiscLanes(tag) {
36857 var validValues = [
36858 'yes', 'no', 'designated'
36861 return tag.split('|')
36862 .map(function (s) {
36863 if (s === '') s = 'no';
36864 return validValues.indexOf(s) === -1 ? 'unknown': s;
36869 function parseBicycleWay(tag) {
36872 var validValues = [
36873 'yes', 'no', 'designated', 'lane'
36876 return tag.split('|')
36877 .map(function (s) {
36878 if (s === '') s = 'no';
36879 return validValues.indexOf(s) === -1 ? 'unknown': s;
36884 function mapToLanesObj(lanesObj, data, key) {
36885 if (data.forward) data.forward.forEach(function(l, i) {
36886 if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
36887 lanesObj.forward[i][key] = l;
36889 if (data.backward) data.backward.forEach(function(l, i) {
36890 if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
36891 lanesObj.backward[i][key] = l;
36893 if (data.unspecified) data.unspecified.forEach(function(l, i) {
36894 if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
36895 lanesObj.unspecified[i][key] = l;
36899 var translations = Object.create(null);
36901 var currentLocale = 'en';
36902 var textDirection = 'ltr';
36904 function setLocale(_) {
36905 if (translations[_] !== undefined) {
36907 } else if (translations[_.split('-')[0]]) {
36908 currentLocale = _.split('-')[0];
36912 function addTranslation(id, value) {
36913 translations[id] = value;
36917 * Given a string identifier, try to find that string in the current
36918 * language, and return it.
36920 * @param {string} s string identifier
36921 * @returns {string?} locale string
36923 function t(s, o, loc) {
36924 loc = loc || currentLocale;
36926 var path = s.split('.').reverse();
36927 var rep = translations[loc];
36929 while (rep !== undefined && path.length) rep = rep[path.pop()];
36931 if (rep !== undefined) {
36932 if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
36936 if (loc !== 'en') {
36937 return t(s, o, 'en');
36940 if (o && 'default' in o) {
36944 var missing = 'Missing ' + loc + ' translation: ' + s;
36945 if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
36951 * Given string 'ltr' or 'rtl', save that setting
36953 * @param {string} s ltr or rtl
36956 function setTextDirection(dir) {
36957 textDirection = dir;
36962 function utilDetect(force) {
36963 if (detected && !force) return detected;
36966 var ua = navigator.userAgent,
36969 m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); // Edge
36971 detected.browser = m[1];
36972 detected.version = m[2];
36974 if (!detected.browser) {
36975 m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); // IE11
36977 detected.browser = 'msie';
36978 detected.version = m[1];
36981 if (!detected.browser) {
36982 m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); // Opera 15+
36984 detected.browser = 'Opera';
36985 detected.version = m[2];
36988 if (!detected.browser) {
36989 m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
36991 detected.browser = m[1];
36992 detected.version = m[2];
36993 m = ua.match(/version\/([\.\d]+)/i);
36994 if (m !== null) detected.version = m[1];
36997 if (!detected.browser) {
36998 detected.browser = navigator.appName;
36999 detected.version = navigator.appVersion;
37002 // keep major.minor version only..
37003 detected.version = detected.version.split(/\W/).slice(0,2).join('.');
37005 if (detected.browser.toLowerCase() === 'msie') {
37006 detected.ie = true;
37007 detected.browser = 'Internet Explorer';
37008 detected.support = parseFloat(detected.version) >= 11;
37010 detected.ie = false;
37011 detected.support = true;
37014 // Added due to incomplete svg style support. See #715
37015 detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
37017 detected.locale = (navigator.languages && navigator.languages.length)
37018 ? navigator.languages[0] : (navigator.language || navigator.userLanguage || 'en-US');
37020 // Loaded locale is stored in currentLocale
37021 // return that instead (except in the situation where 'en' might override 'en-US')
37022 var loadedLocale = currentLocale || 'en';
37023 if (loadedLocale !== 'en') {
37024 detected.locale = loadedLocale;
37027 // detect text direction
37028 var q = utilStringQs(window.location.hash.substring(1));
37029 var lang = dataLocales[detected.locale];
37030 if ((lang && lang.rtl) || q.hasOwnProperty('rtl')) {
37031 detected.textDirection = 'rtl';
37033 detected.textDirection = 'ltr';
37035 setTextDirection(detected.textDirection);
37037 detected.host = window.location && (window.location.origin + window.location.pathname);
37039 detected.filedrop = (window.FileReader && 'ondrop' in window);
37042 return navigator.userAgent.indexOf(x) !== -1;
37046 detected.os = 'win';
37047 detected.platform = 'Windows';
37049 else if (nav('Mac')) {
37050 detected.os = 'mac';
37051 detected.platform = 'Macintosh';
37053 else if (nav('X11') || nav('Linux')) {
37054 detected.os = 'linux';
37055 detected.platform = 'Linux';
37058 detected.os = 'win';
37059 detected.platform = 'Unknown';
37065 var remove$1 = removeDiacritics;
37067 var replacementList = [
37076 chars: "\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F",
37082 chars: "\u00C6\u01FC\u01E2",
37091 chars: "\uA738\uA73A",
37097 chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
37100 chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
37103 chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
37109 chars: "\u01F1\u01C4",
37112 chars: "\u01F2\u01C5",
37115 chars: "\u025B\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E\u1D07",
37118 chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
37121 chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
37124 chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
37127 chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
37130 chars: "\u24BF\uFF2A\u0134\u0248\u0237",
37133 chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
37136 chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
37145 chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
37148 chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
37157 chars: "\u24C4\uFF2F\xD2\xD3\xD4\u1ED2\u1ED0\u1ED6\u1ED4\xD5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\xD6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\xD8\u01FE\u0186\u019F\uA74A\uA74C",
37172 chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
37175 chars: "\u24C6\uFF31\uA756\uA758\u024A",
37178 chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
37181 chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
37184 chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
37193 chars: "\u24CA\uFF35\xD9\xDA\xDB\u0168\u1E78\u016A\u1E7A\u016C\xDC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244",
37196 chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
37202 chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
37205 chars: "\u24CD\uFF38\u1E8A\u1E8C",
37208 chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
37211 chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
37214 chars: "\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0251",
37220 chars: "\u00E6\u01FD\u01E3",
37229 chars: "\uA739\uA73B",
37235 chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
37238 chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
37241 chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
37247 chars: "\u01F3\u01C6",
37250 chars: "\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u01DD",
37253 chars: "\u24D5\uFF46\u1E1F\u0192",
37271 chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
37274 chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
37280 chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
37283 chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
37286 chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
37289 chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
37295 chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
37298 chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
37304 chars: "\u24DE\uFF4F\xF2\xF3\xF4\u1ED3\u1ED1\u1ED7\u1ED5\xF5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\xF6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\xF8\u01FF\uA74B\uA74D\u0275\u0254\u1D11",
37319 chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
37322 chars: "\u24E0\uFF51\u024B\uA757\uA759",
37325 chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
37328 chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
37334 chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
37343 chars: "\u24E4\uFF55\xF9\xFA\xFB\u0169\u1E79\u016B\u1E7B\u016D\xFC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289",
37346 chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
37352 chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
37355 chars: "\u24E7\uFF58\u1E8B\u1E8D",
37358 chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
37361 chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
37365 var diacriticsMap = {};
37366 for (var i = 0; i < replacementList.length; i += 1) {
37367 var chars = replacementList[i].chars;
37368 for (var j = 0; j < chars.length; j += 1) {
37369 diacriticsMap[chars[j]] = replacementList[i].base;
37373 function removeDiacritics(str) {
37374 return str.replace(/[^\u0000-\u007e]/g, function(c) {
37375 return diacriticsMap[c] || c;
37379 function utilTagText(entity) {
37380 return entries(entity.tags).map(function(e) {
37381 return e.key + '=' + e.value;
37386 function utilEntitySelector(ids) {
37387 return ids.length ? '.' + ids.join(',.') : 'nothing';
37391 function utilEntityOrMemberSelector(ids, graph) {
37392 var s = utilEntitySelector(ids);
37394 ids.forEach(function(id) {
37395 var entity = graph.hasEntity(id);
37396 if (entity && entity.type === 'relation') {
37397 entity.members.forEach(function(member) {
37398 s += ',.' + member.id;
37407 function utilDisplayName(entity) {
37408 var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
37409 name = entity.tags[localizedNameKey] || entity.tags.name || '',
37410 network = entity.tags.cycle_network || entity.tags.network;
37411 if (!name && entity.tags.ref) {
37412 name = entity.tags.ref;
37414 name = network + ' ' + name;
37421 function utilDisplayType(id) {
37423 n: t('inspector.node'),
37424 w: t('inspector.way'),
37425 r: t('inspector.relation')
37430 function utilStringQs(str) {
37431 return str.split('&').reduce(function(obj, pair){
37432 var parts = pair.split('=');
37433 if (parts.length === 2) {
37434 obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
37441 function utilQsString(obj, noencode) {
37442 function softEncode(s) {
37443 // encode everything except special characters used in certain hash parameters:
37444 // "/" in map states, ":", ",", {" and "}" in background
37445 return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
37447 return Object.keys(obj).sort().map(function(key) {
37448 return encodeURIComponent(key) + '=' + (
37449 noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
37454 function utilPrefixDOMProperty(property) {
37455 var prefixes = ['webkit', 'ms', 'moz', 'o'],
37457 n = prefixes.length,
37463 property = property.substr(0, 1).toUpperCase() + property.substr(1);
37466 if (prefixes[i] + property in s)
37467 return prefixes[i] + property;
37473 function utilPrefixCSSProperty(property) {
37474 var prefixes = ['webkit', 'ms', 'Moz', 'O'],
37476 n = prefixes.length,
37477 s = document.body.style;
37479 if (property.toLowerCase() in s)
37480 return property.toLowerCase();
37483 if (prefixes[i] + property in s)
37484 return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
37490 var transformProperty;
37491 function utilSetTransform(el, x, y, scale) {
37492 var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
37493 translate = utilDetect().opera ?
37494 'translate(' + x + 'px,' + y + 'px)' :
37495 'translate3d(' + x + 'px,' + y + 'px,0)';
37496 return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
37500 // Calculates Levenshtein distance between two strings
37501 // see: https://en.wikipedia.org/wiki/Levenshtein_distance
37502 // first converts the strings to lowercase and replaces diacritic marks with ascii equilivants.
37503 function utilEditDistance(a, b) {
37504 a = remove$1(a.toLowerCase());
37505 b = remove$1(b.toLowerCase());
37506 if (a.length === 0) return b.length;
37507 if (b.length === 0) return a.length;
37509 for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
37510 for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
37511 for (i = 1; i <= b.length; i++) {
37512 for (j = 1; j <= a.length; j++) {
37513 if (b.charAt(i-1) === a.charAt(j-1)) {
37514 matrix[i][j] = matrix[i-1][j-1];
37516 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
37517 Math.min(matrix[i][j-1] + 1, // insertion
37518 matrix[i-1][j] + 1)); // deletion
37522 return matrix[b.length][a.length];
37526 // a d3.mouse-alike which
37527 // 1. Only works on HTML elements, not SVG
37528 // 2. Does not cause style recalculation
37529 function utilFastMouse(container) {
37530 var rect = container.getBoundingClientRect(),
37531 rectLeft = rect.left,
37532 rectTop = rect.top,
37533 clientLeft = +container.clientLeft,
37534 clientTop = +container.clientTop;
37535 if (textDirection === 'rtl') {
37538 return function(e) {
37540 e.clientX - rectLeft - clientLeft,
37541 e.clientY - rectTop - clientTop];
37546 /* eslint-disable no-proto */
37547 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
37548 /* eslint-enable no-proto */
37551 function utilAsyncMap(inputs, func, callback) {
37552 var remaining = inputs.length,
37556 inputs.forEach(function(d, i) {
37557 func(d, function done(err, data) {
37561 if (!remaining) callback(errors, results);
37567 // wraps an index to an interval [0..length-1]
37568 function utilWrap(index, length) {
37570 index += Math.ceil(-index/length)*length;
37571 return index % length;
37576 * a replacement for functor
37578 * @param {*} value any value
37579 * @returns {Function} a function that returns that value or the value if it's a function
37581 function utilFunctor(value) {
37582 if (typeof value === 'function') return value;
37583 return function() {
37588 // A per-domain session mutex backed by a cookie and dead man's
37589 // switch. If the session crashes, the mutex will auto-release
37590 // after 5 seconds.
37592 function utilSessionMutex(name) {
37597 var expires = new Date();
37598 expires.setSeconds(expires.getSeconds() + 5);
37599 document.cookie = name + '=1; expires=' + expires.toUTCString();
37602 mutex.lock = function() {
37603 if (intervalID) return true;
37604 var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
37605 if (cookie) return false;
37607 intervalID = window.setInterval(renew, 4000);
37611 mutex.unlock = function() {
37612 if (!intervalID) return;
37613 document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
37614 clearInterval(intervalID);
37618 mutex.locked = function() {
37619 return !!intervalID;
37625 function utilSuggestNames(preset, suggestions) {
37626 preset = preset.id.split('/', 2);
37630 return function(value, callback) {
37632 if (value && value.length > 2) {
37633 if (suggestions[k] && suggestions[k][v]) {
37634 for (var sugg in suggestions[k][v]) {
37635 var dist = utilEditDistance(value, sugg.substring(0, value.length));
37645 result.sort(function(a, b) {
37646 return a.dist - b.dist;
37649 result = result.slice(0,3);
37654 function utilTriggerEvent(target, type) {
37655 target.each(function() {
37656 var evt = document.createEvent('HTMLEvents');
37657 evt.initEvent(type, true, true);
37658 this.dispatchEvent(evt);
37662 // Like selection.property('value', ...), but avoids no-op value sets,
37663 // which can result in layout/repaint thrashing in some situations.
37664 function utilGetSetValue(selection, value) {
37665 function d3_selection_value(value) {
37666 function valueNull() {
37670 function valueConstant() {
37671 if (this.value !== value) {
37672 this.value = value;
37676 function valueFunction() {
37677 var x = value.apply(this, arguments);
37680 } else if (this.value !== x) {
37685 return value == null
37686 ? valueNull : (typeof value === 'function'
37687 ? valueFunction : valueConstant);
37690 if (arguments.length === 1) {
37691 return selection.property('value');
37694 return selection.each(d3_selection_value(value));
37697 function validationDeprecatedTag() {
37699 var validation = function(changes) {
37701 for (var i = 0; i < changes.created.length; i++) {
37702 var change = changes.created[i],
37703 deprecatedTags = change.deprecatedTags();
37705 if (!lodash.isEmpty(deprecatedTags)) {
37706 var tags = utilTagText({ tags: deprecatedTags });
37708 id: 'deprecated_tags',
37709 message: t('validations.deprecated_tags', { tags: tags }),
37722 function validationManyDeletions() {
37723 var threshold = 100;
37725 var validation = function(changes) {
37727 if (changes.deleted.length > threshold) {
37729 id: 'many_deletions',
37730 message: t('validations.many_deletions', { n: changes.deleted.length })
37741 function validationMissingTag() {
37743 // Slightly stricter check than Entity#isUsed (#3091)
37744 function hasTags(entity, graph) {
37745 return lodash.without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
37746 graph.parentRelations(entity).length > 0;
37749 var validation = function(changes, graph) {
37751 for (var i = 0; i < changes.created.length; i++) {
37752 var change = changes.created[i],
37753 geometry = change.geometry(graph);
37755 if ((geometry === 'point' || geometry === 'line' || geometry === 'area') && !hasTags(change, graph)) {
37758 message: t('validations.untagged_' + geometry),
37759 tooltip: t('validations.untagged_' + geometry + '_tooltip'),
37772 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
37773 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
37774 function validationTagSuggestsArea() {
37776 function tagSuggestsArea(tags) {
37777 if (lodash.isEmpty(tags)) return false;
37779 var presence = ['landuse', 'amenities', 'tourism', 'shop'];
37780 for (var i = 0; i < presence.length; i++) {
37781 if (tags[presence[i]] !== undefined) {
37782 return presence[i] + '=' + tags[presence[i]];
37786 if (tags.building && tags.building === 'yes') return 'building=yes';
37790 var validation = function(changes, graph) {
37792 for (var i = 0; i < changes.created.length; i++) {
37793 var change = changes.created[i],
37794 geometry = change.geometry(graph),
37795 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
37799 id: 'tag_suggests_area',
37800 message: t('validations.tag_suggests_area', { tag: suggestion }),
37815 var Validations = Object.freeze({
37816 validationDeprecatedTag: validationDeprecatedTag,
37817 validationManyDeletions: validationManyDeletions,
37818 validationMissingTag: validationMissingTag,
37819 validationTagSuggestsArea: validationTagSuggestsArea
37823 iD.Difference represents the difference between two graphs.
37824 It knows how to calculate the set of entities that were
37825 created, modified, or deleted, and also contains the logic
37826 for recursively extending a difference to the complete set
37827 of entities that will require a redraw, taking into account
37828 child and parent relationships.
37830 function coreDifference(base, head) {
37836 function changed(h, b) {
37837 return h !== b && !lodash.isEqual(lodash.omit(h, 'v'), lodash.omit(b, 'v'));
37841 lodash.each(head.entities, function(h, id) {
37842 var b = base.entities[id];
37843 if (changed(h, b)) {
37844 changes[id] = {base: b, head: h};
37850 lodash.each(base.entities, function(b, id) {
37851 var h = head.entities[id];
37852 if (!changes[id] && changed(h, b)) {
37853 changes[id] = {base: b, head: h};
37859 function addParents(parents, result) {
37860 for (var i = 0; i < parents.length; i++) {
37861 var parent = parents[i];
37863 if (parent.id in result)
37866 result[parent.id] = parent;
37867 addParents(head.parentRelations(parent), result);
37872 difference.length = function() {
37877 difference.changes = function() {
37882 difference.extantIDs = function() {
37884 lodash.each(changes, function(change, id) {
37885 if (change.head) result.push(id);
37891 difference.modified = function() {
37893 lodash.each(changes, function(change) {
37894 if (change.base && change.head) result.push(change.head);
37900 difference.created = function() {
37902 lodash.each(changes, function(change) {
37903 if (!change.base && change.head) result.push(change.head);
37909 difference.deleted = function() {
37911 lodash.each(changes, function(change) {
37912 if (change.base && !change.head) result.push(change.base);
37918 difference.summary = function() {
37921 function addEntity(entity, graph, changeType) {
37922 relevant[entity.id] = {
37925 changeType: changeType
37929 function addParents(entity) {
37930 var parents = head.parentWays(entity);
37931 for (var j = parents.length - 1; j >= 0; j--) {
37932 var parent = parents[j];
37933 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
37937 lodash.each(changes, function(change) {
37938 if (change.head && change.head.geometry(head) !== 'vertex') {
37939 addEntity(change.head, head, change.base ? 'modified' : 'created');
37941 } else if (change.base && change.base.geometry(base) !== 'vertex') {
37942 addEntity(change.base, base, 'deleted');
37944 } else if (change.base && change.head) { // modified vertex
37945 var moved = !lodash.isEqual(change.base.loc, change.head.loc),
37946 retagged = !lodash.isEqual(change.base.tags, change.head.tags);
37949 addParents(change.head);
37952 if (retagged || (moved && change.head.hasInterestingTags())) {
37953 addEntity(change.head, head, 'modified');
37956 } else if (change.head && change.head.hasInterestingTags()) { // created vertex
37957 addEntity(change.head, head, 'created');
37959 } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
37960 addEntity(change.base, base, 'deleted');
37964 return values(relevant);
37968 difference.complete = function(extent$$1) {
37969 var result = {}, id, change;
37971 for (id in changes) {
37972 change = changes[id];
37974 var h = change.head,
37979 (!h || !h.intersects(extent$$1, head)) &&
37980 (!b || !b.intersects(extent$$1, base)))
37985 if (entity.type === 'way') {
37986 var nh = h ? h.nodes : [],
37987 nb = b ? b.nodes : [],
37990 diff = lodash.difference(nh, nb);
37991 for (i = 0; i < diff.length; i++) {
37992 result[diff[i]] = head.hasEntity(diff[i]);
37995 diff = lodash.difference(nb, nh);
37996 for (i = 0; i < diff.length; i++) {
37997 result[diff[i]] = head.hasEntity(diff[i]);
38001 addParents(head.parentWays(entity), result);
38002 addParents(head.parentRelations(entity), result);
38012 function coreGraph$$1(other, mutable) {
38013 if (!(this instanceof coreGraph$$1)) return new coreGraph$$1(other, mutable);
38015 if (other instanceof coreGraph$$1) {
38016 var base = other.base();
38017 this.entities = lodash.assign(Object.create(base.entities), other.entities);
38018 this._parentWays = lodash.assign(Object.create(base.parentWays), other._parentWays);
38019 this._parentRels = lodash.assign(Object.create(base.parentRels), other._parentRels);
38022 this.entities = Object.create({});
38023 this._parentWays = Object.create({});
38024 this._parentRels = Object.create({});
38025 this.rebase(other || [], [this]);
38028 this.transients = {};
38029 this._childNodes = {};
38030 this.frozen = !mutable;
38034 coreGraph$$1.prototype = {
38036 hasEntity: function(id) {
38037 return this.entities[id];
38041 entity: function(id) {
38042 var entity = this.entities[id];
38044 throw new Error('entity ' + id + ' not found');
38050 transient: function(entity, key, fn) {
38051 var id = entity.id,
38052 transients = this.transients[id] ||
38053 (this.transients[id] = {});
38055 if (transients[key] !== undefined) {
38056 return transients[key];
38059 transients[key] = fn.call(entity);
38061 return transients[key];
38065 parentWays: function(entity) {
38066 var parents = this._parentWays[entity.id],
38070 for (var i = 0; i < parents.length; i++) {
38071 result.push(this.entity(parents[i]));
38078 isPoi: function(entity) {
38079 var parentWays = this._parentWays[entity.id];
38080 return !parentWays || parentWays.length === 0;
38084 isShared: function(entity) {
38085 var parentWays = this._parentWays[entity.id];
38086 return parentWays && parentWays.length > 1;
38090 parentRelations: function(entity) {
38091 var parents = this._parentRels[entity.id],
38095 for (var i = 0; i < parents.length; i++) {
38096 result.push(this.entity(parents[i]));
38103 childNodes: function(entity) {
38104 if (this._childNodes[entity.id]) return this._childNodes[entity.id];
38105 if (!entity.nodes) return [];
38108 for (var i = 0; i < entity.nodes.length; i++) {
38109 nodes[i] = this.entity(entity.nodes[i]);
38112 if (debug) Object.freeze(nodes);
38114 this._childNodes[entity.id] = nodes;
38115 return this._childNodes[entity.id];
38121 'entities': utilGetPrototypeOf(this.entities),
38122 'parentWays': utilGetPrototypeOf(this._parentWays),
38123 'parentRels': utilGetPrototypeOf(this._parentRels)
38128 // Unlike other graph methods, rebase mutates in place. This is because it
38129 // is used only during the history operation that merges newly downloaded
38130 // data into each state. To external consumers, it should appear as if the
38131 // graph always contained the newly downloaded data.
38132 rebase: function(entities, stack, force) {
38133 var base = this.base(),
38136 for (i = 0; i < entities.length; i++) {
38137 var entity = entities[i];
38139 if (!entity.visible || (!force && base.entities[entity.id]))
38142 // Merging data into the base graph
38143 base.entities[entity.id] = entity;
38144 this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
38146 // Restore provisionally-deleted nodes that are discovered to have an extant parent
38147 if (entity.type === 'way') {
38148 for (j = 0; j < entity.nodes.length; j++) {
38149 id = entity.nodes[j];
38150 for (k = 1; k < stack.length; k++) {
38151 var ents = stack[k].entities;
38152 if (ents.hasOwnProperty(id) && ents[id] === undefined) {
38160 for (i = 0; i < stack.length; i++) {
38161 stack[i]._updateRebased();
38166 _updateRebased: function() {
38167 var base = this.base(),
38168 i, k, child, id, keys;
38170 keys = Object.keys(this._parentWays);
38171 for (i = 0; i < keys.length; i++) {
38173 if (base.parentWays[child]) {
38174 for (k = 0; k < base.parentWays[child].length; k++) {
38175 id = base.parentWays[child][k];
38176 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentWays[child], id)) {
38177 this._parentWays[child].push(id);
38183 keys = Object.keys(this._parentRels);
38184 for (i = 0; i < keys.length; i++) {
38186 if (base.parentRels[child]) {
38187 for (k = 0; k < base.parentRels[child].length; k++) {
38188 id = base.parentRels[child][k];
38189 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentRels[child], id)) {
38190 this._parentRels[child].push(id);
38196 this.transients = {};
38198 // this._childNodes is not updated, under the assumption that
38199 // ways are always downloaded with their child nodes.
38203 // Updates calculated properties (parentWays, parentRels) for the specified change
38204 _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
38206 parentWays = parentWays || this._parentWays;
38207 parentRels = parentRels || this._parentRels;
38209 var type = entity && entity.type || oldentity && oldentity.type,
38210 removed, added, ways, rels, i;
38213 if (type === 'way') {
38215 // Update parentWays
38216 if (oldentity && entity) {
38217 removed = lodash.difference(oldentity.nodes, entity.nodes);
38218 added = lodash.difference(entity.nodes, oldentity.nodes);
38219 } else if (oldentity) {
38220 removed = oldentity.nodes;
38222 } else if (entity) {
38224 added = entity.nodes;
38226 for (i = 0; i < removed.length; i++) {
38227 parentWays[removed[i]] = lodash.without(parentWays[removed[i]], oldentity.id);
38229 for (i = 0; i < added.length; i++) {
38230 ways = lodash.without(parentWays[added[i]], entity.id);
38231 ways.push(entity.id);
38232 parentWays[added[i]] = ways;
38235 } else if (type === 'relation') {
38237 // Update parentRels
38238 if (oldentity && entity) {
38239 removed = lodash.difference(oldentity.members, entity.members);
38240 added = lodash.difference(entity.members, oldentity);
38241 } else if (oldentity) {
38242 removed = oldentity.members;
38244 } else if (entity) {
38246 added = entity.members;
38248 for (i = 0; i < removed.length; i++) {
38249 parentRels[removed[i].id] = lodash.without(parentRels[removed[i].id], oldentity.id);
38251 for (i = 0; i < added.length; i++) {
38252 rels = lodash.without(parentRels[added[i].id], entity.id);
38253 rels.push(entity.id);
38254 parentRels[added[i].id] = rels;
38260 replace: function(entity) {
38261 if (this.entities[entity.id] === entity)
38264 return this.update(function() {
38265 this._updateCalculated(this.entities[entity.id], entity);
38266 this.entities[entity.id] = entity;
38271 remove: function(entity) {
38272 return this.update(function() {
38273 this._updateCalculated(entity, undefined);
38274 this.entities[entity.id] = undefined;
38279 revert: function(id) {
38280 var baseEntity = this.base().entities[id],
38281 headEntity = this.entities[id];
38283 if (headEntity === baseEntity)
38286 return this.update(function() {
38287 this._updateCalculated(headEntity, baseEntity);
38288 delete this.entities[id];
38293 update: function() {
38294 var graph = this.frozen ? coreGraph$$1(this, true) : this;
38296 for (var i = 0; i < arguments.length; i++) {
38297 arguments[i].call(graph, graph);
38300 if (this.frozen) graph.frozen = true;
38306 // Obliterates any existing entities
38307 load: function(entities) {
38308 var base = this.base();
38309 this.entities = Object.create(base.entities);
38311 for (var i in entities) {
38312 this.entities[i] = entities[i];
38313 this._updateCalculated(base.entities[i], this.entities[i]);
38320 var index$9 = partialSort;
38322 // Floyd-Rivest selection algorithm:
38323 // Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right];
38324 // The k-th element will have the (k - left + 1)th smallest value in [left, right]
38326 function partialSort(arr, k, left, right, compare) {
38328 right = right || (arr.length - 1);
38329 compare = compare || defaultCompare;
38331 while (right > left) {
38332 if (right - left > 600) {
38333 var n = right - left + 1;
38334 var m = k - left + 1;
38335 var z = Math.log(n);
38336 var s = 0.5 * Math.exp(2 * z / 3);
38337 var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
38338 var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
38339 var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
38340 partialSort(arr, k, newLeft, newRight, compare);
38347 swap(arr, left, k);
38348 if (compare(arr[right], t) > 0) swap(arr, left, right);
38354 while (compare(arr[i], t) < 0) i++;
38355 while (compare(arr[j], t) > 0) j--;
38358 if (compare(arr[left], t) === 0) swap(arr, left, j);
38361 swap(arr, j, right);
38364 if (j <= k) left = j + 1;
38365 if (k <= j) right = j - 1;
38369 function swap(arr, i, j) {
38375 function defaultCompare(a, b) {
38376 return a < b ? -1 : a > b ? 1 : 0;
38379 var index$8 = rbush;
38381 var quickselect = index$9;
38383 function rbush(maxEntries, format) {
38384 if (!(this instanceof rbush)) return new rbush(maxEntries, format);
38386 // max entries in a node is 9 by default; min node fill is 40% for best performance
38387 this._maxEntries = Math.max(4, maxEntries || 9);
38388 this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
38391 this._initFormat(format);
38397 rbush.prototype = {
38400 return this._all(this.data, []);
38403 search: function (bbox) {
38405 var node = this.data,
38407 toBBox = this.toBBox;
38409 if (!intersects$1(bbox, node)) return result;
38411 var nodesToSearch = [],
38412 i, len, child, childBBox;
38415 for (i = 0, len = node.children.length; i < len; i++) {
38417 child = node.children[i];
38418 childBBox = node.leaf ? toBBox(child) : child;
38420 if (intersects$1(bbox, childBBox)) {
38421 if (node.leaf) result.push(child);
38422 else if (contains$1(bbox, childBBox)) this._all(child, result);
38423 else nodesToSearch.push(child);
38426 node = nodesToSearch.pop();
38432 collides: function (bbox) {
38434 var node = this.data,
38435 toBBox = this.toBBox;
38437 if (!intersects$1(bbox, node)) return false;
38439 var nodesToSearch = [],
38440 i, len, child, childBBox;
38443 for (i = 0, len = node.children.length; i < len; i++) {
38445 child = node.children[i];
38446 childBBox = node.leaf ? toBBox(child) : child;
38448 if (intersects$1(bbox, childBBox)) {
38449 if (node.leaf || contains$1(bbox, childBBox)) return true;
38450 nodesToSearch.push(child);
38453 node = nodesToSearch.pop();
38459 load: function (data) {
38460 if (!(data && data.length)) return this;
38462 if (data.length < this._minEntries) {
38463 for (var i = 0, len = data.length; i < len; i++) {
38464 this.insert(data[i]);
38469 // recursively build the tree with the given data from stratch using OMT algorithm
38470 var node = this._build(data.slice(), 0, data.length - 1, 0);
38472 if (!this.data.children.length) {
38473 // save as is if tree is empty
38476 } else if (this.data.height === node.height) {
38477 // split root if trees have the same height
38478 this._splitRoot(this.data, node);
38481 if (this.data.height < node.height) {
38482 // swap trees if inserted one is bigger
38483 var tmpNode = this.data;
38488 // insert the small tree into the large tree at appropriate level
38489 this._insert(node, this.data.height - node.height - 1, true);
38495 insert: function (item) {
38496 if (item) this._insert(item, this.data.height - 1);
38500 clear: function () {
38501 this.data = createNode([]);
38505 remove: function (item, equalsFn) {
38506 if (!item) return this;
38508 var node = this.data,
38509 bbox = this.toBBox(item),
38512 i, parent, index, goingUp;
38514 // depth-first iterative tree traversal
38515 while (node || path.length) {
38517 if (!node) { // go up
38519 parent = path[path.length - 1];
38524 if (node.leaf) { // check current node
38525 index = findItem(item, node.children, equalsFn);
38527 if (index !== -1) {
38528 // item found, remove the item and condense tree upwards
38529 node.children.splice(index, 1);
38531 this._condense(path);
38536 if (!goingUp && !node.leaf && contains$1(node, bbox)) { // go down
38541 node = node.children[0];
38543 } else if (parent) { // go right
38545 node = parent.children[i];
38548 } else node = null; // nothing found
38554 toBBox: function (item) { return item; },
38556 compareMinX: compareNodeMinX,
38557 compareMinY: compareNodeMinY,
38559 toJSON: function () { return this.data; },
38561 fromJSON: function (data) {
38566 _all: function (node, result) {
38567 var nodesToSearch = [];
38569 if (node.leaf) result.push.apply(result, node.children);
38570 else nodesToSearch.push.apply(nodesToSearch, node.children);
38572 node = nodesToSearch.pop();
38577 _build: function (items, left, right, height) {
38579 var N = right - left + 1,
38580 M = this._maxEntries,
38584 // reached leaf level; return leaf
38585 node = createNode(items.slice(left, right + 1));
38586 calcBBox(node, this.toBBox);
38591 // target height of the bulk-loaded tree
38592 height = Math.ceil(Math.log(N) / Math.log(M));
38594 // target number of root entries to maximize storage utilization
38595 M = Math.ceil(N / Math.pow(M, height - 1));
38598 node = createNode([]);
38600 node.height = height;
38602 // split the items into M mostly square tiles
38604 var N2 = Math.ceil(N / M),
38605 N1 = N2 * Math.ceil(Math.sqrt(M)),
38606 i, j, right2, right3;
38608 multiSelect(items, left, right, N1, this.compareMinX);
38610 for (i = left; i <= right; i += N1) {
38612 right2 = Math.min(i + N1 - 1, right);
38614 multiSelect(items, i, right2, N2, this.compareMinY);
38616 for (j = i; j <= right2; j += N2) {
38618 right3 = Math.min(j + N2 - 1, right2);
38620 // pack each entry recursively
38621 node.children.push(this._build(items, j, right3, height - 1));
38625 calcBBox(node, this.toBBox);
38630 _chooseSubtree: function (bbox, node, level, path) {
38632 var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
38637 if (node.leaf || path.length - 1 === level) break;
38639 minArea = minEnlargement = Infinity;
38641 for (i = 0, len = node.children.length; i < len; i++) {
38642 child = node.children[i];
38643 area = bboxArea(child);
38644 enlargement = enlargedArea(bbox, child) - area;
38646 // choose entry with the least area enlargement
38647 if (enlargement < minEnlargement) {
38648 minEnlargement = enlargement;
38649 minArea = area < minArea ? area : minArea;
38650 targetNode = child;
38652 } else if (enlargement === minEnlargement) {
38653 // otherwise choose one with the smallest area
38654 if (area < minArea) {
38656 targetNode = child;
38661 node = targetNode || node.children[0];
38667 _insert: function (item, level, isNode) {
38669 var toBBox = this.toBBox,
38670 bbox = isNode ? item : toBBox(item),
38673 // find the best node for accommodating the item, saving all nodes along the path too
38674 var node = this._chooseSubtree(bbox, this.data, level, insertPath);
38676 // put the item into the node
38677 node.children.push(item);
38678 extend$1(node, bbox);
38680 // split on node overflow; propagate upwards if necessary
38681 while (level >= 0) {
38682 if (insertPath[level].children.length > this._maxEntries) {
38683 this._split(insertPath, level);
38688 // adjust bboxes along the insertion path
38689 this._adjustParentBBoxes(bbox, insertPath, level);
38692 // split overflowed node into two
38693 _split: function (insertPath, level) {
38695 var node = insertPath[level],
38696 M = node.children.length,
38697 m = this._minEntries;
38699 this._chooseSplitAxis(node, m, M);
38701 var splitIndex = this._chooseSplitIndex(node, m, M);
38703 var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
38704 newNode.height = node.height;
38705 newNode.leaf = node.leaf;
38707 calcBBox(node, this.toBBox);
38708 calcBBox(newNode, this.toBBox);
38710 if (level) insertPath[level - 1].children.push(newNode);
38711 else this._splitRoot(node, newNode);
38714 _splitRoot: function (node, newNode) {
38716 this.data = createNode([node, newNode]);
38717 this.data.height = node.height + 1;
38718 this.data.leaf = false;
38719 calcBBox(this.data, this.toBBox);
38722 _chooseSplitIndex: function (node, m, M) {
38724 var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
38726 minOverlap = minArea = Infinity;
38728 for (i = m; i <= M - m; i++) {
38729 bbox1 = distBBox(node, 0, i, this.toBBox);
38730 bbox2 = distBBox(node, i, M, this.toBBox);
38732 overlap = intersectionArea(bbox1, bbox2);
38733 area = bboxArea(bbox1) + bboxArea(bbox2);
38735 // choose distribution with minimum overlap
38736 if (overlap < minOverlap) {
38737 minOverlap = overlap;
38740 minArea = area < minArea ? area : minArea;
38742 } else if (overlap === minOverlap) {
38743 // otherwise choose distribution with minimum area
38744 if (area < minArea) {
38754 // sorts node children by the best axis for split
38755 _chooseSplitAxis: function (node, m, M) {
38757 var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
38758 compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
38759 xMargin = this._allDistMargin(node, m, M, compareMinX),
38760 yMargin = this._allDistMargin(node, m, M, compareMinY);
38762 // if total distributions margin value is minimal for x, sort by minX,
38763 // otherwise it's already sorted by minY
38764 if (xMargin < yMargin) node.children.sort(compareMinX);
38767 // total margin of all possible split distributions where each node is at least m full
38768 _allDistMargin: function (node, m, M, compare) {
38770 node.children.sort(compare);
38772 var toBBox = this.toBBox,
38773 leftBBox = distBBox(node, 0, m, toBBox),
38774 rightBBox = distBBox(node, M - m, M, toBBox),
38775 margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
38778 for (i = m; i < M - m; i++) {
38779 child = node.children[i];
38780 extend$1(leftBBox, node.leaf ? toBBox(child) : child);
38781 margin += bboxMargin(leftBBox);
38784 for (i = M - m - 1; i >= m; i--) {
38785 child = node.children[i];
38786 extend$1(rightBBox, node.leaf ? toBBox(child) : child);
38787 margin += bboxMargin(rightBBox);
38793 _adjustParentBBoxes: function (bbox, path, level) {
38794 // adjust bboxes along the given tree path
38795 for (var i = level; i >= 0; i--) {
38796 extend$1(path[i], bbox);
38800 _condense: function (path) {
38801 // go through the path, removing empty nodes and updating bboxes
38802 for (var i = path.length - 1, siblings; i >= 0; i--) {
38803 if (path[i].children.length === 0) {
38805 siblings = path[i - 1].children;
38806 siblings.splice(siblings.indexOf(path[i]), 1);
38808 } else this.clear();
38810 } else calcBBox(path[i], this.toBBox);
38814 _initFormat: function (format) {
38815 // data format (minX, minY, maxX, maxY accessors)
38817 // uses eval-type function compilation instead of just accepting a toBBox function
38818 // because the algorithms are very sensitive to sorting functions performance,
38819 // so they should be dead simple and without inner calls
38821 var compareArr = ['return a', ' - b', ';'];
38823 this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
38824 this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
38826 this.toBBox = new Function('a',
38827 'return {minX: a' + format[0] +
38828 ', minY: a' + format[1] +
38829 ', maxX: a' + format[2] +
38830 ', maxY: a' + format[3] + '};');
38834 function findItem(item, items, equalsFn) {
38835 if (!equalsFn) return items.indexOf(item);
38837 for (var i = 0; i < items.length; i++) {
38838 if (equalsFn(item, items[i])) return i;
38843 // calculate node's bbox from bboxes of its children
38844 function calcBBox(node, toBBox) {
38845 distBBox(node, 0, node.children.length, toBBox, node);
38848 // min bounding rectangle of node children from k to p-1
38849 function distBBox(node, k, p, toBBox, destNode) {
38850 if (!destNode) destNode = createNode(null);
38851 destNode.minX = Infinity;
38852 destNode.minY = Infinity;
38853 destNode.maxX = -Infinity;
38854 destNode.maxY = -Infinity;
38856 for (var i = k, child; i < p; i++) {
38857 child = node.children[i];
38858 extend$1(destNode, node.leaf ? toBBox(child) : child);
38864 function extend$1(a, b) {
38865 a.minX = Math.min(a.minX, b.minX);
38866 a.minY = Math.min(a.minY, b.minY);
38867 a.maxX = Math.max(a.maxX, b.maxX);
38868 a.maxY = Math.max(a.maxY, b.maxY);
38872 function compareNodeMinX(a, b) { return a.minX - b.minX; }
38873 function compareNodeMinY(a, b) { return a.minY - b.minY; }
38875 function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }
38876 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
38878 function enlargedArea(a, b) {
38879 return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
38880 (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
38883 function intersectionArea(a, b) {
38884 var minX = Math.max(a.minX, b.minX),
38885 minY = Math.max(a.minY, b.minY),
38886 maxX = Math.min(a.maxX, b.maxX),
38887 maxY = Math.min(a.maxY, b.maxY);
38889 return Math.max(0, maxX - minX) *
38890 Math.max(0, maxY - minY);
38893 function contains$1(a, b) {
38894 return a.minX <= b.minX &&
38895 a.minY <= b.minY &&
38896 b.maxX <= a.maxX &&
38900 function intersects$1(a, b) {
38901 return b.minX <= a.maxX &&
38902 b.minY <= a.maxY &&
38903 b.maxX >= a.minX &&
38907 function createNode(children) {
38909 children: children,
38919 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
38920 // combines selection algorithm with binary divide & conquer approach
38922 function multiSelect(arr, left, right, n, compare) {
38923 var stack = [left, right],
38926 while (stack.length) {
38927 right = stack.pop();
38928 left = stack.pop();
38930 if (right - left <= n) continue;
38932 mid = left + Math.ceil((right - left) / n / 2) * n;
38933 quickselect(arr, mid, left, right, compare);
38935 stack.push(left, mid, mid, right);
38939 function coreTree(head) {
38940 var rtree = index$8(),
38945 function entityBBox(entity) {
38946 var bbox = entity.extent(head).bbox();
38947 bbox.id = entity.id;
38948 bboxes[entity.id] = bbox;
38953 function updateParents(entity, insertions, memo) {
38954 head.parentWays(entity).forEach(function(way) {
38955 if (bboxes[way.id]) {
38956 rtree.remove(bboxes[way.id]);
38957 insertions[way.id] = way;
38959 updateParents(way, insertions, memo);
38962 head.parentRelations(entity).forEach(function(relation) {
38963 if (memo[entity.id]) return;
38964 memo[entity.id] = true;
38965 if (bboxes[relation.id]) {
38966 rtree.remove(bboxes[relation.id]);
38967 insertions[relation.id] = relation;
38969 updateParents(relation, insertions, memo);
38974 tree.rebase = function(entities, force) {
38975 var insertions = {};
38977 for (var i = 0; i < entities.length; i++) {
38978 var entity = entities[i];
38980 if (!entity.visible)
38983 if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
38986 } else if (bboxes[entity.id]) {
38987 rtree.remove(bboxes[entity.id]);
38991 insertions[entity.id] = entity;
38992 updateParents(entity, insertions, {});
38995 rtree.load(lodash.map(insertions, entityBBox));
39001 tree.intersects = function(extent, graph) {
39002 if (graph !== head) {
39003 var diff = coreDifference(head, graph),
39008 diff.deleted().forEach(function(entity) {
39009 rtree.remove(bboxes[entity.id]);
39010 delete bboxes[entity.id];
39013 diff.modified().forEach(function(entity) {
39014 rtree.remove(bboxes[entity.id]);
39015 insertions[entity.id] = entity;
39016 updateParents(entity, insertions, {});
39019 diff.created().forEach(function(entity) {
39020 insertions[entity.id] = entity;
39023 rtree.load(lodash.map(insertions, entityBBox));
39026 return rtree.search(extent.bbox()).map(function(bbox) {
39027 return head.entity(bbox.id);
39036 * This code is licensed under the MIT license.
39038 * Copyright © 2013, iD authors.
39040 * Portions copyright © 2011, Keith Cirkel
39041 * See https://github.com/keithamus/jwerty
39044 function d3keybinding(namespace$$1) {
39047 function matches(binding, event$$1) {
39048 for (var p in binding.event) {
39049 if (event$$1[p] !== binding.event[p])
39055 function testBindings(isCapturing) {
39056 for (var i = 0; i < bindings.length; i++) {
39057 var binding = bindings[i];
39059 if (!!binding.capture === isCapturing && matches(binding, event)) {
39060 binding.callback();
39065 function capture() {
39066 testBindings(true);
39069 function bubble() {
39070 var tagName = select(event.target).node().tagName;
39071 if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
39074 testBindings(false);
39077 function keybinding(selection$$1) {
39078 selection$$1 = selection$$1 || select(document);
39079 selection$$1.on('keydown.capture' + namespace$$1, capture, true);
39080 selection$$1.on('keydown.bubble' + namespace$$1, bubble, false);
39084 keybinding.off = function(selection$$1) {
39086 selection$$1 = selection$$1 || select(document);
39087 selection$$1.on('keydown.capture' + namespace$$1, null);
39088 selection$$1.on('keydown.bubble' + namespace$$1, null);
39092 keybinding.on = function(codes, callback, capture) {
39093 var arr = [].concat(codes);
39094 for (var i = 0; i < arr.length; i++) {
39108 code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
39110 for (var j = 0; j < code.length; j++) {
39111 // Normalise matching errors
39112 if (code[j] === '++') code[i] = '+';
39114 if (code[j] in d3keybinding.modifierCodes) {
39115 binding.event[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
39116 } else if (code[j] in d3keybinding.keyCodes) {
39117 binding.event.keyCode = d3keybinding.keyCodes[code[j]];
39121 bindings.push(binding);
39131 d3keybinding.modifierCodes = {
39133 '⇧': 16, shift: 16,
39134 // CTRL key, on Mac: ⌃
39136 // ALT key, on Mac: ⌥ (Alt)
39137 '⌥': 18, alt: 18, option: 18,
39138 // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
39139 '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
39142 d3keybinding.modifierProperties = {
39149 d3keybinding.keyCodes = {
39150 // Backspace key, on Mac: ⌫ (Backspace)
39151 '⌫': 8, backspace: 8,
39152 // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
39153 '⇥': 9, '⇆': 9, tab: 9,
39155 '↩': 13, 'return': 13, enter: 13, '⌅': 13,
39157 'pause': 19, 'pause-break': 19,
39158 // Caps Lock key, ⇪
39159 '⇪': 20, caps: 20, 'caps-lock': 20,
39160 // Escape key, on Mac: ⎋, on Windows: Esc
39161 '⎋': 27, escape: 27, esc: 27,
39164 // Page-Up key, or pgup, on Mac: ↖
39165 '↖': 33, pgup: 33, 'page-up': 33,
39166 // Page-Down key, or pgdown, on Mac: ↘
39167 '↘': 34, pgdown: 34, 'page-down': 34,
39168 // END key, on Mac: ⇟
39170 // HOME key, on Mac: ⇞
39172 // Insert key, or ins
39173 ins: 45, insert: 45,
39174 // Delete key, on Mac: ⌦ (Delete)
39175 '⌦': 46, del: 46, 'delete': 46,
39176 // Left Arrow Key, or ←
39177 '←': 37, left: 37, 'arrow-left': 37,
39178 // Up Arrow Key, or ↑
39179 '↑': 38, up: 38, 'arrow-up': 38,
39180 // Right Arrow Key, or →
39181 '→': 39, right: 39, 'arrow-right': 39,
39182 // Up Arrow Key, or ↓
39183 '↓': 40, down: 40, 'arrow-down': 40,
39184 // odities, printing characters that come out wrong:
39187 // Num-Multiply, or *
39188 '*': 106, star: 106, asterisk: 106, multiply: 106,
39190 '+': 107, 'plus': 107,
39191 // Num-Subtract, or -
39192 '-': 109, subtract: 109,
39198 ';': 186, semicolon: 186,
39200 '=': 187, 'equals': 187,
39202 ',': 188, comma: 188,
39203 // Dash / Underscore key
39205 // Period, or ., or full-stop
39206 '.': 190, period: 190, 'full-stop': 190,
39207 // Slash, or /, or forward-slash
39208 '/': 191, slash: 191, 'forward-slash': 191,
39209 // Tick, or `, or back-quote
39210 '`': 192, tick: 192, 'back-quote': 192,
39211 // Open bracket, or [
39212 '[': 219, 'open-bracket': 219,
39213 // Back slash, or \
39214 '\\': 220, 'back-slash': 220,
39215 // Close backet, or ]
39216 ']': 221, 'close-bracket': 221,
39217 // Apostrophe, or Quote, or '
39218 '\'': 222, quote: 222, apostrophe: 222
39224 while (++i$1 < 106) {
39225 d3keybinding.keyCodes['num-' + n] = i$1;
39231 while (++i$1 < 58) {
39232 d3keybinding.keyCodes[n] = i$1;
39238 while (++i$1 < 136) {
39239 d3keybinding.keyCodes['f' + n] = i$1;
39245 while (++i$1 < 91) {
39246 d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
39249 function tooltip() {
39250 var tooltip = function(selection$$1) {
39251 selection$$1.each(setup);
39253 animation = utilFunctor(false),
39254 html$$1 = utilFunctor(false),
39255 title = function() {
39256 var title = this.getAttribute('data-original-title');
39260 title = this.getAttribute('title');
39261 this.removeAttribute('title');
39262 this.setAttribute('data-original-title', title);
39266 over = 'mouseenter.tooltip',
39267 out = 'mouseleave.tooltip',
39268 placement = utilFunctor('top');
39271 tooltip.title = function(_) {
39272 if (arguments.length) {
39273 title = utilFunctor(_);
39281 tooltip.html = function(_) {
39282 if (arguments.length) {
39283 html$$1 = utilFunctor(_);
39291 tooltip.placement = function(_) {
39292 if (arguments.length) {
39293 placement = utilFunctor(_);
39301 tooltip.show = function(selection$$1) {
39302 selection$$1.each(show);
39306 tooltip.hide = function(selection$$1) {
39307 selection$$1.each(hide);
39311 tooltip.toggle = function(selection$$1) {
39312 selection$$1.each(toggle);
39316 tooltip.destroy = function(selection$$1) {
39320 .attr('title', function() {
39321 return this.getAttribute('data-original-title') || this.getAttribute('title');
39323 .attr('data-original-title', null)
39324 .selectAll('.tooltip')
39330 var root = select(this),
39331 animate = animation.apply(this, arguments),
39332 tip = root.selectAll('.tooltip').data([0]);
39334 var enter = tip.enter()
39336 .attr('class', 'tooltip');
39340 .attr('class', 'tooltip-arrow');
39344 .attr('class', 'tooltip-inner');
39350 tip.classed('fade', true);
39353 var place = placement.apply(this, arguments);
39354 tip.classed(place, true);
39356 root.on(over, show);
39357 root.on(out, hide);
39362 var root = select(this),
39363 content = title.apply(this, arguments),
39364 tip = root.selectAll('.tooltip')
39365 .classed('in', true),
39366 markup = html$$1.apply(this, arguments);
39368 tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
39369 var place = placement.apply(this, arguments),
39370 outer = getPosition(root.node()),
39371 inner = getPosition(tip.node()),
39376 pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
39379 pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
39382 pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
39385 pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
39390 tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
39392 tip.style('left', null).style('top', null);
39395 this.tooltipVisible = true;
39400 select(this).selectAll('.tooltip')
39401 .classed('in', false);
39403 this.tooltipVisible = false;
39407 function toggle() {
39408 if (this.tooltipVisible) {
39409 hide.apply(this, arguments);
39411 show.apply(this, arguments);
39419 function getPosition(node) {
39420 var mode = select(node).style('position');
39421 if (mode === 'absolute' || mode === 'static') {
39423 x: node.offsetLeft,
39425 w: node.offsetWidth,
39426 h: node.offsetHeight
39432 w: node.offsetWidth,
39433 h: node.offsetHeight
39438 function svgAreas$$1(projection, context) {
39439 // Patterns only work in Firefox when set directly on element.
39440 // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
39442 wetland: 'wetland',
39445 construction: 'construction',
39446 military: 'construction',
39447 cemetery: 'cemetery',
39448 grave_yard: 'cemetery',
39451 farmland: 'farmland',
39455 var patternKeys = ['landuse', 'natural', 'amenity'];
39458 function setPattern(d) {
39459 for (var i = 0; i < patternKeys.length; i++) {
39460 if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
39461 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
39465 this.style.fill = this.style.stroke = '';
39469 return function drawAreas(selection$$1, graph, entities, filter) {
39470 var path$$1 = svgPath(projection, graph, true),
39474 for (var i = 0; i < entities.length; i++) {
39475 var entity = entities[i];
39476 if (entity.geometry(graph) !== 'area') continue;
39478 multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
39479 if (multipolygon) {
39480 areas[multipolygon.id] = {
39481 entity: multipolygon.mergeTags(entity.tags),
39482 area: Math.abs(entity.area(graph))
39484 } else if (!areas[entity.id]) {
39485 areas[entity.id] = {
39487 area: Math.abs(entity.area(graph))
39492 areas = values(areas).filter(function hasPath(a) { return path$$1(a.entity); });
39493 areas.sort(function areaSort(a, b) { return b.area - a.area; });
39494 areas = lodash.map(areas, 'entity');
39496 var strokes = areas.filter(function(area$$1) {
39497 return area$$1.type === 'way';
39507 var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
39509 .data(data.clip, osmEntity$$1.key);
39514 var clipPathsEnter = clipPaths.enter()
39515 .append('clipPath')
39516 .attr('class', 'clipPath')
39517 .attr('id', function(entity) { return entity.id + '-clippath'; });
39522 clipPaths.merge(clipPathsEnter)
39524 .attr('d', path$$1);
39527 var layer = selection$$1.selectAll('.layer-areas');
39529 var areagroup = layer
39530 .selectAll('g.areagroup')
39531 .data(['fill', 'shadow', 'stroke']);
39533 areagroup = areagroup.enter()
39535 .attr('class', function(d) { return 'areagroup area-' + d; })
39538 var paths = areagroup
39541 .data(function(layer) { return data[layer]; }, osmEntity$$1.key);
39546 var fills = selection$$1.selectAll('.area-fill path.area').nodes();
39548 var bisect$$1 = bisector(function(node) {
39549 return -node.__data__.area(graph);
39552 function sortedByArea(entity) {
39553 if (this._parent.__data__ === 'fill') {
39554 return fills[bisect$$1(fills, -entity.area(graph))];
39558 paths = paths.enter()
39559 .insert('path', sortedByArea)
39561 .each(function(entity) {
39562 var layer = this.parentNode.__data__;
39564 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
39566 if (layer === 'fill') {
39567 this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
39568 setPattern.apply(this, arguments);
39571 .call(svgTagClasses())
39572 .attr('d', path$$1);
39576 function svgDebug(projection, context) {
39578 function multipolygons(imagery) {
39579 return imagery.map(function(data$$1) {
39581 type: 'MultiPolygon',
39582 coordinates: [ data$$1.polygon ]
39587 function drawDebug(selection$$1) {
39588 var showsTile = context.getDebug('tile'),
39589 showsCollision = context.getDebug('collision'),
39590 showsImagery = context.getDebug('imagery'),
39591 showsImperial = context.getDebug('imperial'),
39592 showsDriveLeft = context.getDebug('driveLeft'),
39593 path$$1 = index$5(projection);
39596 var debugData = [];
39598 debugData.push({ class: 'red', label: 'tile' });
39600 if (showsCollision) {
39601 debugData.push({ class: 'yellow', label: 'collision' });
39603 if (showsImagery) {
39604 debugData.push({ class: 'orange', label: 'imagery' });
39606 if (showsImperial) {
39607 debugData.push({ class: 'cyan', label: 'imperial' });
39609 if (showsDriveLeft) {
39610 debugData.push({ class: 'green', label: 'driveLeft' });
39614 var legend = select('#content')
39615 .selectAll('.debug-legend')
39616 .data(debugData.length ? [0] : []);
39621 legend = legend.enter()
39623 .attr('class', 'fillD debug-legend')
39627 var legendItems = legend.selectAll('.debug-legend-item')
39628 .data(debugData, function(d) { return d.label; });
39633 legendItems.enter()
39635 .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
39636 .text(function(d) { return d.label; });
39639 var layer = selection$$1.selectAll('.layer-debug')
39640 .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
39645 layer = layer.enter()
39647 .attr('class', 'layer-debug')
39651 var extent$$1 = context.map().extent(),
39652 dataImagery = data.imagery || [],
39653 availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
39654 if (!source.polygon) return false;
39655 return source.polygon.some(function(polygon) {
39656 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
39660 var imagery = layer.selectAll('path.debug-imagery')
39661 .data(showsImagery ? availableImagery : []);
39668 .attr('class', 'debug-imagery debug orange');
39671 var imperial = layer
39672 .selectAll('path.debug-imperial')
39673 .data(showsImperial ? [dataImperial] : []);
39680 .attr('class', 'debug-imperial debug cyan');
39683 var driveLeft = layer
39684 .selectAll('path.debug-drive-left')
39685 .data(showsDriveLeft ? [dataDriveLeft] : []);
39692 .attr('class', 'debug-drive-left debug green');
39696 layer.selectAll('path')
39697 .attr('d', path$$1);
39701 // This looks strange because `enabled` methods on other layers are
39702 // chainable getter/setters, and this one is just a getter.
39703 drawDebug.enabled = function() {
39704 if (!arguments.length) {
39705 return context.getDebug('tile') ||
39706 context.getDebug('collision') ||
39707 context.getDebug('imagery') ||
39708 context.getDebug('imperial') ||
39709 context.getDebug('driveLeft');
39720 A standalone SVG element that contains only a `defs` sub-element. To be
39721 used once globally, since defs IDs must be unique within a document.
39723 function svgDefs(context) {
39725 function SVGSpriteDefinition(id, href) {
39726 return function(defs) {
39728 .mimeType('image/svg+xml')
39729 .response(function(xhr) { return xhr.responseXML; })
39730 .get(function(err, svg) {
39732 defs.node().appendChild(
39733 select(svg.documentElement).attr('id', id).node()
39740 return function drawDefs(selection$$1) {
39741 var defs = selection$$1.append('defs');
39744 defs.append('marker')
39745 .attr('id', 'oneway-marker')
39746 .attr('viewBox', '0 0 10 10')
39749 .attr('markerWidth', 2)
39750 .attr('markerHeight', 2)
39751 .attr('markerUnits', 'strokeWidth')
39752 .attr('orient', 'auto')
39755 .attr('class', 'oneway')
39756 .attr('d', 'M 5 3 L 0 3 L 0 2 L 5 2 L 5 0 L 10 2.5 L 5 5 z')
39757 .attr('stroke', 'none')
39758 .attr('fill', '#000')
39759 .attr('opacity', '0.5');
39762 var patterns = defs.selectAll('pattern')
39764 // pattern name, pattern image name
39765 ['wetland', 'wetland'],
39766 ['construction', 'construction'],
39767 ['cemetery', 'cemetery'],
39768 ['orchard', 'orchard'],
39769 ['farmland', 'farmland'],
39776 .attr('id', function (d) {
39777 return 'pattern-' + d[0];
39780 .attr('height', 32)
39781 .attr('patternUnits', 'userSpaceOnUse');
39783 patterns.append('rect')
39787 .attr('height', 32)
39788 .attr('class', function (d) {
39789 return 'pattern-color-' + d[0];
39792 patterns.append('image')
39796 .attr('height', 32)
39797 .attr('xlink:href', function (d) {
39798 return context.imagePath('pattern/' + d[1] + '.png');
39803 .data([12, 18, 20, 32, 45])
39805 .append('clipPath')
39806 .attr('id', function (d) {
39807 return 'clip-square-' + d;
39812 .attr('width', function (d) {
39815 .attr('height', function (d) {
39819 defs.call(SVGSpriteDefinition(
39821 context.imagePath('iD-sprite.svg')));
39823 defs.call(SVGSpriteDefinition(
39825 context.imagePath('maki-sprite.svg')));
39829 var sax = createCommonjsModule(function (module, exports) {
39830 //[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
39831 //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
39832 //[5] Name ::= NameStartChar (NameChar)*
39833 var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;//\u10000-\uEFFFF
39834 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]");
39835 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
39836 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
39837 //var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
39839 //S_TAG, S_ATTR, S_EQ, S_V
39840 //S_ATTR_S, S_E, S_S, S_C
39841 var S_TAG = 0;//tag name offerring
39842 var S_ATTR = 1;//attr name offerring
39843 var S_ATTR_S=2;//attr name end and space offer
39844 var S_EQ = 3;//=space?
39845 var S_V = 4;//attr value(no quot value only)
39846 var S_E = 5;//attr value end and no space(quot end)
39847 var S_S = 6;//(attr value end || tag end ) && (space offer)
39848 var S_C = 7;//closed el<el />
39850 function XMLReader(){
39854 XMLReader.prototype = {
39855 parse:function(source,defaultNSMap,entityMap){
39856 var domBuilder = this.domBuilder;
39857 domBuilder.startDocument();
39858 _copy(defaultNSMap ,defaultNSMap = {});
39859 parse(source,defaultNSMap,entityMap,
39860 domBuilder,this.errorHandler);
39861 domBuilder.endDocument();
39864 function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
39865 function fixedFromCharCode(code) {
39866 // String.prototype.fromCharCode does not supports
39867 // > 2 bytes unicode chars directly
39868 if (code > 0xffff) {
39870 var surrogate1 = 0xd800 + (code >> 10)
39871 , surrogate2 = 0xdc00 + (code & 0x3ff);
39873 return String.fromCharCode(surrogate1, surrogate2);
39875 return String.fromCharCode(code);
39878 function entityReplacer(a){
39879 var k = a.slice(1,-1);
39880 if(k in entityMap){
39881 return entityMap[k];
39882 }else if(k.charAt(0) === '#'){
39883 return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
39885 errorHandler.error('entity not found:'+a);
39889 function appendText(end){//has some bugs
39891 var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
39892 locator&&position(start);
39893 domBuilder.characters(xt,0,end-start);
39897 function position(p,m){
39898 while(p>=lineEnd && (m = linePattern.exec(source))){
39899 lineStart = m.index;
39900 lineEnd = lineStart + m[0].length;
39901 locator.lineNumber++;
39902 //console.log('line++:',locator,startPos,endPos)
39904 locator.columnNumber = p-lineStart+1;
39908 var linePattern = /.+(?:\r\n?|\n)|.*$/g;
39909 var locator = domBuilder.locator;
39911 var parseStack = [{currentNSMap:defaultNSMapCopy}];
39916 var tagStart = source.indexOf('<',start);
39918 if(!source.substr(start).match(/^\s*$/)){
39919 var doc = domBuilder.document;
39920 var text = doc.createTextNode(source.substr(start));
39921 doc.appendChild(text);
39922 domBuilder.currentElement = text;
39926 if(tagStart>start){
39927 appendText(tagStart);
39929 switch(source.charAt(tagStart+1)){
39931 var end = source.indexOf('>',tagStart+3);
39932 var tagName = source.substring(tagStart+2,end);
39933 var config = parseStack.pop();
39934 var localNSMap = config.localNSMap;
39935 if(config.tagName != tagName){
39936 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
39938 domBuilder.endElement(config.uri,config.localName,tagName);
39940 for(var prefix in localNSMap){
39941 domBuilder.endPrefixMapping(prefix) ;
39947 case '?':// <?...?>
39948 locator&&position(tagStart);
39949 end = parseInstruction(source,tagStart,domBuilder);
39951 case '!':// <!doctype,<![CDATA,<!--
39952 locator&&position(tagStart);
39953 end = parseDCC(source,tagStart,domBuilder,errorHandler);
39957 locator&&position(tagStart);
39959 var el = new ElementAttributes();
39962 var end = parseElementStartPart(source,tagStart,el,entityReplacer,errorHandler);
39963 var len = el.length;
39967 //attribute position fixed
39968 for(var i = 0;i<len;i++){
39970 position(a.offset);
39971 a.offset = copyLocator(locator,{});
39976 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
39978 if(!entityMap.nbsp){
39979 errorHandler.warning('unclosed xml attribute');
39982 appendElement(el,domBuilder,parseStack);
39985 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
39986 end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
39992 errorHandler.error('element parse error: '+e);
39998 //TODO: 这里有可能sax回退,有位置错误风险
39999 appendText(Math.max(tagStart,start)+1);
40003 function copyLocator(f,t){
40004 t.lineNumber = f.lineNumber;
40005 t.columnNumber = f.columnNumber;
40010 * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
40011 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40013 function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
40017 var s = S_TAG;//status
40019 var c = source.charAt(p);
40022 if(s === S_ATTR){//attrName
40023 attrName = source.slice(start,p);
40025 }else if(s === S_ATTR_S){
40028 //fatalError: equal must after attrName or space after attrName
40029 throw new Error('attribute equal must after attrName');
40034 if(s === S_EQ){//equal
40036 p = source.indexOf(c,start);
40038 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40039 el.add(attrName,value,start-1);
40042 //fatalError: no end quot match
40043 throw new Error('attribute value no end \''+c+'\' match');
40045 }else if(s == S_V){
40046 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40047 //console.log(attrName,value,start,p)
40048 el.add(attrName,value,start);
40050 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
40054 //fatalError: no equal before
40055 throw new Error('attribute value must after "="');
40061 el.setTagName(source.slice(start,p));
40073 throw new Error("attribute invalid close char('/')")
40076 case ''://end document
40077 //throw new Error('unexpected end of input')
40078 errorHandler.error('unexpected end of input');
40082 el.setTagName(source.slice(start,p));
40087 case S_V://Compatible state
40089 value = source.slice(start,p);
40090 if(value.slice(-1) === '/'){
40092 value = value.slice(0,-1);
40095 if(s === S_ATTR_S){
40099 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40100 el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
40102 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
40103 el.add(value,value,start);
40107 throw new Error('attribute value missed!!');
40109 // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
40111 /*xml space '\x20' | #x9 | #xD | #xA; */
40115 if(c<= ' '){//space
40118 el.setTagName(source.slice(start,p));//tagName
40122 attrName = source.slice(start,p);
40126 var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40127 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40128 el.add(attrName,value,start);
40140 //S_TAG, S_ATTR, S_EQ, S_V
40141 //S_ATTR_S, S_E, S_S, S_C
40143 //case S_TAG:void();break;
40144 //case S_ATTR:void();break;
40145 //case S_V:void();break;
40147 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!');
40148 el.add(attrName,attrName,start);
40153 errorHandler.warning('attribute space is required"'+attrName+'"!!');
40163 throw new Error("elements closed character '/' and '>' must be connected to");
40171 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40173 function appendElement(el,domBuilder,parseStack){
40174 var tagName = el.tagName;
40175 var localNSMap = null;
40176 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
40180 var qName = a.qName;
40181 var value = a.value;
40182 var nsp = qName.indexOf(':');
40184 var prefix = a.prefix = qName.slice(0,nsp);
40185 var localName = qName.slice(nsp+1);
40186 var nsPrefix = prefix === 'xmlns' && localName;
40190 nsPrefix = qName === 'xmlns' && '';
40192 //can not set prefix,because prefix !== ''
40193 a.localName = localName ;
40194 //prefix == null for no ns prefix attribute
40195 if(nsPrefix !== false){//hack!!
40196 if(localNSMap == null){
40198 //console.log(currentNSMap,0)
40199 _copy(currentNSMap,currentNSMap={});
40200 //console.log(currentNSMap,1)
40202 currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
40203 a.uri = 'http://www.w3.org/2000/xmlns/';
40204 domBuilder.startPrefixMapping(nsPrefix, value);
40210 var prefix = a.prefix;
40211 if(prefix){//no prefix attribute has no namespace
40212 if(prefix === 'xml'){
40213 a.uri = 'http://www.w3.org/XML/1998/namespace';
40214 }if(prefix !== 'xmlns'){
40215 a.uri = currentNSMap[prefix];
40217 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
40221 var nsp = tagName.indexOf(':');
40223 prefix = el.prefix = tagName.slice(0,nsp);
40224 localName = el.localName = tagName.slice(nsp+1);
40226 prefix = null;//important!!
40227 localName = el.localName = tagName;
40229 //no prefix element has default namespace
40230 var ns = el.uri = currentNSMap[prefix || ''];
40231 domBuilder.startElement(ns,localName,tagName,el);
40232 //endPrefixMapping and startPrefixMapping have not any help for dom builder
40233 //localNSMap = null
40235 domBuilder.endElement(ns,localName,tagName);
40237 for(prefix in localNSMap){
40238 domBuilder.endPrefixMapping(prefix);
40242 el.currentNSMap = currentNSMap;
40243 el.localNSMap = localNSMap;
40244 parseStack.push(el);
40247 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
40248 if(/^(?:script|textarea)$/i.test(tagName)){
40249 var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
40250 var text = source.substring(elStartEnd+1,elEndStart);
40251 if(/[&<]/.test(text)){
40252 if(/^script$/i.test(tagName)){
40253 //if(!/\]\]>/.test(text)){
40254 //lexHandler.startCDATA();
40255 domBuilder.characters(text,0,text.length);
40256 //lexHandler.endCDATA();
40259 }//}else{//text area
40260 text = text.replace(/&#?\w+;/g,entityReplacer);
40261 domBuilder.characters(text,0,text.length);
40267 return elStartEnd+1;
40269 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
40270 //if(tagName in closeMap){
40271 var pos = closeMap[tagName];
40273 //console.log(tagName)
40274 pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>');
40276 return pos<elStartEnd;
40279 function _copy(source,target){
40280 for(var n in source){target[n] = source[n];}
40282 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
40283 var next= source.charAt(start+2);
40286 if(source.charAt(start + 3) === '-'){
40287 var end = source.indexOf('-->',start+4);
40288 //append comment source.substring(4,end)//<!--
40290 domBuilder.comment(source,start+4,end-start-4);
40293 errorHandler.error("Unclosed comment");
40301 if(source.substr(start+3,6) == 'CDATA['){
40302 var end = source.indexOf(']]>',start+9);
40303 domBuilder.startCDATA();
40304 domBuilder.characters(source,start+9,end-start-9);
40305 domBuilder.endCDATA();
40309 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
40310 var matchs = split(source,start);
40311 var len = matchs.length;
40312 if(len>1 && /!doctype/i.test(matchs[0][0])){
40313 var name = matchs[1][0];
40314 var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
40315 var sysid = len>4 && matchs[4][0];
40316 var lastMatch = matchs[len-1];
40317 domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
40318 sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
40319 domBuilder.endDTD();
40321 return lastMatch.index+lastMatch[0].length
40329 function parseInstruction(source,start,domBuilder){
40330 var end = source.indexOf('?>',start);
40332 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
40334 var len = match[0].length;
40335 domBuilder.processingInstruction(match[1], match[2]) ;
40347 function ElementAttributes(source){
40350 ElementAttributes.prototype = {
40351 setTagName:function(tagName){
40352 if(!tagNamePattern.test(tagName)){
40353 throw new Error('invalid tagName:'+tagName)
40355 this.tagName = tagName;
40357 add:function(qName,value,offset){
40358 if(!tagNamePattern.test(qName)){
40359 throw new Error('invalid attribute:'+qName)
40361 this[this.length++] = {qName:qName,value:value,offset:offset};
40364 getLocalName:function(i){return this[i].localName},
40365 getOffset:function(i){return this[i].offset},
40366 getQName:function(i){return this[i].qName},
40367 getURI:function(i){return this[i].uri},
40368 getValue:function(i){return this[i].value}
40369 // ,getIndex:function(uri, localName)){
40376 // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
40377 // getType:function(uri,localName){}
40378 // getType:function(i){},
40384 function _set_proto_(thiz,parent){
40385 thiz.__proto__ = parent;
40388 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
40389 _set_proto_ = function(thiz,parent){
40391 p.prototype = parent;
40393 for(parent in thiz){
40394 p[parent] = thiz[parent];
40400 function split(source,start){
40403 var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
40404 reg.lastIndex = start;
40405 reg.exec(source);//skip <
40406 while(match = reg.exec(source)){
40408 if(match[1])return buf;
40412 if(typeof commonjsRequire == 'function'){
40413 exports.XMLReader = XMLReader;
40417 var dom = createCommonjsModule(function (module, exports) {
40420 * Object DOMException
40421 * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
40422 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
40425 function copy(src,dest){
40431 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
40432 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
40434 function _extends(Class,Super){
40435 var pt = Class.prototype;
40437 var ppt = Object.create(Super.prototype);
40438 pt.__proto__ = ppt;
40440 if(!(pt instanceof Super)){
40442 t.prototype = Super.prototype;
40445 Class.prototype = pt = t;
40447 if(pt.constructor != Class){
40448 if(typeof Class != 'function'){
40449 console.error("unknow Class:"+Class);
40451 pt.constructor = Class;
40454 var htmlns = 'http://www.w3.org/1999/xhtml';
40457 var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
40458 var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
40459 var TEXT_NODE = NodeType.TEXT_NODE = 3;
40460 var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
40461 var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
40462 var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
40463 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
40464 var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
40465 var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
40466 var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
40467 var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
40468 var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
40471 var ExceptionCode = {};
40472 var ExceptionMessage = {};
40473 var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
40474 var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
40475 var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
40476 var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
40477 var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
40478 var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
40479 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
40480 var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
40481 var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
40482 var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
40484 var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
40485 var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
40486 var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
40487 var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
40488 var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
40491 function DOMException(code, message) {
40492 if(message instanceof Error){
40493 var error = message;
40496 Error.call(this, ExceptionMessage[code]);
40497 this.message = ExceptionMessage[code];
40498 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
40501 if(message) this.message = this.message + ": " + message;
40504 DOMException.prototype = Error.prototype;
40505 copy(ExceptionCode,DOMException);
40507 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
40508 * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
40509 * The items in the NodeList are accessible via an integral index, starting from 0.
40511 function NodeList() {
40513 NodeList.prototype = {
40515 * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
40520 * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
40522 * @param index unsigned long
40523 * Index into the collection.
40525 * The node at the indexth position in the NodeList, or null if that is not a valid index.
40527 item: function(index) {
40528 return this[index] || null;
40530 toString:function(){
40531 for(var buf = [], i = 0;i<this.length;i++){
40532 serializeToString(this[i],buf);
40534 return buf.join('');
40537 function LiveNodeList(node,refresh){
40539 this._refresh = refresh;
40540 _updateLiveList(this);
40542 function _updateLiveList(list){
40543 var inc = list._node._inc || list._node.ownerDocument._inc;
40544 if(list._inc != inc){
40545 var ls = list._refresh(list._node);
40546 //console.log(ls.length)
40547 __set__(list,'length',ls.length);
40552 LiveNodeList.prototype.item = function(i){
40553 _updateLiveList(this);
40557 _extends(LiveNodeList,NodeList);
40560 * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
40561 * NamedNodeMap objects in the DOM are live.
40562 * used for attributes or DocumentType entities
40564 function NamedNodeMap() {
40567 function _findNodeIndex(list,node){
40568 var i = list.length;
40570 if(list[i] === node){return i}
40574 function _addNamedNode(el,list,newAttr,oldAttr){
40576 list[_findNodeIndex(list,oldAttr)] = newAttr;
40578 list[list.length++] = newAttr;
40581 newAttr.ownerElement = el;
40582 var doc = el.ownerDocument;
40584 oldAttr && _onRemoveAttribute(doc,el,oldAttr);
40585 _onAddAttribute(doc,el,newAttr);
40589 function _removeNamedNode(el,list,attr){
40590 var i = _findNodeIndex(list,attr);
40592 var lastIndex = list.length-1;
40593 while(i<lastIndex){
40594 list[i] = list[++i];
40596 list.length = lastIndex;
40598 var doc = el.ownerDocument;
40600 _onRemoveAttribute(doc,el,attr);
40601 attr.ownerElement = null;
40605 throw DOMException(NOT_FOUND_ERR,new Error())
40608 NamedNodeMap.prototype = {
40610 item:NodeList.prototype.item,
40611 getNamedItem: function(key) {
40612 // if(key.indexOf(':')>0 || key == 'xmlns'){
40615 var i = this.length;
40617 var attr = this[i];
40618 if(attr.nodeName == key){
40623 setNamedItem: function(attr) {
40624 var el = attr.ownerElement;
40625 if(el && el!=this._ownerElement){
40626 throw new DOMException(INUSE_ATTRIBUTE_ERR);
40628 var oldAttr = this.getNamedItem(attr.nodeName);
40629 _addNamedNode(this._ownerElement,this,attr,oldAttr);
40633 setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
40634 var el = attr.ownerElement, oldAttr;
40635 if(el && el!=this._ownerElement){
40636 throw new DOMException(INUSE_ATTRIBUTE_ERR);
40638 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
40639 _addNamedNode(this._ownerElement,this,attr,oldAttr);
40644 removeNamedItem: function(key) {
40645 var attr = this.getNamedItem(key);
40646 _removeNamedNode(this._ownerElement,this,attr);
40650 },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
40653 removeNamedItemNS:function(namespaceURI,localName){
40654 var attr = this.getNamedItemNS(namespaceURI,localName);
40655 _removeNamedNode(this._ownerElement,this,attr);
40658 getNamedItemNS: function(namespaceURI, localName) {
40659 var i = this.length;
40661 var node = this[i];
40662 if(node.localName == localName && node.namespaceURI == namespaceURI){
40670 * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
40672 function DOMImplementation(/* Object */ features) {
40673 this._features = {};
40675 for (var feature in features) {
40676 this._features = features[feature];
40681 DOMImplementation.prototype = {
40682 hasFeature: function(/* string */ feature, /* string */ version) {
40683 var versions = this._features[feature.toLowerCase()];
40684 if (versions && (!version || version in versions)) {
40690 // Introduced in DOM Level 2:
40691 createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
40692 var doc = new Document();
40693 doc.implementation = this;
40694 doc.childNodes = new NodeList();
40695 doc.doctype = doctype;
40697 doc.appendChild(doctype);
40700 var root = doc.createElementNS(namespaceURI,qualifiedName);
40701 doc.appendChild(root);
40705 // Introduced in DOM Level 2:
40706 createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
40707 var node = new DocumentType();
40708 node.name = qualifiedName;
40709 node.nodeName = qualifiedName;
40710 node.publicId = publicId;
40711 node.systemId = systemId;
40712 // Introduced in DOM Level 2:
40713 //readonly attribute DOMString internalSubset;
40716 // readonly attribute NamedNodeMap entities;
40717 // readonly attribute NamedNodeMap notations;
40724 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
40733 previousSibling : null,
40734 nextSibling : null,
40738 ownerDocument : null,
40740 namespaceURI : null,
40743 // Modified in DOM Level 2:
40744 insertBefore:function(newChild, refChild){//raises
40745 return _insertBefore(this,newChild,refChild);
40747 replaceChild:function(newChild, oldChild){//raises
40748 this.insertBefore(newChild,oldChild);
40750 this.removeChild(oldChild);
40753 removeChild:function(oldChild){
40754 return _removeChild(this,oldChild);
40756 appendChild:function(newChild){
40757 return this.insertBefore(newChild,null);
40759 hasChildNodes:function(){
40760 return this.firstChild != null;
40762 cloneNode:function(deep){
40763 return cloneNode(this.ownerDocument||this,this,deep);
40765 // Modified in DOM Level 2:
40766 normalize:function(){
40767 var child = this.firstChild;
40769 var next = child.nextSibling;
40770 if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
40771 this.removeChild(next);
40772 child.appendData(next.data);
40779 // Introduced in DOM Level 2:
40780 isSupported:function(feature, version){
40781 return this.ownerDocument.implementation.hasFeature(feature,version);
40783 // Introduced in DOM Level 2:
40784 hasAttributes:function(){
40785 return this.attributes.length>0;
40787 lookupPrefix:function(namespaceURI){
40790 var map = el._nsMap;
40794 if(map[n] == namespaceURI){
40799 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
40803 // Introduced in DOM Level 3:
40804 lookupNamespaceURI:function(prefix){
40807 var map = el._nsMap;
40811 return map[prefix] ;
40814 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
40818 // Introduced in DOM Level 3:
40819 isDefaultNamespace:function(namespaceURI){
40820 var prefix = this.lookupPrefix(namespaceURI);
40821 return prefix == null;
40826 function _xmlEncoder(c){
40827 return c == '<' && '<' ||
40828 c == '>' && '>' ||
40829 c == '&' && '&' ||
40830 c == '"' && '"' ||
40831 '&#'+c.charCodeAt()+';'
40835 copy(NodeType,Node);
40836 copy(NodeType,Node.prototype);
40839 * @param callback return true for continue,false for break
40840 * @return boolean true: break visit;
40842 function _visitNode(node,callback){
40843 if(callback(node)){
40846 if(node = node.firstChild){
40848 if(_visitNode(node,callback)){return true}
40849 }while(node=node.nextSibling)
40855 function Document(){
40857 function _onAddAttribute(doc,el,newAttr){
40859 var ns = newAttr.namespaceURI;
40860 if(ns == 'http://www.w3.org/2000/xmlns/'){
40862 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
40865 function _onRemoveAttribute(doc,el,newAttr,remove){
40867 var ns = newAttr.namespaceURI;
40868 if(ns == 'http://www.w3.org/2000/xmlns/'){
40870 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
40873 function _onUpdateChild(doc,el,newChild){
40874 if(doc && doc._inc){
40876 //update childNodes
40877 var cs = el.childNodes;
40879 cs[cs.length++] = newChild;
40882 var child = el.firstChild;
40886 child =child.nextSibling;
40897 * writeable properties:
40898 * nodeValue,Attr:value,CharacterData:data
40901 function _removeChild(parentNode,child){
40902 var previous = child.previousSibling;
40903 var next = child.nextSibling;
40905 previous.nextSibling = next;
40907 parentNode.firstChild = next;
40910 next.previousSibling = previous;
40912 parentNode.lastChild = previous;
40914 _onUpdateChild(parentNode.ownerDocument,parentNode);
40918 * preformance key(refChild == null)
40920 function _insertBefore(parentNode,newChild,nextChild){
40921 var cp = newChild.parentNode;
40923 cp.removeChild(newChild);//remove and update
40925 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
40926 var newFirst = newChild.firstChild;
40927 if (newFirst == null) {
40930 var newLast = newChild.lastChild;
40932 newFirst = newLast = newChild;
40934 var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
40936 newFirst.previousSibling = pre;
40937 newLast.nextSibling = nextChild;
40941 pre.nextSibling = newFirst;
40943 parentNode.firstChild = newFirst;
40945 if(nextChild == null){
40946 parentNode.lastChild = newLast;
40948 nextChild.previousSibling = newLast;
40951 newFirst.parentNode = parentNode;
40952 }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
40953 _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
40954 //console.log(parentNode.lastChild.nextSibling == null)
40955 if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
40956 newChild.firstChild = newChild.lastChild = null;
40960 function _appendSingleChild(parentNode,newChild){
40961 var cp = newChild.parentNode;
40963 var pre = parentNode.lastChild;
40964 cp.removeChild(newChild);//remove and update
40965 var pre = parentNode.lastChild;
40967 var pre = parentNode.lastChild;
40968 newChild.parentNode = parentNode;
40969 newChild.previousSibling = pre;
40970 newChild.nextSibling = null;
40972 pre.nextSibling = newChild;
40974 parentNode.firstChild = newChild;
40976 parentNode.lastChild = newChild;
40977 _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
40979 //console.log("__aa",parentNode.lastChild.nextSibling == null)
40981 Document.prototype = {
40982 //implementation : null,
40983 nodeName : '#document',
40984 nodeType : DOCUMENT_NODE,
40986 documentElement : null,
40989 insertBefore : function(newChild, refChild){//raises
40990 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
40991 var child = newChild.firstChild;
40993 var next = child.nextSibling;
40994 this.insertBefore(child,refChild);
40999 if(this.documentElement == null && newChild.nodeType == 1){
41000 this.documentElement = newChild;
41003 return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
41005 removeChild : function(oldChild){
41006 if(this.documentElement == oldChild){
41007 this.documentElement = null;
41009 return _removeChild(this,oldChild);
41011 // Introduced in DOM Level 2:
41012 importNode : function(importedNode,deep){
41013 return importNode(this,importedNode,deep);
41015 // Introduced in DOM Level 2:
41016 getElementById : function(id){
41018 _visitNode(this.documentElement,function(node){
41019 if(node.nodeType == 1){
41020 if(node.getAttribute('id') == id){
41029 //document factory method:
41030 createElement : function(tagName){
41031 var node = new Element();
41032 node.ownerDocument = this;
41033 node.nodeName = tagName;
41034 node.tagName = tagName;
41035 node.childNodes = new NodeList();
41036 var attrs = node.attributes = new NamedNodeMap();
41037 attrs._ownerElement = node;
41040 createDocumentFragment : function(){
41041 var node = new DocumentFragment();
41042 node.ownerDocument = this;
41043 node.childNodes = new NodeList();
41046 createTextNode : function(data){
41047 var node = new Text();
41048 node.ownerDocument = this;
41049 node.appendData(data);
41052 createComment : function(data){
41053 var node = new Comment();
41054 node.ownerDocument = this;
41055 node.appendData(data);
41058 createCDATASection : function(data){
41059 var node = new CDATASection();
41060 node.ownerDocument = this;
41061 node.appendData(data);
41064 createProcessingInstruction : function(target,data){
41065 var node = new ProcessingInstruction();
41066 node.ownerDocument = this;
41067 node.tagName = node.target = target;
41068 node.nodeValue= node.data = data;
41071 createAttribute : function(name){
41072 var node = new Attr();
41073 node.ownerDocument = this;
41075 node.nodeName = name;
41076 node.localName = name;
41077 node.specified = true;
41080 createEntityReference : function(name){
41081 var node = new EntityReference();
41082 node.ownerDocument = this;
41083 node.nodeName = name;
41086 // Introduced in DOM Level 2:
41087 createElementNS : function(namespaceURI,qualifiedName){
41088 var node = new Element();
41089 var pl = qualifiedName.split(':');
41090 var attrs = node.attributes = new NamedNodeMap();
41091 node.childNodes = new NodeList();
41092 node.ownerDocument = this;
41093 node.nodeName = qualifiedName;
41094 node.tagName = qualifiedName;
41095 node.namespaceURI = namespaceURI;
41096 if(pl.length == 2){
41097 node.prefix = pl[0];
41098 node.localName = pl[1];
41100 //el.prefix = null;
41101 node.localName = qualifiedName;
41103 attrs._ownerElement = node;
41106 // Introduced in DOM Level 2:
41107 createAttributeNS : function(namespaceURI,qualifiedName){
41108 var node = new Attr();
41109 var pl = qualifiedName.split(':');
41110 node.ownerDocument = this;
41111 node.nodeName = qualifiedName;
41112 node.name = qualifiedName;
41113 node.namespaceURI = namespaceURI;
41114 node.specified = true;
41115 if(pl.length == 2){
41116 node.prefix = pl[0];
41117 node.localName = pl[1];
41119 //el.prefix = null;
41120 node.localName = qualifiedName;
41125 _extends(Document,Node);
41128 function Element() {
41131 Element.prototype = {
41132 nodeType : ELEMENT_NODE,
41133 hasAttribute : function(name){
41134 return this.getAttributeNode(name)!=null;
41136 getAttribute : function(name){
41137 var attr = this.getAttributeNode(name);
41138 return attr && attr.value || '';
41140 getAttributeNode : function(name){
41141 return this.attributes.getNamedItem(name);
41143 setAttribute : function(name, value){
41144 var attr = this.ownerDocument.createAttribute(name);
41145 attr.value = attr.nodeValue = "" + value;
41146 this.setAttributeNode(attr);
41148 removeAttribute : function(name){
41149 var attr = this.getAttributeNode(name);
41150 attr && this.removeAttributeNode(attr);
41153 //four real opeartion method
41154 appendChild:function(newChild){
41155 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41156 return this.insertBefore(newChild,null);
41158 return _appendSingleChild(this,newChild);
41161 setAttributeNode : function(newAttr){
41162 return this.attributes.setNamedItem(newAttr);
41164 setAttributeNodeNS : function(newAttr){
41165 return this.attributes.setNamedItemNS(newAttr);
41167 removeAttributeNode : function(oldAttr){
41168 return this.attributes.removeNamedItem(oldAttr.nodeName);
41170 //get real attribute name,and remove it by removeAttributeNode
41171 removeAttributeNS : function(namespaceURI, localName){
41172 var old = this.getAttributeNodeNS(namespaceURI, localName);
41173 old && this.removeAttributeNode(old);
41176 hasAttributeNS : function(namespaceURI, localName){
41177 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
41179 getAttributeNS : function(namespaceURI, localName){
41180 var attr = this.getAttributeNodeNS(namespaceURI, localName);
41181 return attr && attr.value || '';
41183 setAttributeNS : function(namespaceURI, qualifiedName, value){
41184 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
41185 attr.value = attr.nodeValue = "" + value;
41186 this.setAttributeNode(attr);
41188 getAttributeNodeNS : function(namespaceURI, localName){
41189 return this.attributes.getNamedItemNS(namespaceURI, localName);
41192 getElementsByTagName : function(tagName){
41193 return new LiveNodeList(this,function(base){
41195 _visitNode(base,function(node){
41196 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
41203 getElementsByTagNameNS : function(namespaceURI, localName){
41204 return new LiveNodeList(this,function(base){
41206 _visitNode(base,function(node){
41207 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
41215 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
41216 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
41219 _extends(Element,Node);
41222 Attr.prototype.nodeType = ATTRIBUTE_NODE;
41223 _extends(Attr,Node);
41226 function CharacterData() {
41228 CharacterData.prototype = {
41230 substringData : function(offset, count) {
41231 return this.data.substring(offset, offset+count);
41233 appendData: function(text) {
41234 text = this.data+text;
41235 this.nodeValue = this.data = text;
41236 this.length = text.length;
41238 insertData: function(offset,text) {
41239 this.replaceData(offset,0,text);
41242 appendChild:function(newChild){
41243 //if(!(newChild instanceof CharacterData)){
41244 throw new Error(ExceptionMessage[3])
41246 return Node.prototype.appendChild.apply(this,arguments)
41248 deleteData: function(offset, count) {
41249 this.replaceData(offset,count,"");
41251 replaceData: function(offset, count, text) {
41252 var start = this.data.substring(0,offset);
41253 var end = this.data.substring(offset+count);
41254 text = start + text + end;
41255 this.nodeValue = this.data = text;
41256 this.length = text.length;
41259 _extends(CharacterData,Node);
41263 nodeName : "#text",
41264 nodeType : TEXT_NODE,
41265 splitText : function(offset) {
41266 var text = this.data;
41267 var newText = text.substring(offset);
41268 text = text.substring(0, offset);
41269 this.data = this.nodeValue = text;
41270 this.length = text.length;
41271 var newNode = this.ownerDocument.createTextNode(newText);
41272 if(this.parentNode){
41273 this.parentNode.insertBefore(newNode, this.nextSibling);
41278 _extends(Text,CharacterData);
41279 function Comment() {
41281 Comment.prototype = {
41282 nodeName : "#comment",
41283 nodeType : COMMENT_NODE
41285 _extends(Comment,CharacterData);
41287 function CDATASection() {
41289 CDATASection.prototype = {
41290 nodeName : "#cdata-section",
41291 nodeType : CDATA_SECTION_NODE
41293 _extends(CDATASection,CharacterData);
41296 function DocumentType() {
41298 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
41299 _extends(DocumentType,Node);
41301 function Notation() {
41303 Notation.prototype.nodeType = NOTATION_NODE;
41304 _extends(Notation,Node);
41306 function Entity() {
41308 Entity.prototype.nodeType = ENTITY_NODE;
41309 _extends(Entity,Node);
41311 function EntityReference() {
41313 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
41314 _extends(EntityReference,Node);
41316 function DocumentFragment() {
41318 DocumentFragment.prototype.nodeName = "#document-fragment";
41319 DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
41320 _extends(DocumentFragment,Node);
41323 function ProcessingInstruction() {
41325 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
41326 _extends(ProcessingInstruction,Node);
41327 function XMLSerializer(){}
41328 XMLSerializer.prototype.serializeToString = function(node,attributeSorter){
41329 return node.toString(attributeSorter);
41331 Node.prototype.toString =function(attributeSorter){
41333 serializeToString(this,buf,attributeSorter);
41334 return buf.join('');
41336 function serializeToString(node,buf,attributeSorter,isHTML){
41337 switch(node.nodeType){
41339 var attrs = node.attributes;
41340 var len = attrs.length;
41341 var child = node.firstChild;
41342 var nodeName = node.tagName;
41343 isHTML = (htmlns === node.namespaceURI) ||isHTML;
41344 buf.push('<',nodeName);
41345 if(attributeSorter){
41346 buf.sort.apply(attrs, attributeSorter);
41348 for(var i=0;i<len;i++){
41349 serializeToString(attrs.item(i),buf,attributeSorter,isHTML);
41351 if(child || isHTML && !/^(?:meta|link|img|br|hr|input|button)$/i.test(nodeName)){
41353 //if is cdata child node
41354 if(isHTML && /^script$/i.test(nodeName)){
41356 buf.push(child.data);
41360 serializeToString(child,buf,attributeSorter,isHTML);
41361 child = child.nextSibling;
41364 buf.push('</',nodeName,'>');
41369 case DOCUMENT_NODE:
41370 case DOCUMENT_FRAGMENT_NODE:
41371 var child = node.firstChild;
41373 serializeToString(child,buf,attributeSorter,isHTML);
41374 child = child.nextSibling;
41377 case ATTRIBUTE_NODE:
41378 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
41380 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
41381 case CDATA_SECTION_NODE:
41382 return buf.push( '<![CDATA[',node.data,']]>');
41384 return buf.push( "<!--",node.data,"-->");
41385 case DOCUMENT_TYPE_NODE:
41386 var pubid = node.publicId;
41387 var sysid = node.systemId;
41388 buf.push('<!DOCTYPE ',node.name);
41390 buf.push(' PUBLIC "',pubid);
41391 if (sysid && sysid!='.') {
41392 buf.push( '" "',sysid);
41395 }else if(sysid && sysid!='.'){
41396 buf.push(' SYSTEM "',sysid,'">');
41398 var sub = node.internalSubset;
41400 buf.push(" [",sub,"]");
41405 case PROCESSING_INSTRUCTION_NODE:
41406 return buf.push( "<?",node.target," ",node.data,"?>");
41407 case ENTITY_REFERENCE_NODE:
41408 return buf.push( '&',node.nodeName,';');
41409 //case ENTITY_NODE:
41410 //case NOTATION_NODE:
41412 buf.push('??',node.nodeName);
41415 function importNode(doc,node,deep){
41417 switch (node.nodeType) {
41419 node2 = node.cloneNode(false);
41420 node2.ownerDocument = doc;
41421 //var attrs = node2.attributes;
41422 //var len = attrs.length;
41423 //for(var i=0;i<len;i++){
41424 //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
41426 case DOCUMENT_FRAGMENT_NODE:
41428 case ATTRIBUTE_NODE:
41431 //case ENTITY_REFERENCE_NODE:
41432 //case PROCESSING_INSTRUCTION_NODE:
41433 ////case TEXT_NODE:
41434 //case CDATA_SECTION_NODE:
41435 //case COMMENT_NODE:
41438 //case DOCUMENT_NODE:
41439 //case DOCUMENT_TYPE_NODE:
41440 //cannot be imported.
41441 //case ENTITY_NODE:
41442 //case NOTATION_NODE:
41443 //can not hit in level3
41447 node2 = node.cloneNode(false);//false
41449 node2.ownerDocument = doc;
41450 node2.parentNode = null;
41452 var child = node.firstChild;
41454 node2.appendChild(importNode(doc,child,deep));
41455 child = child.nextSibling;
41461 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
41462 // attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
41463 function cloneNode(doc,node,deep){
41464 var node2 = new node.constructor();
41465 for(var n in node){
41467 if(typeof v != 'object' ){
41473 if(node.childNodes){
41474 node2.childNodes = new NodeList();
41476 node2.ownerDocument = doc;
41477 switch (node2.nodeType) {
41479 var attrs = node.attributes;
41480 var attrs2 = node2.attributes = new NamedNodeMap();
41481 var len = attrs.length;
41482 attrs2._ownerElement = node2;
41483 for(var i=0;i<len;i++){
41484 node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
41487 case ATTRIBUTE_NODE:
41491 var child = node.firstChild;
41493 node2.appendChild(cloneNode(doc,child,deep));
41494 child = child.nextSibling;
41500 function __set__(object,key,value){
41501 object[key] = value;
41505 if(Object.defineProperty){
41506 Object.defineProperty(LiveNodeList.prototype,'length',{
41508 _updateLiveList(this);
41509 return this.$$length;
41512 Object.defineProperty(Node.prototype,'textContent',{
41514 return getTextContent(this);
41516 set:function(data){
41517 switch(this.nodeType){
41520 while(this.firstChild){
41521 this.removeChild(this.firstChild);
41523 if(data || String(data)){
41524 this.appendChild(this.ownerDocument.createTextNode(data));
41530 this.value = value;
41531 this.nodeValue = data;
41536 function getTextContent(node){
41537 switch(node.nodeType){
41541 node = node.firstChild;
41543 if(node.nodeType!==7 && node.nodeType !==8){
41544 buf.push(getTextContent(node));
41546 node = node.nextSibling;
41548 return buf.join('');
41550 return node.nodeValue;
41553 __set__ = function(object,key,value){
41554 //console.log(value)
41555 object['$$'+key] = value;
41561 if(typeof commonjsRequire == 'function'){
41562 exports.DOMImplementation = DOMImplementation;
41563 exports.XMLSerializer = XMLSerializer;
41567 var domParser = createCommonjsModule(function (module, exports) {
41568 function DOMParser(options){
41569 this.options = options ||{locator:{}};
41572 DOMParser.prototype.parseFromString = function(source,mimeType){
41573 var options = this.options;
41574 var sax$$1 = new XMLReader();
41575 var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
41576 var errorHandler = options.errorHandler;
41577 var locator = options.locator;
41578 var defaultNSMap = options.xmlns||{};
41579 var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
41581 domBuilder.setDocumentLocator(locator);
41584 sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
41585 sax$$1.domBuilder = options.domBuilder || domBuilder;
41586 if(/\/x?html?$/.test(mimeType)){
41587 entityMap.nbsp = '\xa0';
41588 entityMap.copy = '\xa9';
41589 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
41591 defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
41593 sax$$1.parse(source,defaultNSMap,entityMap);
41595 sax$$1.errorHandler.error("invalid document source");
41597 return domBuilder.document;
41599 function buildErrorHandler(errorImpl,domBuilder,locator){
41601 if(domBuilder instanceof DOMHandler){
41604 errorImpl = domBuilder ;
41606 var errorHandler = {};
41607 var isCallback = errorImpl instanceof Function;
41608 locator = locator||{};
41609 function build(key){
41610 var fn = errorImpl[key];
41611 if(!fn && isCallback){
41612 fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
41614 errorHandler[key] = fn && function(msg){
41615 fn('[xmldom '+key+']\t'+msg+_locator(locator));
41620 build('fatalError');
41621 return errorHandler;
41624 //console.log('#\n\n\n\n\n\n\n####')
41626 * +ContentHandler+ErrorHandler
41627 * +LexicalHandler+EntityResolver2
41628 * -DeclHandler-DTDHandler
41630 * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
41631 * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
41632 * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
41634 function DOMHandler() {
41635 this.cdata = false;
41637 function position(locator,node){
41638 node.lineNumber = locator.lineNumber;
41639 node.columnNumber = locator.columnNumber;
41642 * @see org.xml.sax.ContentHandler#startDocument
41643 * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
41645 DOMHandler.prototype = {
41646 startDocument : function() {
41647 this.document = new DOMImplementation().createDocument(null, null, null);
41648 if (this.locator) {
41649 this.document.documentURI = this.locator.systemId;
41652 startElement:function(namespaceURI, localName, qName, attrs) {
41653 var doc = this.document;
41654 var el = doc.createElementNS(namespaceURI, qName||localName);
41655 var len = attrs.length;
41656 appendElement(this, el);
41657 this.currentElement = el;
41659 this.locator && position(this.locator,el);
41660 for (var i = 0 ; i < len; i++) {
41661 var namespaceURI = attrs.getURI(i);
41662 var value = attrs.getValue(i);
41663 var qName = attrs.getQName(i);
41664 var attr = doc.createAttributeNS(namespaceURI, qName);
41665 if( attr.getOffset){
41666 position(attr.getOffset(1),attr);
41668 attr.value = attr.nodeValue = value;
41669 el.setAttributeNode(attr);
41672 endElement:function(namespaceURI, localName, qName) {
41673 var current = this.currentElement;
41674 var tagName = current.tagName;
41675 this.currentElement = current.parentNode;
41677 startPrefixMapping:function(prefix, uri) {
41679 endPrefixMapping:function(prefix) {
41681 processingInstruction:function(target, data) {
41682 var ins = this.document.createProcessingInstruction(target, data);
41683 this.locator && position(this.locator,ins);
41684 appendElement(this, ins);
41686 ignorableWhitespace:function(ch, start, length) {
41688 characters:function(chars, start, length) {
41689 chars = _toString.apply(this,arguments);
41690 //console.log(chars)
41691 if(this.currentElement && chars){
41693 var charNode = this.document.createCDATASection(chars);
41694 this.currentElement.appendChild(charNode);
41696 var charNode = this.document.createTextNode(chars);
41697 this.currentElement.appendChild(charNode);
41699 this.locator && position(this.locator,charNode);
41702 skippedEntity:function(name) {
41704 endDocument:function() {
41705 this.document.normalize();
41707 setDocumentLocator:function (locator) {
41708 if(this.locator = locator){// && !('lineNumber' in locator)){
41709 locator.lineNumber = 0;
41713 comment:function(chars, start, length) {
41714 chars = _toString.apply(this,arguments);
41715 var comm = this.document.createComment(chars);
41716 this.locator && position(this.locator,comm);
41717 appendElement(this, comm);
41720 startCDATA:function() {
41721 //used in characters() methods
41724 endCDATA:function() {
41725 this.cdata = false;
41728 startDTD:function(name, publicId, systemId) {
41729 var impl = this.document.implementation;
41730 if (impl && impl.createDocumentType) {
41731 var dt = impl.createDocumentType(name, publicId, systemId);
41732 this.locator && position(this.locator,dt);
41733 appendElement(this, dt);
41737 * @see org.xml.sax.ErrorHandler
41738 * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
41740 warning:function(error) {
41741 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
41743 error:function(error) {
41744 console.error('[xmldom error]\t'+error,_locator(this.locator));
41746 fatalError:function(error) {
41747 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
41751 function _locator(l){
41753 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
41756 function _toString(chars,start,length){
41757 if(typeof chars == 'string'){
41758 return chars.substr(start,length)
41759 }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
41760 if(chars.length >= start+length || start){
41761 return new java.lang.String(chars,start,length)+'';
41768 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
41769 * used method of org.xml.sax.ext.LexicalHandler:
41770 * #comment(chars, start, length)
41773 * #startDTD(name, publicId, systemId)
41776 * IGNORED method of org.xml.sax.ext.LexicalHandler:
41778 * #startEntity(name)
41782 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
41783 * IGNORED method of org.xml.sax.ext.DeclHandler
41784 * #attributeDecl(eName, aName, type, mode, value)
41785 * #elementDecl(name, model)
41786 * #externalEntityDecl(name, publicId, systemId)
41787 * #internalEntityDecl(name, value)
41788 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
41789 * IGNORED method of org.xml.sax.EntityResolver2
41790 * #resolveEntity(String name,String publicId,String baseURI,String systemId)
41791 * #resolveEntity(publicId, systemId)
41792 * #getExternalSubset(name, baseURI)
41793 * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
41794 * IGNORED method of org.xml.sax.DTDHandler
41795 * #notationDecl(name, publicId, systemId) {};
41796 * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
41798 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
41799 DOMHandler.prototype[key] = function(){return null};
41802 /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
41803 function appendElement (hander,node) {
41804 if (!hander.currentElement) {
41805 hander.document.appendChild(node);
41807 hander.currentElement.appendChild(node);
41809 }//appendChild and setAttributeNS are preformance key
41811 if(typeof commonjsRequire == 'function'){
41812 var XMLReader = sax.XMLReader;
41813 var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
41814 exports.XMLSerializer = dom.XMLSerializer ;
41815 exports.DOMParser = DOMParser;
41819 var togeojson = createCommonjsModule(function (module, exports) {
41820 var toGeoJSON = (function() {
41823 var removeSpace = /\s*/g,
41824 trimSpace = /^\s*|\s*$/g,
41825 splitSpace = /\s+/;
41826 // generate a short, numeric hash of a string
41827 function okhash(x) {
41828 if (!x || !x.length) return 0;
41829 for (var i = 0, h = 0; i < x.length; i++) {
41830 h = ((h << 5) - h) + x.charCodeAt(i) | 0;
41833 // all Y children of X
41834 function get(x, y) { return x.getElementsByTagName(y); }
41835 function attr(x, y) { return x.getAttribute(y); }
41836 function attrf(x, y) { return parseFloat(attr(x, y)); }
41837 // one Y child of X, if any, otherwise null
41838 function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
41839 // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
41840 function norm(el) { if (el.normalize) { el.normalize(); } return el; }
41841 // cast array x into numbers
41842 function numarray(x) {
41843 for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
41846 // get the content of a text node, if any
41847 function nodeVal(x) {
41848 if (x) { norm(x); }
41849 return (x && x.textContent) || '';
41851 // get the contents of multiple text nodes, if present
41852 function getMulti(x, ys) {
41854 for (k = 0; k < ys.length; k++) {
41855 n = get1(x, ys[k]);
41856 if (n) o[ys[k]] = nodeVal(n);
41860 // add properties of Y to X, overwriting if present in both
41861 function extend(x, y) { for (var k in y) x[k] = y[k]; }
41862 // get one coordinate from a coordinate array, if any
41863 function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
41864 // get all coordinates from a coordinate array as [[],[]]
41865 function coord(v) {
41866 var coords = v.replace(trimSpace, '').split(splitSpace),
41868 for (var i = 0; i < coords.length; i++) {
41869 o.push(coord1(coords[i]));
41873 function coordPair(x) {
41874 var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
41875 ele = get1(x, 'ele'),
41876 // handle namespaced attribute in browser
41877 heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
41878 time = get1(x, 'time'),
41881 e = parseFloat(nodeVal(ele));
41888 time: time ? nodeVal(time) : null,
41889 heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
41893 // create a new feature collection parent object
41896 type: 'FeatureCollection',
41902 if (typeof XMLSerializer !== 'undefined') {
41903 /* istanbul ignore next */
41904 serializer = new XMLSerializer();
41905 // only require xmldom in a node environment
41906 } else if (typeof exports === 'object' && typeof process === 'object' && !process.browser) {
41907 serializer = new (domParser.XMLSerializer)();
41909 function xml2str(str) {
41910 // IE9 will create a new XMLSerializer but it'll crash immediately.
41911 // This line is ignored because we don't run coverage tests in IE9
41912 /* istanbul ignore next */
41913 if (str.xml !== undefined) return str.xml;
41914 return serializer.serializeToString(str);
41918 kml: function(doc) {
41921 // styleindex keeps track of hashed styles in order to match features
41922 styleIndex = {}, styleByHash = {},
41923 // stylemapindex keeps track of style maps to expose in properties
41924 styleMapIndex = {},
41925 // atomic geospatial types supported by KML - MultiGeometry is
41926 // handled separately
41927 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
41928 // all root placemarks in the file
41929 placemarks = get(doc, 'Placemark'),
41930 styles = get(doc, 'Style'),
41931 styleMaps = get(doc, 'StyleMap');
41933 for (var k = 0; k < styles.length; k++) {
41934 var hash = okhash(xml2str(styles[k])).toString(16);
41935 styleIndex['#' + attr(styles[k], 'id')] = hash;
41936 styleByHash[hash] = styles[k];
41938 for (var l = 0; l < styleMaps.length; l++) {
41939 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
41940 var pairs = get(styleMaps[l], 'Pair');
41942 for (var m = 0; m < pairs.length; m++) {
41943 pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
41945 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
41948 for (var j = 0; j < placemarks.length; j++) {
41949 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
41951 function kmlColor(v) {
41952 var color, opacity;
41954 if (v.substr(0, 1) === '#') { v = v.substr(1); }
41955 if (v.length === 6 || v.length === 3) { color = v; }
41956 if (v.length === 8) {
41957 opacity = parseInt(v.substr(0, 2), 16) / 255;
41958 color = '#' + v.substr(6, 2) +
41962 return [color, isNaN(opacity) ? undefined : opacity];
41964 function gxCoord(v) { return numarray(v.split(' ')); }
41965 function gxCoords(root) {
41966 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
41967 if (elems.length === 0) elems = get(root, 'gx:coord');
41968 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
41969 var timeElems = get(root, 'when');
41970 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
41976 function getGeometry(root) {
41977 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
41978 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
41979 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
41980 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
41981 for (i = 0; i < geotypes.length; i++) {
41982 geomNodes = get(root, geotypes[i]);
41984 for (j = 0; j < geomNodes.length; j++) {
41985 geomNode = geomNodes[j];
41986 if (geotypes[i] === 'Point') {
41989 coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
41991 } else if (geotypes[i] === 'LineString') {
41993 type: 'LineString',
41994 coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
41996 } else if (geotypes[i] === 'Polygon') {
41997 var rings = get(geomNode, 'LinearRing'),
41999 for (k = 0; k < rings.length; k++) {
42000 coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
42004 coordinates: coords
42006 } else if (geotypes[i] === 'Track' ||
42007 geotypes[i] === 'gx:Track') {
42008 var track = gxCoords(geomNode);
42010 type: 'LineString',
42011 coordinates: track.coords
42013 if (track.times.length) coordTimes.push(track.times);
42020 coordTimes: coordTimes
42023 function getPlacemark(root) {
42024 var geomsAndTimes = getGeometry(root), i, properties = {},
42025 name = nodeVal(get1(root, 'name')),
42026 styleUrl = nodeVal(get1(root, 'styleUrl')),
42027 description = nodeVal(get1(root, 'description')),
42028 timeSpan = get1(root, 'TimeSpan'),
42029 timeStamp = get1(root, 'TimeStamp'),
42030 extendedData = get1(root, 'ExtendedData'),
42031 lineStyle = get1(root, 'LineStyle'),
42032 polyStyle = get1(root, 'PolyStyle'),
42033 visibility = get1(root, 'visibility');
42035 if (!geomsAndTimes.geoms.length) return [];
42036 if (name) properties.name = name;
42038 if (styleUrl[0] !== '#') {
42039 styleUrl = '#' + styleUrl;
42042 properties.styleUrl = styleUrl;
42043 if (styleIndex[styleUrl]) {
42044 properties.styleHash = styleIndex[styleUrl];
42046 if (styleMapIndex[styleUrl]) {
42047 properties.styleMapHash = styleMapIndex[styleUrl];
42048 properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
42050 // Try to populate the lineStyle or polyStyle since we got the style hash
42051 var style = styleByHash[properties.styleHash];
42053 if (!lineStyle) lineStyle = get1(style, 'LineStyle');
42054 if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
42057 if (description) properties.description = description;
42059 var begin = nodeVal(get1(timeSpan, 'begin'));
42060 var end = nodeVal(get1(timeSpan, 'end'));
42061 properties.timespan = { begin: begin, end: end };
42064 properties.timestamp = nodeVal(get1(timeStamp, 'when'));
42067 var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
42068 color = linestyles[0],
42069 opacity = linestyles[1],
42070 width = parseFloat(nodeVal(get1(lineStyle, 'width')));
42071 if (color) properties.stroke = color;
42072 if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
42073 if (!isNaN(width)) properties['stroke-width'] = width;
42076 var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
42077 pcolor = polystyles[0],
42078 popacity = polystyles[1],
42079 fill = nodeVal(get1(polyStyle, 'fill')),
42080 outline = nodeVal(get1(polyStyle, 'outline'));
42081 if (pcolor) properties.fill = pcolor;
42082 if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
42083 if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
42084 if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
42086 if (extendedData) {
42087 var datas = get(extendedData, 'Data'),
42088 simpleDatas = get(extendedData, 'SimpleData');
42090 for (i = 0; i < datas.length; i++) {
42091 properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
42093 for (i = 0; i < simpleDatas.length; i++) {
42094 properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
42098 properties.visibility = nodeVal(visibility);
42100 if (geomsAndTimes.coordTimes.length) {
42101 properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
42102 geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
42106 geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
42107 type: 'GeometryCollection',
42108 geometries: geomsAndTimes.geoms
42110 properties: properties
42112 if (attr(root, 'id')) feature.id = attr(root, 'id');
42117 gpx: function(doc) {
42119 tracks = get(doc, 'trk'),
42120 routes = get(doc, 'rte'),
42121 waypoints = get(doc, 'wpt'),
42122 // a feature collection
42125 for (i = 0; i < tracks.length; i++) {
42126 feature = getTrack(tracks[i]);
42127 if (feature) gj.features.push(feature);
42129 for (i = 0; i < routes.length; i++) {
42130 feature = getRoute(routes[i]);
42131 if (feature) gj.features.push(feature);
42133 for (i = 0; i < waypoints.length; i++) {
42134 gj.features.push(getPoint(waypoints[i]));
42136 function getPoints(node, pointname) {
42137 var pts = get(node, pointname),
42142 if (l < 2) return {}; // Invalid line in GeoJSON
42143 for (var i = 0; i < l; i++) {
42144 var c = coordPair(pts[i]);
42145 line.push(c.coordinates);
42146 if (c.time) times.push(c.time);
42147 if (c.heartRate) heartRates.push(c.heartRate);
42152 heartRates: heartRates
42155 function getTrack(node) {
42156 var segments = get(node, 'trkseg'),
42161 for (var i = 0; i < segments.length; i++) {
42162 line = getPoints(segments[i], 'trkpt');
42164 if (line.line) track.push(line.line);
42165 if (line.times && line.times.length) times.push(line.times);
42166 if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
42169 if (track.length === 0) return;
42170 var properties = getProperties(node);
42171 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
42172 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
42175 properties: properties,
42177 type: track.length === 1 ? 'LineString' : 'MultiLineString',
42178 coordinates: track.length === 1 ? track[0] : track
42182 function getRoute(node) {
42183 var line = getPoints(node, 'rtept');
42184 if (!line.line) return;
42187 properties: getProperties(node),
42189 type: 'LineString',
42190 coordinates: line.line
42195 function getPoint(node) {
42196 var prop = getProperties(node);
42197 extend(prop, getMulti(node, ['sym', 'type']));
42203 coordinates: coordPair(node).coordinates
42207 function getProperties(node) {
42209 prop = getMulti(node, ['name', 'cmt', 'desc', 'time', 'keywords']);
42210 links = get(node, 'link');
42211 if (links.length) prop.links = [];
42212 for (var i = 0, link; i < links.length; i++) {
42213 link = { href: attr(links[i], 'href') };
42214 extend(link, getMulti(links[i], ['text', 'type']));
42215 prop.links.push(link);
42225 if (typeof module !== 'undefined') module.exports = toGeoJSON;
42228 function svgGpx(projection, context, dispatch$$1) {
42229 var showLabels = true,
42230 detected = utilDetect(),
42235 if (svgGpx.initialized) return; // run once
42237 svgGpx.geojson = {};
42238 svgGpx.enabled = true;
42241 event.stopPropagation();
42242 event.preventDefault();
42243 event.dataTransfer.dropEffect = 'copy';
42247 .attr('dropzone', 'copy')
42248 .on('drop.localgpx', function() {
42249 event.stopPropagation();
42250 event.preventDefault();
42251 if (!detected.filedrop) return;
42252 drawGpx.files(event.dataTransfer.files);
42254 .on('dragenter.localgpx', over)
42255 .on('dragexit.localgpx', over)
42256 .on('dragover.localgpx', over);
42258 svgGpx.initialized = true;
42262 function drawGpx(selection$$1) {
42263 var geojson = svgGpx.geojson,
42264 enabled = svgGpx.enabled;
42266 layer = selection$$1.selectAll('.layer-gpx')
42267 .data(enabled ? [0] : []);
42272 layer = layer.enter()
42274 .attr('class', 'layer-gpx')
42285 paths = paths.enter()
42287 .attr('class', 'gpx')
42291 var path$$1 = index$5(projection);
42294 .attr('d', path$$1);
42297 var labels = layer.selectAll('text')
42298 .data(showLabels && geojson.features ? geojson.features : []);
42303 labels = labels.enter()
42305 .attr('class', 'gpx')
42309 .text(function(d) {
42310 return d.properties.desc || d.properties.name;
42312 .attr('x', function(d) {
42313 var centroid = path$$1.centroid(d);
42314 return centroid[0] + 7;
42316 .attr('y', function(d) {
42317 var centroid = path$$1.centroid(d);
42318 return centroid[1];
42324 function toDom(x) {
42325 return (new DOMParser()).parseFromString(x, 'text/xml');
42329 drawGpx.showLabels = function(_) {
42330 if (!arguments.length) return showLabels;
42336 drawGpx.enabled = function(_) {
42337 if (!arguments.length) return svgGpx.enabled;
42338 svgGpx.enabled = _;
42339 dispatch$$1.call('change');
42344 drawGpx.hasGpx = function() {
42345 var geojson = svgGpx.geojson;
42346 return (!(lodash.isEmpty(geojson) || lodash.isEmpty(geojson.features)));
42350 drawGpx.geojson = function(gj) {
42351 if (!arguments.length) return svgGpx.geojson;
42352 if (lodash.isEmpty(gj) || lodash.isEmpty(gj.features)) return this;
42353 svgGpx.geojson = gj;
42354 dispatch$$1.call('change');
42359 drawGpx.url = function(url) {
42360 text(url, function(err, data) {
42362 drawGpx.geojson(togeojson.gpx(toDom(data)));
42369 drawGpx.files = function(fileList) {
42370 if (!fileList.length) return this;
42371 var f = fileList[0],
42372 reader = new FileReader();
42374 reader.onload = function(e) {
42375 drawGpx.geojson(togeojson.gpx(toDom(e.target.result))).fitZoom();
42378 reader.readAsText(f);
42383 drawGpx.fitZoom = function() {
42384 if (!this.hasGpx()) return this;
42385 var geojson = svgGpx.geojson;
42387 var map$$1 = context.map(),
42388 viewport = map$$1.trimmedExtent().polygon(),
42389 coords = lodash.reduce(geojson.features, function(coords, feature) {
42390 var c = feature.geometry.coordinates;
42391 return lodash.union(coords, feature.geometry.type === 'Point' ? [c] : c);
42394 if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
42395 var extent$$1 = geoExtent$$1(bounds(geojson));
42396 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
42407 function svgIcon(name, svgklass, useklass) {
42408 return function drawIcon(selection) {
42409 selection.selectAll('svg')
42413 .attr('class', 'icon ' + (svgklass || ''))
42415 .attr('xlink:href', name)
42416 .attr('class', useklass);
42420 function svgLabels(projection, context) {
42421 var path$$1 = index$5(projection),
42422 detected = utilDetect(),
42423 baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge'),
42424 rdrawn = index$8(),
42425 rskipped = index$8(),
42426 textWidthCache = {},
42429 // Listed from highest to lowest priority
42431 ['line', 'aeroway', '*', 12],
42432 ['line', 'highway', 'motorway', 12],
42433 ['line', 'highway', 'trunk', 12],
42434 ['line', 'highway', 'primary', 12],
42435 ['line', 'highway', 'secondary', 12],
42436 ['line', 'highway', 'tertiary', 12],
42437 ['line', 'highway', '*', 12],
42438 ['line', 'railway', '*', 12],
42439 ['line', 'waterway', '*', 12],
42440 ['area', 'aeroway', '*', 12],
42441 ['area', 'amenity', '*', 12],
42442 ['area', 'building', '*', 12],
42443 ['area', 'historic', '*', 12],
42444 ['area', 'leisure', '*', 12],
42445 ['area', 'man_made', '*', 12],
42446 ['area', 'natural', '*', 12],
42447 ['area', 'shop', '*', 12],
42448 ['area', 'tourism', '*', 12],
42449 ['area', 'camp_site', '*', 12],
42450 ['point', 'aeroway', '*', 10],
42451 ['point', 'amenity', '*', 10],
42452 ['point', 'building', '*', 10],
42453 ['point', 'historic', '*', 10],
42454 ['point', 'leisure', '*', 10],
42455 ['point', 'man_made', '*', 10],
42456 ['point', 'natural', '*', 10],
42457 ['point', 'shop', '*', 10],
42458 ['point', 'tourism', '*', 10],
42459 ['point', 'camp_site', '*', 10],
42460 ['line', 'name', '*', 12],
42461 ['area', 'name', '*', 12],
42462 ['point', 'name', '*', 10]
42466 function blacklisted(preset) {
42467 var noIcons = ['building', 'landuse', 'natural'];
42468 return lodash.some(noIcons, function(s) {
42469 return preset.id.indexOf(s) >= 0;
42474 function get(array, prop) {
42475 return function(d, i) { return array[i][prop]; };
42479 function textWidth(text$$1, size, elem) {
42480 var c = textWidthCache[size];
42481 if (!c) c = textWidthCache[size] = {};
42487 c[text$$1] = elem.getComputedTextLength();
42491 var str = encodeURIComponent(text$$1).match(/%[CDEFcdef]/g);
42492 if (str === null) {
42493 return size / 3 * 2 * text$$1.length;
42495 return size / 3 * (2 * text$$1.length + str.length);
42501 function drawLinePaths(selection$$1, entities, filter, classes, labels) {
42502 var paths = selection$$1.selectAll('path')
42504 .data(entities, osmEntity$$1.key);
42511 .style('stroke-width', get(labels, 'font-size'))
42512 .attr('id', function(d) { return 'labelpath-' + d.id; })
42513 .attr('class', classes)
42515 .attr('d', get(labels, 'lineString'));
42519 function drawLineLabels(selection$$1, entities, filter, classes, labels) {
42520 var texts = selection$$1.selectAll('text.' + classes)
42522 .data(entities, osmEntity$$1.key);
42529 .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
42530 .attr('dy', baselineHack ? '0.35em' : null)
42531 .append('textPath')
42532 .attr('class', 'textpath');
42534 texts = selection$$1.selectAll('text.' + classes);
42536 texts.selectAll('.textpath')
42538 .data(entities, osmEntity$$1.key)
42539 .attr('startOffset', '50%')
42540 .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
42541 .text(utilDisplayName);
42545 function drawPointLabels(selection$$1, entities, filter, classes, labels) {
42546 var texts = selection$$1.selectAll('text.' + classes)
42548 .data(entities, osmEntity$$1.key);
42553 texts = texts.enter()
42555 .attr('class', function(d, i) {
42556 return classes + ' ' + labels[i].classes + ' ' + d.id;
42561 .attr('x', get(labels, 'x'))
42562 .attr('y', get(labels, 'y'))
42563 .style('text-anchor', get(labels, 'textAnchor'))
42564 .text(utilDisplayName)
42565 .each(function(d, i) {
42566 textWidth(utilDisplayName(d), labels[i].height, this);
42571 function drawAreaLabels(selection$$1, entities, filter, classes, labels) {
42572 entities = entities.filter(hasText);
42573 labels = labels.filter(hasText);
42574 drawPointLabels(selection$$1, entities, filter, classes, labels);
42576 function hasText(d, i) {
42577 return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
42582 function drawAreaIcons(selection$$1, entities, filter, classes, labels) {
42583 var icons = selection$$1.selectAll('use')
42585 .data(entities, osmEntity$$1.key);
42590 icons = icons.enter()
42592 .attr('class', 'icon areaicon')
42593 .attr('width', '18px')
42594 .attr('height', '18px')
42598 .attr('transform', get(labels, 'transform'))
42599 .attr('xlink:href', function(d) {
42600 var icon = context.presets().match(d, context.graph()).icon;
42601 return '#' + icon + (icon === 'hairdresser' ? '-24': '-18'); // workaround: maki hairdresser-18 broken?
42606 function drawCollisionBoxes(selection$$1, rtree, which) {
42607 var showDebug = context.getDebug('collision'),
42608 classes = 'debug ' + which + ' ' +
42609 (which === 'debug-skipped' ? 'orange' : 'yellow');
42611 var debug = selection$$1.selectAll('.layer-label-debug')
42612 .data(showDebug ? [true] : []);
42617 debug = debug.enter()
42619 .attr('class', 'layer-label-debug')
42623 var gj = rtree.all().map(function(d) {
42624 return { type: 'Polygon', coordinates: [[
42633 var debugboxes = debug.selectAll('.' + which)
42639 debugboxes = debugboxes.enter()
42641 .attr('class', classes)
42642 .merge(debugboxes);
42645 .attr('d', index$5());
42650 function drawLabels(selection$$1, graph, entities, filter, dimensions, fullRedraw) {
42651 var lowZoom = context.surface().classed('low-zoom');
42653 var labelable = [], i, j, k, entity, geometry;
42654 for (i = 0; i < labelStack.length; i++) {
42655 labelable.push([]);
42663 for (i = 0; i < entities.length; i++) {
42664 entity = entities[i];
42666 .concat(entitybboxes[entity.id] || [])
42667 .concat(entitybboxes[entity.id + 'I'] || []);
42669 for (j = 0; j < toRemove.length; j++) {
42670 rdrawn.remove(toRemove[j]);
42671 rskipped.remove(toRemove[j]);
42676 // Split entities into groups specified by labelStack
42677 for (i = 0; i < entities.length; i++) {
42678 entity = entities[i];
42679 geometry = entity.geometry(graph);
42680 if (geometry === 'vertex') { geometry = 'point'; } // treat vertex like point
42682 var preset = geometry === 'area' && context.presets().match(entity, graph),
42683 icon = preset && !blacklisted(preset) && preset.icon;
42685 if (!icon && !utilDisplayName(entity))
42688 for (k = 0; k < labelStack.length; k++) {
42689 var matchGeom = labelStack[k][0],
42690 matchKey = labelStack[k][1],
42691 matchVal = labelStack[k][2],
42692 hasVal = entity.tags[matchKey];
42694 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
42695 labelable[k].push(entity);
42713 // Try and find a valid label for labellable entities
42714 for (k = 0; k < labelable.length; k++) {
42715 var fontSize = labelStack[k][3];
42716 for (i = 0; i < labelable[k].length; i++) {
42717 entity = labelable[k][i];
42718 geometry = entity.geometry(graph);
42720 var name = utilDisplayName(entity),
42721 width = name && textWidth(name, fontSize),
42723 if (geometry === 'point') {
42724 p = getPointLabel(entity, width, fontSize, geometry);
42725 } else if (geometry === 'vertex' && !lowZoom) {
42726 // don't label vertices at low zoom because they don't have icons
42727 p = getPointLabel(entity, width, fontSize, geometry);
42728 } else if (geometry === 'line') {
42729 p = getLineLabel(entity, width, fontSize);
42730 } else if (geometry === 'area') {
42731 p = getAreaLabel(entity, width, fontSize);
42735 if (geometry === 'vertex') { geometry = 'point'; } // treat vertex like point
42736 p.classes = geometry + ' tag-' + labelStack[k][1];
42737 positions[geometry].push(p);
42738 labelled[geometry].push(entity);
42744 function getPointLabel(entity, width, height, geometry) {
42745 var y = (geometry === 'point' ? -12 : 0),
42747 ltr: [15, y, 'start'],
42748 rtl: [-15, y, 'end']
42751 var coord = projection(entity.loc),
42753 textDirection = detected.textDirection,
42754 offset = pointOffsets[textDirection],
42758 x: coord[0] + offset[0],
42759 y: coord[1] + offset[1],
42760 textAnchor: offset[2]
42764 if (textDirection === 'rtl') {
42766 minX: p.x - width - margin,
42767 minY: p.y - (height / 2) - margin,
42768 maxX: p.x + margin,
42769 maxY: p.y + (height / 2) + margin
42773 minX: p.x - margin,
42774 minY: p.y - (height / 2) - margin,
42775 maxX: p.x + width + margin,
42776 maxY: p.y + (height / 2) + margin
42780 if (tryInsert([bbox], entity.id, true)) {
42786 function getLineLabel(entity, width, height) {
42787 var viewport = geoExtent$$1(context.projection.clipExtent()).polygon(),
42788 nodes = lodash.map(graph.childNodes(entity), 'loc').map(projection),
42789 length = geoPathLength(nodes);
42791 if (length < width + 20) return;
42793 // % along the line to attempt to place the label
42794 var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
42795 25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
42798 for (var i = 0; i < lineOffsets.length; i++) {
42799 var offset = lineOffsets[i],
42800 middle = offset / 100 * length,
42801 start = middle - width / 2;
42803 if (start < 0 || start + width > length) continue;
42805 // generate subpath and ignore paths that are invalid or don't cross viewport.
42806 var sub = subpath(nodes, start, start + width);
42807 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
42811 var isReverse = reverse(sub);
42813 sub = sub.reverse();
42817 boxsize = (height + 2) / 2;
42819 for (var j = 0; j < sub.length - 1; j++) {
42821 var b = sub[j + 1];
42822 var num = Math.max(1, Math.floor(geoEuclideanDistance(a, b) / boxsize / 2));
42824 for (var box = 0; box < num; box++) {
42825 var p = geoInterp(a, b, box / num);
42826 var x0 = p[0] - boxsize - margin;
42827 var y0 = p[1] - boxsize - margin;
42828 var x1 = p[0] + boxsize + margin;
42829 var y1 = p[1] + boxsize + margin;
42832 minX: Math.min(x0, x1),
42833 minY: Math.min(y0, y1),
42834 maxX: Math.max(x0, x1),
42835 maxY: Math.max(y0, y1)
42840 if (tryInsert(bboxes, entity.id, false)) {
42842 'font-size': height + 2,
42843 lineString: lineString(sub),
42844 startOffset: offset + '%'
42849 function reverse(p) {
42850 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
42851 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
42854 function lineString(nodes) {
42855 return 'M' + nodes.join('L');
42858 function subpath(nodes, from, to) {
42860 start, end, i0, i1;
42862 for (var i = 0; i < nodes.length - 1; i++) {
42865 var current = geoEuclideanDistance(a, b);
42867 if (!start && sofar + current >= from) {
42868 portion = (from - sofar) / current;
42870 a[0] + portion * (b[0] - a[0]),
42871 a[1] + portion * (b[1] - a[1])
42875 if (!end && sofar + current >= to) {
42876 portion = (to - sofar) / current;
42878 a[0] + portion * (b[0] - a[0]),
42879 a[1] + portion * (b[1] - a[1])
42886 var ret = nodes.slice(i0, i1);
42887 ret.unshift(start);
42894 function getAreaLabel(entity, width, height) {
42895 var centroid = path$$1.centroid(entity.asGeoJSON(graph, true)),
42896 extent$$1 = entity.extent(graph),
42897 entitywidth = projection(extent$$1[1])[0] - projection(extent$$1[0])[0];
42899 if (isNaN(centroid[0]) || entitywidth < 20) return;
42902 iconX = centroid[0] - (iconSize / 2),
42903 iconY = centroid[1] - (iconSize / 2),
42905 textOffset = iconSize + margin,
42906 p = { transform: 'translate(' + iconX + ',' + iconY + ')' };
42911 maxX: iconX + iconSize,
42912 maxY: iconY + iconSize
42916 if (tryInsert([bbox], entity.id + 'I', true)) {
42917 if (width && entitywidth >= width + 20) {
42918 var labelX = centroid[0],
42919 labelY = centroid[1] + textOffset;
42922 minX: labelX - (width / 2) - margin,
42923 minY: labelY - (height / 2) - margin,
42924 maxX: labelX + (width / 2) + margin,
42925 maxY: labelY + (height / 2) + margin
42928 // try to add label
42929 if (tryInsert([bbox], entity.id, true)) {
42932 p.textAnchor = 'middle';
42942 function tryInsert(bboxes, id, saveSkipped) {
42943 var skipped = false,
42946 for (var i = 0; i < bboxes.length; i++) {
42950 // Check that label is visible
42951 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
42955 if (rdrawn.collides(bbox)) {
42961 entitybboxes[id] = bboxes;
42965 rskipped.load(bboxes);
42968 rdrawn.load(bboxes);
42975 var label = selection$$1.selectAll('.layer-label'),
42976 halo = selection$$1.selectAll('.layer-halo');
42979 drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
42980 drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
42983 drawLinePaths(halo, labelled.line, filter, '', positions.line);
42984 drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
42985 drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
42988 drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
42989 drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
42990 drawAreaIcons(label, labelled.area, filter, 'arealabel-icon', positions.area);
42993 drawCollisionBoxes(label, rskipped, 'debug-skipped');
42994 drawCollisionBoxes(label, rdrawn, 'debug-drawn');
42996 selection$$1.call(filterLabels);
43000 function filterLabels(selection$$1) {
43001 var layers = selection$$1
43002 .selectAll('.layer-label, .layer-halo');
43004 layers.selectAll('.proximate')
43005 .classed('proximate', false);
43007 var mouse$$1 = context.mouse(),
43008 graph = context.graph(),
43009 selectedIDs = context.selectedIDs(),
43013 // hide labels near the mouse
43016 bbox = { minX: mouse$$1[0] - pad, minY: mouse$$1[1] - pad, maxX: mouse$$1[0] + pad, maxY: mouse$$1[1] + pad };
43017 ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
43020 // hide labels along selected ways, or near selected vertices
43021 for (var i = 0; i < selectedIDs.length; i++) {
43022 var entity = graph.hasEntity(selectedIDs[i]);
43023 if (!entity) continue;
43024 var geometry = entity.geometry(graph);
43026 if (geometry === 'line') {
43027 ids.push(selectedIDs[i]);
43028 } else if (geometry === 'vertex') {
43029 var point = context.projection(entity.loc);
43031 bbox = { minX: point[0] - pad, minY: point[1] - pad, maxX: point[0] + pad, maxY: point[1] + pad };
43032 ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
43036 layers.selectAll(utilEntitySelector(ids))
43037 .classed('proximate', true);
43041 var throttleFilterLabels = lodash.throttle(filterLabels, 100);
43044 drawLabels.observe = function(selection$$1) {
43045 var listener = function() { throttleFilterLabels(selection$$1); };
43046 selection$$1.on('mousemove.hidelabels', listener);
43047 context.on('enter.hidelabels', listener);
43051 drawLabels.off = function(selection$$1) {
43052 throttleFilterLabels.cancel();
43053 selection$$1.on('mousemove.hidelabels', null);
43054 context.on('enter.hidelabels', null);
43061 // Copies a variable number of methods from source to target.
43062 function utilRebind(target, source) {
43063 var i = 1, n = arguments.length, method;
43065 target[method = arguments[i]] = d3_rebind(target, source, source[method]);
43070 // Method is assumed to be a standard D3 getter-setter:
43071 // If passed with no arguments, gets the value.
43072 // If passed with arguments, sets the value and returns the target.
43073 function d3_rebind(target, source, method) {
43074 return function() {
43075 var value = method.apply(source, arguments);
43076 return value === source ? target : value;
43080 function refresh(selection, node) {
43081 var cr = node.getBoundingClientRect();
43082 var prop = [cr.width, cr.height];
43083 selection.property('__dimensions__', prop);
43087 function utilGetDimensions(selection, force) {
43088 if (!selection || selection.empty()) {
43091 var node = selection.node(),
43092 cached = selection.property('__dimensions__');
43093 return (!cached || force) ? refresh(selection, node) : cached;
43097 function utilSetDimensions(selection, dimensions) {
43098 if (!selection || selection.empty()) {
43101 var node = selection.node();
43102 if (dimensions === null) {
43103 refresh(selection, node);
43107 .property('__dimensions__', [dimensions[0], dimensions[1]])
43108 .attr('width', dimensions[0])
43109 .attr('height', dimensions[1]);
43112 function svgPointTransform(projection) {
43113 return function(entity) {
43114 // http://jsperf.com/short-array-join
43115 var pt = projection(entity.loc);
43116 return 'translate(' + pt[0] + ',' + pt[1] + ')';
43120 function d3geoTile() {
43121 var size = [960, 500],
43123 scaleExtent = [0, 20],
43124 translate = [size[0] / 2, size[1] / 2],
43127 function bound(_) {
43128 return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
43132 var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
43133 z0 = bound(Math.round(z + zoomDelta)),
43134 k = Math.pow(2, z - z0 + 8),
43135 origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
43137 cols = range(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
43138 rows = range(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
43140 rows.forEach(function(y) {
43141 cols.forEach(function(x) {
43142 tiles.push([x, y, z0]);
43146 tiles.translate = origin;
43152 tile.scaleExtent = function(_) {
43153 if (!arguments.length) return scaleExtent;
43158 tile.size = function(_) {
43159 if (!arguments.length) return size;
43164 tile.scale = function(_) {
43165 if (!arguments.length) return scale;
43170 tile.translate = function(_) {
43171 if (!arguments.length) return translate;
43176 tile.zoomDelta = function(_) {
43177 if (!arguments.length) return zoomDelta;
43185 /* global Mapillary:false */
43186 var apibase = 'https://a.mapillary.com/v2/';
43187 var viewercss = 'mapillary-js/mapillary.min.css';
43188 var viewerjs = 'mapillary-js/mapillary.min.js';
43189 var trafficocss = 'traffico/stylesheets/traffico.css';
43190 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
43191 var maxResults = 1000;
43193 var dispatch$2 = dispatch('loadedImages', 'loadedSigns');
43194 var mapillaryCache;
43195 var mapillaryClicks;
43196 var mapillaryImage;
43197 var mapillarySignDefs;
43198 var mapillaryViewer;
43201 function abortRequest(i) {
43206 function nearNullIsland(x, y, z) {
43208 var center = Math.pow(2, z - 1),
43209 width = Math.pow(2, z - 6),
43210 min$$1 = center - (width / 2),
43211 max$$1 = center + (width / 2) - 1;
43212 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
43218 function maxPageAtZoom(z) {
43219 if (z < 15) return 2;
43220 if (z === 15) return 5;
43221 if (z === 16) return 10;
43222 if (z === 17) return 20;
43223 if (z === 18) return 40;
43224 if (z > 18) return 80;
43228 function getTiles(projection) {
43229 var s = projection.scale() * 2 * Math.PI,
43230 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
43231 ts = 256 * Math.pow(2, z - tileZoom),
43233 s / 2 - projection.translate()[0],
43234 s / 2 - projection.translate()[1]];
43237 .scaleExtent([tileZoom, tileZoom])
43239 .size(projection.clipExtent()[1])
43240 .translate(projection.translate())()
43241 .map(function(tile) {
43242 var x = tile[0] * ts - origin[0],
43243 y = tile[1] * ts - origin[1];
43246 id: tile.toString(),
43248 extent: geoExtent$$1(
43249 projection.invert([x, y + ts]),
43250 projection.invert([x + ts, y])
43257 function loadTiles(which, url, projection) {
43258 var s = projection.scale() * 2 * Math.PI,
43259 currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
43261 var tiles = getTiles(projection).filter(function(t) {
43262 return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
43265 lodash.filter(which.inflight, function(v, k) {
43266 var wanted = lodash.find(tiles, function(tile) { return k === (tile.id + ',0'); });
43267 if (!wanted) delete which.inflight[k];
43269 }).map(abortRequest);
43271 tiles.forEach(function(tile) {
43272 loadNextTilePage(which, currZoom, url, tile);
43277 function loadNextTilePage(which, currZoom, url, tile) {
43278 var cache = mapillaryCache[which],
43279 rect = tile.extent.rectangle(),
43280 maxPages = maxPageAtZoom(currZoom),
43281 nextPage = cache.nextPage[tile.id] || 0;
43283 if (nextPage > maxPages) return;
43285 var id = tile.id + ',' + String(nextPage);
43286 if (cache.loaded[id] || cache.inflight[id]) return;
43288 cache.inflight[id] = json(url +
43293 client_id: clientId,
43298 }), function(err, data) {
43299 cache.loaded[id] = true;
43300 delete cache.inflight[id];
43301 if (err || !data.features || !data.features.length) return;
43306 for (var i = 0; i < data.features.length; i++) {
43307 feature = data.features[i];
43308 loc = feature.geometry.coordinates;
43309 d = { key: feature.properties.key, loc: loc };
43310 if (which === 'images') d.ca = feature.properties.ca;
43311 if (which === 'signs') d.signs = feature.properties.rects;
43313 features.push({minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d});
43316 cache.rtree.load(features);
43318 if (which === 'images') dispatch$2.call('loadedImages');
43319 if (which === 'signs') dispatch$2.call('loadedSigns');
43321 if (data.features.length === maxResults) { // more pages to load
43322 cache.nextPage[tile.id] = nextPage + 1;
43323 loadNextTilePage(which, currZoom, url, tile);
43325 cache.nextPage[tile.id] = Infinity; // no more pages to load
43332 // partition viewport into `psize` x `psize` regions
43333 function partitionViewport(psize, projection) {
43334 var dimensions = projection.clipExtent()[1];
43335 psize = psize || 16;
43336 var cols = range(0, dimensions[0], psize),
43337 rows = range(0, dimensions[1], psize),
43340 rows.forEach(function(y) {
43341 cols.forEach(function(x) {
43342 var min$$1 = [x, y + psize],
43343 max$$1 = [x + psize, y];
43345 geoExtent$$1(projection.invert(min$$1), projection.invert(max$$1)));
43353 // no more than `limit` results per partition.
43354 function searchLimited(psize, limit, projection, rtree) {
43355 limit = limit || 3;
43357 var partitions = partitionViewport(psize, projection);
43358 return lodash.flatten(lodash.compact(lodash.map(partitions, function(extent$$1) {
43359 return rtree.search(extent$$1.bbox())
43361 .map(function(d) { return d.data; });
43367 var serviceMapillary = {
43370 if (!mapillaryCache) {
43374 this.event = utilRebind(this, dispatch$2, 'on');
43377 reset: function() {
43378 var cache = mapillaryCache;
43381 if (cache.images && cache.images.inflight) {
43382 lodash.forEach(cache.images.inflight, abortRequest);
43384 if (cache.signs && cache.signs.inflight) {
43385 lodash.forEach(cache.signs.inflight, abortRequest);
43390 images: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$8() },
43391 signs: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$8() }
43394 mapillaryImage = null;
43395 mapillaryClicks = [];
43399 images: function(projection) {
43400 var psize = 16, limit = 3;
43401 return searchLimited(psize, limit, projection, mapillaryCache.images.rtree);
43405 signs: function(projection) {
43406 var psize = 32, limit = 3;
43407 return searchLimited(psize, limit, projection, mapillaryCache.signs.rtree);
43411 signsSupported: function() {
43412 var detected = utilDetect();
43413 if (detected.ie) return false;
43414 if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
43419 signHTML: function(d) {
43420 if (!mapillarySignDefs) return;
43422 var detectionPackage = d.signs[0].package,
43423 type = d.signs[0].type,
43424 country = detectionPackage.split('_')[1];
43426 return mapillarySignDefs[country][type];
43430 loadImages: function(projection) {
43431 var url = apibase + 'search/im/geojson?';
43432 loadTiles('images', url, projection);
43436 loadSigns: function(context, projection) {
43437 var url = apibase + 'search/im/geojson/or?';
43438 loadTiles('signs', url, projection);
43440 // load traffico css
43441 select('head').selectAll('#traffico')
43445 .attr('id', 'traffico')
43446 .attr('rel', 'stylesheet')
43447 .attr('href', context.asset(trafficocss));
43449 // load traffico sign defs
43450 if (!mapillarySignDefs) {
43451 mapillarySignDefs = {};
43452 lodash.each(['au', 'br', 'ca', 'de', 'us'], function(region) {
43453 json(context.asset('traffico/string-maps/' + region + '-map.json'), function(err, data) {
43455 if (region === 'de') region = 'eu';
43456 mapillarySignDefs[region] = data;
43463 loadViewer: function(context) {
43465 var wrap = select('#content').selectAll('.mapillary-wrap')
43468 var enter = wrap.enter()
43470 .attr('class', 'mapillary-wrap')
43471 .classed('al', true) // 'al'=left, 'ar'=right
43472 .classed('hidden', true);
43476 .attr('class', 'thumb-hide')
43477 .on('click', function () { that.hideViewer(); })
43479 .call(svgIcon('#icon-close'));
43484 .attr('class', 'mly-wrapper')
43485 .classed('active', false);
43487 // load mapillary-viewercss
43488 select('head').selectAll('#mapillary-viewercss')
43492 .attr('id', 'mapillary-viewercss')
43493 .attr('rel', 'stylesheet')
43494 .attr('href', context.asset(viewercss));
43496 // load mapillary-viewerjs
43497 select('head').selectAll('#mapillary-viewerjs')
43501 .attr('id', 'mapillary-viewerjs')
43502 .attr('src', context.asset(viewerjs));
43506 showViewer: function() {
43508 .selectAll('.mapillary-wrap')
43509 .classed('hidden', false)
43510 .selectAll('.mly-wrapper')
43511 .classed('active', true);
43517 hideViewer: function() {
43519 .selectAll('.mapillary-wrap')
43520 .classed('hidden', true)
43521 .selectAll('.mly-wrapper')
43522 .classed('active', false);
43524 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
43525 .classed('selected', false);
43527 mapillaryImage = null;
43532 updateViewer: function(imageKey, context) {
43533 if (!imageKey) return;
43535 if (!mapillaryViewer) {
43536 this.initViewer(imageKey, context);
43538 mapillaryViewer.moveToKey(imageKey);
43545 initViewer: function(imageKey, context) {
43547 if (Mapillary && imageKey) {
43549 baseImageSize: 320,
43556 mapillaryViewer = new Mapillary.Viewer('mly', clientId, imageKey, opts);
43557 mapillaryViewer.on('nodechanged', nodeChanged);
43560 function nodeChanged(node) {
43561 var clicks = mapillaryClicks;
43562 var index = clicks.indexOf(node.key);
43563 if (index > -1) { // nodechange initiated from clicking on a marker..
43564 clicks.splice(index, 1);
43565 } else { // nodechange initiated from the Mapillary viewer controls..
43566 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
43567 context.map().centerEase(loc);
43568 that.selectedImage(node.key, false);
43574 selectedImage: function(imageKey, fromClick) {
43575 if (!arguments.length) return mapillaryImage;
43577 mapillaryImage = imageKey;
43579 mapillaryClicks.push(imageKey);
43582 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
43583 .classed('selected', function(d) { return d.key === imageKey; });
43589 cache: function(_) {
43590 if (!arguments.length) return mapillaryCache;
43591 mapillaryCache = _;
43596 signDefs: function(_) {
43597 if (!arguments.length) return mapillarySignDefs;
43598 mapillarySignDefs = _;
43604 var endpoint = 'https://nominatim.openstreetmap.org/reverse?';
43605 var nominatimCache;
43608 var serviceNominatim = {
43610 init: function() { nominatimCache = index$8(); },
43611 reset: function() { nominatimCache = index$8(); },
43614 countryCode: function (location, callback) {
43615 var countryCodes = nominatimCache.search(
43616 { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
43619 if (countryCodes.length > 0) {
43620 return callback(null, countryCodes[0].data);
43629 }), function(err, result) {
43631 return callback(err);
43632 else if (result && result.error)
43633 return callback(result.error);
43635 var extent$$1 = geoExtent$$1(location).padByMeters(1000);
43636 nominatimCache.insert(Object.assign(extent$$1.bbox(),
43637 { data: result.address.country_code }
43640 callback(null, result.address.country_code);
43647 var hashes$1 = createCommonjsModule(function (module, exports) {
43649 * jshashes - https://github.com/h2non/jshashes
43650 * Released under the "New BSD" license
43652 * Algorithms specification:
43654 * MD5 - http://www.ietf.org/rfc/rfc1321.txt
43655 * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
43656 * SHA1 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
43657 * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
43658 * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
43659 * HMAC - http://www.ietf.org/rfc/rfc2104.txt
43664 function utf8Encode(str) {
43665 var x, y, output = '',
43669 if (str && str.length) {
43671 while ((i += 1) < l) {
43672 /* Decode utf-16 surrogate pairs */
43673 x = str.charCodeAt(i);
43674 y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
43675 if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
43676 x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
43679 /* Encode output as utf-8 */
43681 output += String.fromCharCode(x);
43682 } else if (x <= 0x7FF) {
43683 output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
43684 0x80 | (x & 0x3F));
43685 } else if (x <= 0xFFFF) {
43686 output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
43687 0x80 | ((x >>> 6) & 0x3F),
43688 0x80 | (x & 0x3F));
43689 } else if (x <= 0x1FFFFF) {
43690 output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
43691 0x80 | ((x >>> 12) & 0x3F),
43692 0x80 | ((x >>> 6) & 0x3F),
43693 0x80 | (x & 0x3F));
43700 function utf8Decode(str) {
43701 var i, ac, c1, c2, c3, arr = [],
43703 i = ac = c1 = c2 = c3 = 0;
43705 if (str && str.length) {
43710 c1 = str.charCodeAt(i);
43713 arr[ac] = String.fromCharCode(c1);
43715 } else if (c1 > 191 && c1 < 224) {
43716 c2 = str.charCodeAt(i + 1);
43717 arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
43720 c2 = str.charCodeAt(i + 1);
43721 c3 = str.charCodeAt(i + 2);
43722 arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
43727 return arr.join('');
43731 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
43732 * to work around bugs in some JS interpreters.
43735 function safe_add(x, y) {
43736 var lsw = (x & 0xFFFF) + (y & 0xFFFF),
43737 msw = (x >> 16) + (y >> 16) + (lsw >> 16);
43738 return (msw << 16) | (lsw & 0xFFFF);
43742 * Bitwise rotate a 32-bit number to the left.
43745 function bit_rol(num, cnt) {
43746 return (num << cnt) | (num >>> (32 - cnt));
43750 * Convert a raw string to a hex string
43753 function rstr2hex(input, hexcase) {
43754 var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
43758 for (; i < l; i += 1) {
43759 x = input.charCodeAt(i);
43760 output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
43766 * Encode a string as utf-16
43769 function str2rstr_utf16le(input) {
43770 var i, l = input.length,
43772 for (i = 0; i < l; i += 1) {
43773 output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF);
43778 function str2rstr_utf16be(input) {
43779 var i, l = input.length,
43781 for (i = 0; i < l; i += 1) {
43782 output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF);
43788 * Convert an array of big-endian words to a string
43791 function binb2rstr(input) {
43792 var i, l = input.length * 32,
43794 for (i = 0; i < l; i += 8) {
43795 output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
43801 * Convert an array of little-endian words to a string
43804 function binl2rstr(input) {
43805 var i, l = input.length * 32,
43807 for (i = 0; i < l; i += 8) {
43808 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
43814 * Convert a raw string to an array of little-endian words
43815 * Characters >255 have their high-byte silently ignored.
43818 function rstr2binl(input) {
43819 var i, l = input.length * 8,
43820 output = Array(input.length >> 2),
43821 lo = output.length;
43822 for (i = 0; i < lo; i += 1) {
43825 for (i = 0; i < l; i += 8) {
43826 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
43832 * Convert a raw string to an array of big-endian words
43833 * Characters >255 have their high-byte silently ignored.
43836 function rstr2binb(input) {
43837 var i, l = input.length * 8,
43838 output = Array(input.length >> 2),
43839 lo = output.length;
43840 for (i = 0; i < lo; i += 1) {
43843 for (i = 0; i < l; i += 8) {
43844 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
43850 * Convert a raw string to an arbitrary string encoding
43853 function rstr2any(input, encoding) {
43854 var divisor = encoding.length,
43855 remainders = Array(),
43856 i, q, x, ld, quotient, dividend, output, full_length;
43858 /* Convert to an array of 16-bit big-endian values, forming the dividend */
43859 dividend = Array(Math.ceil(input.length / 2));
43860 ld = dividend.length;
43861 for (i = 0; i < ld; i += 1) {
43862 dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
43866 * Repeatedly perform a long division. The binary array forms the dividend,
43867 * the length of the encoding is the divisor. Once computed, the quotient
43868 * forms the dividend for the next step. We stop when the dividend is zerHashes.
43869 * All remainders are stored for later use.
43871 while (dividend.length > 0) {
43872 quotient = Array();
43874 for (i = 0; i < dividend.length; i += 1) {
43875 x = (x << 16) + dividend[i];
43876 q = Math.floor(x / divisor);
43878 if (quotient.length > 0 || q > 0) {
43879 quotient[quotient.length] = q;
43882 remainders[remainders.length] = x;
43883 dividend = quotient;
43886 /* Convert the remainders to the output string */
43888 for (i = remainders.length - 1; i >= 0; i--) {
43889 output += encoding.charAt(remainders[i]);
43892 /* Append leading zero equivalents */
43893 full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
43894 for (i = output.length; i < full_length; i += 1) {
43895 output = encoding[0] + output;
43901 * Convert a raw string to a base-64 string
43904 function rstr2b64(input, b64pad) {
43905 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
43907 len = input.length,
43909 b64pad = b64pad || '=';
43910 for (i = 0; i < len; i += 3) {
43911 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
43912 for (j = 0; j < 4; j += 1) {
43913 if (i * 8 + j * 6 > input.length * 8) {
43916 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
43925 * @property {String} version
43934 Base64: function() {
43935 // private properties
43936 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
43937 pad = '=', // default pad according with the RFC standard
43938 url = false, // URL encoding support @todo
43939 utf8 = true; // by default enable UTF-8 support encoding
43941 // public method for encoding
43942 this.encode = function(input) {
43945 len = input.length;
43948 input = (utf8) ? utf8Encode(input) : input;
43950 for (i = 0; i < len; i += 3) {
43951 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
43952 for (j = 0; j < 4; j += 1) {
43953 if (i * 8 + j * 6 > len * 8) {
43956 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
43963 // public method for decoding
43964 this.decode = function(input) {
43965 // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
43966 var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
43974 input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
43977 do { // unpack four hexets into three octets using index points in b64
43978 h1 = tab.indexOf(input.charAt(i += 1));
43979 h2 = tab.indexOf(input.charAt(i += 1));
43980 h3 = tab.indexOf(input.charAt(i += 1));
43981 h4 = tab.indexOf(input.charAt(i += 1));
43983 bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
43985 o1 = bits >> 16 & 0xff;
43986 o2 = bits >> 8 & 0xff;
43991 arr[ac] = String.fromCharCode(o1);
43992 } else if (h4 === 64) {
43993 arr[ac] = String.fromCharCode(o1, o2);
43995 arr[ac] = String.fromCharCode(o1, o2, o3);
43997 } while (i < input.length);
43999 dec = arr.join('');
44000 dec = (utf8) ? utf8Decode(dec) : dec;
44005 // set custom pad string
44006 this.setPad = function(str) {
44010 // set custom tab string characters
44011 this.setTab = function(str) {
44015 this.setUTF8 = function(bool) {
44016 if (typeof bool === 'boolean') {
44024 * CRC-32 calculation
44028 * @param {String} str Input String
44031 CRC32: function(str) {
44036 str = utf8Encode(str);
44039 '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
44040 '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
44041 '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
44042 '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
44043 'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
44044 '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
44045 'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
44046 '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
44047 'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
44048 '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
44049 'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
44050 '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
44051 'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
44052 '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
44053 '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
44054 '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
44055 '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
44056 'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
44057 '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
44058 'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
44059 '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
44060 'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
44061 '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
44062 'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
44063 '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
44064 'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
44068 for (i = 0, iTop = str.length; i < iTop; i += 1) {
44069 y = (crc ^ str.charCodeAt(i)) & 0xFF;
44070 x = '0x' + table.substr(y * 9, 8);
44071 crc = (crc >>> 8) ^ x;
44073 // always return a positive number (that's what >>> 0 does)
44074 return (crc ^ (-1)) >>> 0;
44080 * @param {Object} [config]
44082 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
44083 * Digest Algorithm, as defined in RFC 1321.
44084 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
44085 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44086 * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
44088 MD5: function(options) {
44090 * Private config properties. You may need to tweak these to be compatible with
44091 * the server-side, but the defaults work in most cases.
44092 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44094 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44095 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44096 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44098 // privileged (public) methods
44099 this.hex = function(s) {
44100 return rstr2hex(rstr(s, utf8), hexcase);
44102 this.b64 = function(s) {
44103 return rstr2b64(rstr(s), b64pad);
44105 this.any = function(s, e) {
44106 return rstr2any(rstr(s, utf8), e);
44108 this.raw = function(s) {
44109 return rstr(s, utf8);
44111 this.hex_hmac = function(k, d) {
44112 return rstr2hex(rstr_hmac(k, d), hexcase);
44114 this.b64_hmac = function(k, d) {
44115 return rstr2b64(rstr_hmac(k, d), b64pad);
44117 this.any_hmac = function(k, d, e) {
44118 return rstr2any(rstr_hmac(k, d), e);
44121 * Perform a simple self-test to see if the VM is working
44122 * @return {String} Hexadecimal hash sample
44124 this.vm_test = function() {
44125 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44128 * Enable/disable uppercase hexadecimal returned string
44130 * @return {Object} this
44132 this.setUpperCase = function(a) {
44133 if (typeof a === 'boolean') {
44139 * Defines a base64 pad string
44140 * @param {String} Pad
44141 * @return {Object} this
44143 this.setPad = function(a) {
44144 b64pad = a || b64pad;
44148 * Defines a base64 pad string
44150 * @return {Object} [this]
44152 this.setUTF8 = function(a) {
44153 if (typeof a === 'boolean') {
44162 * Calculate the MD5 of a raw string
44166 s = (utf8) ? utf8Encode(s) : s;
44167 return binl2rstr(binl(rstr2binl(s), s.length * 8));
44171 * Calculate the HMAC-MD5, of a key and some data (raw strings)
44174 function rstr_hmac(key, data) {
44175 var bkey, ipad, opad, hash, i;
44177 key = (utf8) ? utf8Encode(key) : key;
44178 data = (utf8) ? utf8Encode(data) : data;
44179 bkey = rstr2binl(key);
44180 if (bkey.length > 16) {
44181 bkey = binl(bkey, key.length * 8);
44184 ipad = Array(16), opad = Array(16);
44185 for (i = 0; i < 16; i += 1) {
44186 ipad[i] = bkey[i] ^ 0x36363636;
44187 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44189 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
44190 return binl2rstr(binl(opad.concat(hash), 512 + 128));
44194 * Calculate the MD5 of an array of little-endian words, and a bit length.
44197 function binl(x, len) {
44198 var i, olda, oldb, oldc, oldd,
44204 /* append padding */
44205 x[len >> 5] |= 0x80 << ((len) % 32);
44206 x[(((len + 64) >>> 9) << 4) + 14] = len;
44208 for (i = 0; i < x.length; i += 16) {
44214 a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
44215 d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
44216 c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
44217 b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
44218 a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
44219 d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
44220 c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
44221 b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
44222 a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
44223 d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
44224 c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
44225 b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
44226 a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
44227 d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
44228 c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
44229 b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
44231 a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
44232 d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
44233 c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
44234 b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
44235 a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
44236 d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
44237 c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
44238 b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
44239 a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
44240 d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
44241 c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
44242 b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
44243 a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
44244 d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
44245 c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
44246 b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
44248 a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
44249 d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
44250 c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
44251 b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
44252 a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
44253 d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
44254 c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
44255 b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
44256 a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
44257 d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
44258 c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
44259 b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
44260 a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
44261 d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
44262 c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
44263 b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
44265 a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
44266 d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
44267 c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
44268 b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
44269 a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
44270 d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
44271 c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
44272 b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
44273 a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
44274 d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
44275 c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
44276 b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
44277 a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
44278 d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
44279 c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
44280 b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
44282 a = safe_add(a, olda);
44283 b = safe_add(b, oldb);
44284 c = safe_add(c, oldc);
44285 d = safe_add(d, oldd);
44287 return Array(a, b, c, d);
44291 * These functions implement the four basic operations the algorithm uses.
44294 function md5_cmn(q, a, b, x, s, t) {
44295 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
44298 function md5_ff(a, b, c, d, x, s, t) {
44299 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
44302 function md5_gg(a, b, c, d, x, s, t) {
44303 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
44306 function md5_hh(a, b, c, d, x, s, t) {
44307 return md5_cmn(b ^ c ^ d, a, b, x, s, t);
44310 function md5_ii(a, b, c, d, x, s, t) {
44311 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
44316 * @class Hashes.SHA1
44317 * @param {Object} [config]
44320 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
44321 * Version 2.2 Copyright Paul Johnston 2000 - 2009.
44322 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44323 * See http://pajhome.org.uk/crypt/md5 for details.
44325 SHA1: function(options) {
44327 * Private config properties. You may need to tweak these to be compatible with
44328 * the server-side, but the defaults work in most cases.
44329 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44331 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44332 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44333 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44336 this.hex = function(s) {
44337 return rstr2hex(rstr(s, utf8), hexcase);
44339 this.b64 = function(s) {
44340 return rstr2b64(rstr(s, utf8), b64pad);
44342 this.any = function(s, e) {
44343 return rstr2any(rstr(s, utf8), e);
44345 this.raw = function(s) {
44346 return rstr(s, utf8);
44348 this.hex_hmac = function(k, d) {
44349 return rstr2hex(rstr_hmac(k, d));
44351 this.b64_hmac = function(k, d) {
44352 return rstr2b64(rstr_hmac(k, d), b64pad);
44354 this.any_hmac = function(k, d, e) {
44355 return rstr2any(rstr_hmac(k, d), e);
44358 * Perform a simple self-test to see if the VM is working
44359 * @return {String} Hexadecimal hash sample
44362 this.vm_test = function() {
44363 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44366 * @description Enable/disable uppercase hexadecimal returned string
44368 * @return {Object} this
44371 this.setUpperCase = function(a) {
44372 if (typeof a === 'boolean') {
44378 * @description Defines a base64 pad string
44379 * @param {string} Pad
44380 * @return {Object} this
44383 this.setPad = function(a) {
44384 b64pad = a || b64pad;
44388 * @description Defines a base64 pad string
44390 * @return {Object} this
44393 this.setUTF8 = function(a) {
44394 if (typeof a === 'boolean') {
44403 * Calculate the SHA-512 of a raw string
44407 s = (utf8) ? utf8Encode(s) : s;
44408 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44412 * Calculate the HMAC-SHA1 of a key and some data (raw strings)
44415 function rstr_hmac(key, data) {
44416 var bkey, ipad, opad, i, hash;
44417 key = (utf8) ? utf8Encode(key) : key;
44418 data = (utf8) ? utf8Encode(data) : data;
44419 bkey = rstr2binb(key);
44421 if (bkey.length > 16) {
44422 bkey = binb(bkey, key.length * 8);
44424 ipad = Array(16), opad = Array(16);
44425 for (i = 0; i < 16; i += 1) {
44426 ipad[i] = bkey[i] ^ 0x36363636;
44427 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44429 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
44430 return binb2rstr(binb(opad.concat(hash), 512 + 160));
44434 * Calculate the SHA-1 of an array of big-endian words, and a bit length
44437 function binb(x, len) {
44438 var i, j, t, olda, oldb, oldc, oldd, olde,
44446 /* append padding */
44447 x[len >> 5] |= 0x80 << (24 - len % 32);
44448 x[((len + 64 >> 9) << 4) + 15] = len;
44450 for (i = 0; i < x.length; i += 16) {
44457 for (j = 0; j < 80; j += 1) {
44461 w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
44463 t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
44464 safe_add(safe_add(e, w[j]), sha1_kt(j)));
44467 c = bit_rol(b, 30);
44472 a = safe_add(a, olda);
44473 b = safe_add(b, oldb);
44474 c = safe_add(c, oldc);
44475 d = safe_add(d, oldd);
44476 e = safe_add(e, olde);
44478 return Array(a, b, c, d, e);
44482 * Perform the appropriate triplet combination function for the current
44486 function sha1_ft(t, b, c, d) {
44488 return (b & c) | ((~b) & d);
44494 return (b & c) | (b & d) | (c & d);
44500 * Determine the appropriate additive constant for the current iteration
44503 function sha1_kt(t) {
44504 return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
44505 (t < 60) ? -1894007588 : -899497514;
44509 * @class Hashes.SHA256
44512 * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
44513 * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
44514 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44515 * See http://pajhome.org.uk/crypt/md5 for details.
44516 * Also http://anmar.eu.org/projects/jssha2/
44518 SHA256: function(options) {
44520 * Private properties configuration variables. You may need to tweak these to be compatible with
44521 * the server-side, but the defaults work in most cases.
44522 * @see this.setUpperCase() method
44523 * @see this.setPad() method
44525 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase */
44526 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
44527 /* base-64 pad character. Default '=' for strict RFC compliance */
44528 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
44529 /* enable/disable utf8 encoding */
44532 /* privileged (public) methods */
44533 this.hex = function(s) {
44534 return rstr2hex(rstr(s, utf8));
44536 this.b64 = function(s) {
44537 return rstr2b64(rstr(s, utf8), b64pad);
44539 this.any = function(s, e) {
44540 return rstr2any(rstr(s, utf8), e);
44542 this.raw = function(s) {
44543 return rstr(s, utf8);
44545 this.hex_hmac = function(k, d) {
44546 return rstr2hex(rstr_hmac(k, d));
44548 this.b64_hmac = function(k, d) {
44549 return rstr2b64(rstr_hmac(k, d), b64pad);
44551 this.any_hmac = function(k, d, e) {
44552 return rstr2any(rstr_hmac(k, d), e);
44555 * Perform a simple self-test to see if the VM is working
44556 * @return {String} Hexadecimal hash sample
44559 this.vm_test = function() {
44560 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44563 * Enable/disable uppercase hexadecimal returned string
44565 * @return {Object} this
44568 this.setUpperCase = function(a) {
44569 if (typeof a === 'boolean') {
44575 * @description Defines a base64 pad string
44576 * @param {string} Pad
44577 * @return {Object} this
44580 this.setPad = function(a) {
44581 b64pad = a || b64pad;
44585 * Defines a base64 pad string
44587 * @return {Object} this
44590 this.setUTF8 = function(a) {
44591 if (typeof a === 'boolean') {
44600 * Calculate the SHA-512 of a raw string
44603 function rstr(s, utf8) {
44604 s = (utf8) ? utf8Encode(s) : s;
44605 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44609 * Calculate the HMAC-sha256 of a key and some data (raw strings)
44612 function rstr_hmac(key, data) {
44613 key = (utf8) ? utf8Encode(key) : key;
44614 data = (utf8) ? utf8Encode(data) : data;
44616 bkey = rstr2binb(key),
44620 if (bkey.length > 16) {
44621 bkey = binb(bkey, key.length * 8);
44624 for (; i < 16; i += 1) {
44625 ipad[i] = bkey[i] ^ 0x36363636;
44626 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44629 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
44630 return binb2rstr(binb(opad.concat(hash), 512 + 256));
44634 * Main sha256 function, with its support functions
44637 function sha256_S(X, n) {
44638 return (X >>> n) | (X << (32 - n));
44641 function sha256_R(X, n) {
44645 function sha256_Ch(x, y, z) {
44646 return ((x & y) ^ ((~x) & z));
44649 function sha256_Maj(x, y, z) {
44650 return ((x & y) ^ (x & z) ^ (y & z));
44653 function sha256_Sigma0256(x) {
44654 return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
44657 function sha256_Sigma1256(x) {
44658 return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
44661 function sha256_Gamma0256(x) {
44662 return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
44665 function sha256_Gamma1256(x) {
44666 return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
44669 function sha256_Sigma0512(x) {
44670 return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));
44673 function sha256_Sigma1512(x) {
44674 return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));
44677 function sha256_Gamma0512(x) {
44678 return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));
44681 function sha256_Gamma1512(x) {
44682 return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));
44686 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
44687 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
44688 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
44689 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
44690 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
44691 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
44692 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
44695 function binb(m, l) {
44696 var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
44697 1359893119, -1694144372, 528734635, 1541459225
44699 var W = new Array(64);
44700 var a, b, c, d, e, f, g, h;
44703 /* append padding */
44704 m[l >> 5] |= 0x80 << (24 - l % 32);
44705 m[((l + 64 >> 9) << 4) + 15] = l;
44707 for (i = 0; i < m.length; i += 16) {
44717 for (j = 0; j < 64; j += 1) {
44721 W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
44722 sha256_Gamma0256(W[j - 15])), W[j - 16]);
44725 T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
44726 sha256_K[j]), W[j]);
44727 T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
44731 e = safe_add(d, T1);
44735 a = safe_add(T1, T2);
44738 HASH[0] = safe_add(a, HASH[0]);
44739 HASH[1] = safe_add(b, HASH[1]);
44740 HASH[2] = safe_add(c, HASH[2]);
44741 HASH[3] = safe_add(d, HASH[3]);
44742 HASH[4] = safe_add(e, HASH[4]);
44743 HASH[5] = safe_add(f, HASH[5]);
44744 HASH[6] = safe_add(g, HASH[6]);
44745 HASH[7] = safe_add(h, HASH[7]);
44753 * @class Hashes.SHA512
44756 * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
44757 * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
44758 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44759 * See http://pajhome.org.uk/crypt/md5 for details.
44761 SHA512: function(options) {
44763 * Private properties configuration variables. You may need to tweak these to be compatible with
44764 * the server-side, but the defaults work in most cases.
44765 * @see this.setUpperCase() method
44766 * @see this.setPad() method
44768 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
44769 /* hexadecimal output case format. false - lowercase; true - uppercase */
44770 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
44771 /* base-64 pad character. Default '=' for strict RFC compliance */
44772 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
44773 /* enable/disable utf8 encoding */
44776 /* privileged (public) methods */
44777 this.hex = function(s) {
44778 return rstr2hex(rstr(s));
44780 this.b64 = function(s) {
44781 return rstr2b64(rstr(s), b64pad);
44783 this.any = function(s, e) {
44784 return rstr2any(rstr(s), e);
44786 this.raw = function(s) {
44787 return rstr(s, utf8);
44789 this.hex_hmac = function(k, d) {
44790 return rstr2hex(rstr_hmac(k, d));
44792 this.b64_hmac = function(k, d) {
44793 return rstr2b64(rstr_hmac(k, d), b64pad);
44795 this.any_hmac = function(k, d, e) {
44796 return rstr2any(rstr_hmac(k, d), e);
44799 * Perform a simple self-test to see if the VM is working
44800 * @return {String} Hexadecimal hash sample
44803 this.vm_test = function() {
44804 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44807 * @description Enable/disable uppercase hexadecimal returned string
44809 * @return {Object} this
44812 this.setUpperCase = function(a) {
44813 if (typeof a === 'boolean') {
44819 * @description Defines a base64 pad string
44820 * @param {string} Pad
44821 * @return {Object} this
44824 this.setPad = function(a) {
44825 b64pad = a || b64pad;
44829 * @description Defines a base64 pad string
44831 * @return {Object} this
44834 this.setUTF8 = function(a) {
44835 if (typeof a === 'boolean') {
44841 /* private methods */
44844 * Calculate the SHA-512 of a raw string
44848 s = (utf8) ? utf8Encode(s) : s;
44849 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44852 * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
44855 function rstr_hmac(key, data) {
44856 key = (utf8) ? utf8Encode(key) : key;
44857 data = (utf8) ? utf8Encode(data) : data;
44860 bkey = rstr2binb(key),
44864 if (bkey.length > 32) {
44865 bkey = binb(bkey, key.length * 8);
44868 for (; i < 32; i += 1) {
44869 ipad[i] = bkey[i] ^ 0x36363636;
44870 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44873 hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
44874 return binb2rstr(binb(opad.concat(hash), 1024 + 512));
44878 * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
44881 function binb(x, len) {
44884 hash = new Array(16),
44885 //Initial hash values
44887 new int64(0x6a09e667, -205731576),
44888 new int64(-1150833019, -2067093701),
44889 new int64(0x3c6ef372, -23791573),
44890 new int64(-1521486534, 0x5f1d36f1),
44891 new int64(0x510e527f, -1377402159),
44892 new int64(-1694144372, 0x2b3e6c1f),
44893 new int64(0x1f83d9ab, -79577749),
44894 new int64(0x5be0cd19, 0x137e2179)
44896 T1 = new int64(0, 0),
44897 T2 = new int64(0, 0),
44898 a = new int64(0, 0),
44899 b = new int64(0, 0),
44900 c = new int64(0, 0),
44901 d = new int64(0, 0),
44902 e = new int64(0, 0),
44903 f = new int64(0, 0),
44904 g = new int64(0, 0),
44905 h = new int64(0, 0),
44906 //Temporary variables not specified by the document
44907 s0 = new int64(0, 0),
44908 s1 = new int64(0, 0),
44909 Ch = new int64(0, 0),
44910 Maj = new int64(0, 0),
44911 r1 = new int64(0, 0),
44912 r2 = new int64(0, 0),
44913 r3 = new int64(0, 0);
44915 if (sha512_k === undefined) {
44918 new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
44919 new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
44920 new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
44921 new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
44922 new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
44923 new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
44924 new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
44925 new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
44926 new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
44927 new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
44928 new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
44929 new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
44930 new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
44931 new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
44932 new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
44933 new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
44934 new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
44935 new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
44936 new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
44937 new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
44938 new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
44939 new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
44940 new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
44941 new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
44942 new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
44943 new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
44944 new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
44945 new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
44946 new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
44947 new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
44948 new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
44949 new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
44950 new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
44951 new int64(-354779690, -840897762), new int64(-176337025, -294727304),
44952 new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
44953 new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
44954 new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
44955 new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
44956 new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
44957 new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
44961 for (i = 0; i < 80; i += 1) {
44962 W[i] = new int64(0, 0);
44965 // append padding to the source string. The format is described in the FIPS.
44966 x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
44967 x[((len + 128 >> 10) << 5) + 31] = len;
44969 for (i = 0; i < l; i += 32) { //32 dwords is the block size
44970 int64copy(a, H[0]);
44971 int64copy(b, H[1]);
44972 int64copy(c, H[2]);
44973 int64copy(d, H[3]);
44974 int64copy(e, H[4]);
44975 int64copy(f, H[5]);
44976 int64copy(g, H[6]);
44977 int64copy(h, H[7]);
44979 for (j = 0; j < 16; j += 1) {
44980 W[j].h = x[i + 2 * j];
44981 W[j].l = x[i + 2 * j + 1];
44984 for (j = 16; j < 80; j += 1) {
44986 int64rrot(r1, W[j - 2], 19);
44987 int64revrrot(r2, W[j - 2], 29);
44988 int64shr(r3, W[j - 2], 6);
44989 s1.l = r1.l ^ r2.l ^ r3.l;
44990 s1.h = r1.h ^ r2.h ^ r3.h;
44992 int64rrot(r1, W[j - 15], 1);
44993 int64rrot(r2, W[j - 15], 8);
44994 int64shr(r3, W[j - 15], 7);
44995 s0.l = r1.l ^ r2.l ^ r3.l;
44996 s0.h = r1.h ^ r2.h ^ r3.h;
44998 int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
45001 for (j = 0; j < 80; j += 1) {
45003 Ch.l = (e.l & f.l) ^ (~e.l & g.l);
45004 Ch.h = (e.h & f.h) ^ (~e.h & g.h);
45007 int64rrot(r1, e, 14);
45008 int64rrot(r2, e, 18);
45009 int64revrrot(r3, e, 9);
45010 s1.l = r1.l ^ r2.l ^ r3.l;
45011 s1.h = r1.h ^ r2.h ^ r3.h;
45014 int64rrot(r1, a, 28);
45015 int64revrrot(r2, a, 2);
45016 int64revrrot(r3, a, 7);
45017 s0.l = r1.l ^ r2.l ^ r3.l;
45018 s0.h = r1.h ^ r2.h ^ r3.h;
45021 Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
45022 Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
45024 int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
45025 int64add(T2, s0, Maj);
45030 int64add(e, d, T1);
45034 int64add(a, T1, T2);
45036 int64add(H[0], H[0], a);
45037 int64add(H[1], H[1], b);
45038 int64add(H[2], H[2], c);
45039 int64add(H[3], H[3], d);
45040 int64add(H[4], H[4], e);
45041 int64add(H[5], H[5], f);
45042 int64add(H[6], H[6], g);
45043 int64add(H[7], H[7], h);
45046 //represent the hash as an array of 32-bit dwords
45047 for (i = 0; i < 8; i += 1) {
45048 hash[2 * i] = H[i].h;
45049 hash[2 * i + 1] = H[i].l;
45054 //A constructor for 64-bit numbers
45056 function int64(h, l) {
45059 //this.toString = int64toString;
45062 //Copies src into dst, assuming both are 64-bit numbers
45064 function int64copy(dst, src) {
45069 //Right-rotates a 64-bit number by shift
45070 //Won't handle cases of shift>=32
45071 //The function revrrot() is for that
45073 function int64rrot(dst, x, shift) {
45074 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45075 dst.h = (x.h >>> shift) | (x.l << (32 - shift));
45078 //Reverses the dwords of the source and then rotates right by shift.
45079 //This is equivalent to rotation by 32+shift
45081 function int64revrrot(dst, x, shift) {
45082 dst.l = (x.h >>> shift) | (x.l << (32 - shift));
45083 dst.h = (x.l >>> shift) | (x.h << (32 - shift));
45086 //Bitwise-shifts right a 64-bit number by shift
45087 //Won't handle shift>=32, but it's never needed in SHA512
45089 function int64shr(dst, x, shift) {
45090 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45091 dst.h = (x.h >>> shift);
45094 //Adds two 64-bit numbers
45095 //Like the original implementation, does not rely on 32-bit operations
45097 function int64add(dst, x, y) {
45098 var w0 = (x.l & 0xffff) + (y.l & 0xffff);
45099 var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
45100 var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
45101 var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
45102 dst.l = (w0 & 0xffff) | (w1 << 16);
45103 dst.h = (w2 & 0xffff) | (w3 << 16);
45106 //Same, except with 4 addends. Works faster than adding them one by one.
45108 function int64add4(dst, a, b, c, d) {
45109 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
45110 var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
45111 var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
45112 var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
45113 dst.l = (w0 & 0xffff) | (w1 << 16);
45114 dst.h = (w2 & 0xffff) | (w3 << 16);
45117 //Same, except with 5 addends
45119 function int64add5(dst, a, b, c, d, e) {
45120 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
45121 w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
45122 w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
45123 w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
45124 dst.l = (w0 & 0xffff) | (w1 << 16);
45125 dst.h = (w2 & 0xffff) | (w3 << 16);
45129 * @class Hashes.RMD160
45131 * @param {Object} [config]
45133 * A JavaScript implementation of the RIPEMD-160 Algorithm
45134 * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
45135 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45136 * See http://pajhome.org.uk/crypt/md5 for details.
45137 * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
45139 RMD160: function(options) {
45141 * Private properties configuration variables. You may need to tweak these to be compatible with
45142 * the server-side, but the defaults work in most cases.
45143 * @see this.setUpperCase() method
45144 * @see this.setPad() method
45146 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
45147 /* hexadecimal output case format. false - lowercase; true - uppercase */
45148 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45149 /* base-64 pad character. Default '=' for strict RFC compliance */
45150 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45151 /* enable/disable utf8 encoding */
45153 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
45154 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
45155 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
45156 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
45157 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
45160 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
45161 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
45162 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
45163 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
45164 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
45167 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
45168 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
45169 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
45170 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
45171 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
45174 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
45175 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
45176 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
45177 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
45178 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
45181 /* privileged (public) methods */
45182 this.hex = function(s) {
45183 return rstr2hex(rstr(s, utf8));
45185 this.b64 = function(s) {
45186 return rstr2b64(rstr(s, utf8), b64pad);
45188 this.any = function(s, e) {
45189 return rstr2any(rstr(s, utf8), e);
45191 this.raw = function(s) {
45192 return rstr(s, utf8);
45194 this.hex_hmac = function(k, d) {
45195 return rstr2hex(rstr_hmac(k, d));
45197 this.b64_hmac = function(k, d) {
45198 return rstr2b64(rstr_hmac(k, d), b64pad);
45200 this.any_hmac = function(k, d, e) {
45201 return rstr2any(rstr_hmac(k, d), e);
45204 * Perform a simple self-test to see if the VM is working
45205 * @return {String} Hexadecimal hash sample
45208 this.vm_test = function() {
45209 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45212 * @description Enable/disable uppercase hexadecimal returned string
45214 * @return {Object} this
45217 this.setUpperCase = function(a) {
45218 if (typeof a === 'boolean') {
45224 * @description Defines a base64 pad string
45225 * @param {string} Pad
45226 * @return {Object} this
45229 this.setPad = function(a) {
45230 if (typeof a !== 'undefined') {
45236 * @description Defines a base64 pad string
45238 * @return {Object} this
45241 this.setUTF8 = function(a) {
45242 if (typeof a === 'boolean') {
45248 /* private methods */
45251 * Calculate the rmd160 of a raw string
45255 s = (utf8) ? utf8Encode(s) : s;
45256 return binl2rstr(binl(rstr2binl(s), s.length * 8));
45260 * Calculate the HMAC-rmd160 of a key and some data (raw strings)
45263 function rstr_hmac(key, data) {
45264 key = (utf8) ? utf8Encode(key) : key;
45265 data = (utf8) ? utf8Encode(data) : data;
45267 bkey = rstr2binl(key),
45271 if (bkey.length > 16) {
45272 bkey = binl(bkey, key.length * 8);
45275 for (i = 0; i < 16; i += 1) {
45276 ipad[i] = bkey[i] ^ 0x36363636;
45277 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45279 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
45280 return binl2rstr(binl(opad.concat(hash), 512 + 160));
45284 * Convert an array of little-endian words to a string
45287 function binl2rstr(input) {
45288 var i, output = '',
45289 l = input.length * 32;
45290 for (i = 0; i < l; i += 8) {
45291 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
45297 * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
45300 function binl(x, len) {
45307 A1, B1, C1, D1, E1,
45308 A2, B2, C2, D2, E2;
45310 /* append padding */
45311 x[len >> 5] |= 0x80 << (len % 32);
45312 x[(((len + 64) >>> 9) << 4) + 14] = len;
45315 for (i = 0; i < l; i += 16) {
45321 for (j = 0; j <= 79; j += 1) {
45322 T = safe_add(A1, rmd160_f(j, B1, C1, D1));
45323 T = safe_add(T, x[i + rmd160_r1[j]]);
45324 T = safe_add(T, rmd160_K1(j));
45325 T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
45328 D1 = bit_rol(C1, 10);
45331 T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
45332 T = safe_add(T, x[i + rmd160_r2[j]]);
45333 T = safe_add(T, rmd160_K2(j));
45334 T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
45337 D2 = bit_rol(C2, 10);
45342 T = safe_add(h1, safe_add(C1, D2));
45343 h1 = safe_add(h2, safe_add(D1, E2));
45344 h2 = safe_add(h3, safe_add(E1, A2));
45345 h3 = safe_add(h4, safe_add(A1, B2));
45346 h4 = safe_add(h0, safe_add(B1, C2));
45349 return [h0, h1, h2, h3, h4];
45352 // specific algorithm methods
45354 function rmd160_f(j, x, y, z) {
45355 return (0 <= j && j <= 15) ? (x ^ y ^ z) :
45356 (16 <= j && j <= 31) ? (x & y) | (~x & z) :
45357 (32 <= j && j <= 47) ? (x | ~y) ^ z :
45358 (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
45359 (64 <= j && j <= 79) ? x ^ (y | ~z) :
45360 'rmd160_f: j out of range';
45363 function rmd160_K1(j) {
45364 return (0 <= j && j <= 15) ? 0x00000000 :
45365 (16 <= j && j <= 31) ? 0x5a827999 :
45366 (32 <= j && j <= 47) ? 0x6ed9eba1 :
45367 (48 <= j && j <= 63) ? 0x8f1bbcdc :
45368 (64 <= j && j <= 79) ? 0xa953fd4e :
45369 'rmd160_K1: j out of range';
45372 function rmd160_K2(j) {
45373 return (0 <= j && j <= 15) ? 0x50a28be6 :
45374 (16 <= j && j <= 31) ? 0x5c4dd124 :
45375 (32 <= j && j <= 47) ? 0x6d703ef3 :
45376 (48 <= j && j <= 63) ? 0x7a6d76e9 :
45377 (64 <= j && j <= 79) ? 0x00000000 :
45378 'rmd160_K2: j out of range';
45384 (function(window, undefined) {
45385 var freeExports = false;
45386 if (typeof exports === 'object') {
45387 freeExports = exports;
45388 if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
45389 window = commonjsGlobal;
45393 if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
45394 // define as an anonymous module, so, through path mapping, it can be aliased
45395 define(function() {
45398 } else if (freeExports) {
45399 // in Node.js or RingoJS v0.8.0+
45400 if (typeof module === 'object' && module && module.exports === freeExports) {
45401 module.exports = Hashes;
45403 // in Narwhal or RingoJS v0.7.0-
45405 freeExports.Hashes = Hashes;
45408 // in a browser or Rhino
45409 window.Hashes = Hashes;
45415 var immutable = extend$2;
45417 var hasOwnProperty = Object.prototype.hasOwnProperty;
45419 function extend$2() {
45422 for (var i = 0; i < arguments.length; i++) {
45423 var source = arguments[i];
45425 for (var key in source) {
45426 if (hasOwnProperty.call(source, key)) {
45427 target[key] = source[key];
45435 var hashes = hashes$1;
45436 var xtend$1 = immutable;
45437 var sha1 = new hashes.SHA1();
45441 ohauth$1.qsString = function(obj) {
45442 return Object.keys(obj).sort().map(function(key) {
45443 return ohauth$1.percentEncode(key) + '=' +
45444 ohauth$1.percentEncode(obj[key]);
45448 ohauth$1.stringQs = function(str) {
45449 return str.split('&').filter(function (pair) {
45450 return pair !== '';
45451 }).reduce(function(obj, pair){
45452 var parts = pair.split('=');
45453 obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
45454 '' : decodeURIComponent(parts[1]);
45459 ohauth$1.rawxhr = function(method, url, data, headers, callback) {
45460 var xhr = new XMLHttpRequest(),
45461 twoHundred = /^20\d$/;
45462 xhr.onreadystatechange = function() {
45463 if (4 === xhr.readyState && 0 !== xhr.status) {
45464 if (twoHundred.test(xhr.status)) callback(null, xhr);
45465 else return callback(xhr, null);
45468 xhr.onerror = function(e) { return callback(e, null); };
45469 xhr.open(method, url, true);
45470 for (var h in headers) xhr.setRequestHeader(h, headers[h]);
45475 ohauth$1.xhr = function(method, url, auth, data, options, callback) {
45476 var headers = (options && options.header) || {
45477 'Content-Type': 'application/x-www-form-urlencoded'
45479 headers.Authorization = 'OAuth ' + ohauth$1.authHeader(auth);
45480 return ohauth$1.rawxhr(method, url, data, headers, callback);
45483 ohauth$1.nonce = function() {
45484 for (var o = ''; o.length < 6;) {
45485 o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
45490 ohauth$1.authHeader = function(obj) {
45491 return Object.keys(obj).sort().map(function(key) {
45492 return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
45496 ohauth$1.timestamp = function() { return ~~((+new Date()) / 1000); };
45498 ohauth$1.percentEncode = function(s) {
45499 return encodeURIComponent(s)
45500 .replace(/\!/g, '%21').replace(/\'/g, '%27')
45501 .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
45504 ohauth$1.baseString = function(method, url, params) {
45505 if (params.oauth_signature) delete params.oauth_signature;
45508 ohauth$1.percentEncode(url),
45509 ohauth$1.percentEncode(ohauth$1.qsString(params))].join('&');
45512 ohauth$1.signature = function(oauth_secret, token_secret, baseString) {
45513 return sha1.b64_hmac(
45514 ohauth$1.percentEncode(oauth_secret) + '&' +
45515 ohauth$1.percentEncode(token_secret),
45520 * Takes an options object for configuration (consumer_key,
45521 * consumer_secret, version, signature_method, token, token_secret)
45522 * and returns a function that generates the Authorization header
45525 * The returned function takes these parameters:
45526 * - method: GET/POST/...
45527 * - uri: full URI with protocol, port, path and query string
45528 * - extra_params: any extra parameters (that are passed in the POST data),
45529 * can be an object or a from-urlencoded string.
45531 * Returned function returns full OAuth header with "OAuth" string in it.
45534 ohauth$1.headerGenerator = function(options) {
45535 options = options || {};
45536 var consumer_key = options.consumer_key || '',
45537 consumer_secret = options.consumer_secret || '',
45538 signature_method = options.signature_method || 'HMAC-SHA1',
45539 version = options.version || '1.0',
45540 token = options.token || '',
45541 token_secret = options.token_secret || '';
45543 return function(method, uri, extra_params) {
45544 method = method.toUpperCase();
45545 if (typeof extra_params === 'string' && extra_params.length > 0) {
45546 extra_params = ohauth$1.stringQs(extra_params);
45549 var uri_parts = uri.split('?', 2),
45550 base_uri = uri_parts[0];
45552 var query_params = uri_parts.length === 2 ?
45553 ohauth$1.stringQs(uri_parts[1]) : {};
45555 var oauth_params = {
45556 oauth_consumer_key: consumer_key,
45557 oauth_signature_method: signature_method,
45558 oauth_version: version,
45559 oauth_timestamp: ohauth$1.timestamp(),
45560 oauth_nonce: ohauth$1.nonce()
45563 if (token) oauth_params.oauth_token = token;
45565 var all_params = xtend$1({}, oauth_params, query_params, extra_params),
45566 base_str = ohauth$1.baseString(method, base_uri, all_params);
45568 oauth_params.oauth_signature = ohauth$1.signature(consumer_secret, token_secret, base_str);
45570 return 'OAuth ' + ohauth$1.authHeader(oauth_params);
45574 var index$12 = ohauth$1;
45576 var store$1 = createCommonjsModule(function (module, exports) {
45578 // Module export pattern from
45579 // https://github.com/umdjs/umd/blob/master/returnExports.js
45580 ;(function (root, factory) {
45581 if (typeof define === 'function' && define.amd) {
45582 // AMD. Register as an anonymous module.
45583 define([], factory);
45584 } else if (typeof exports === 'object') {
45585 // Node. Does not work with strict CommonJS, but
45586 // only CommonJS-like environments that support module.exports,
45588 module.exports = factory();
45590 // Browser globals (root is window)
45591 root.store = factory();
45593 }(commonjsGlobal, function () {
45597 win = (typeof window != 'undefined' ? window : commonjsGlobal),
45598 doc = win.document,
45599 localStorageName = 'localStorage',
45600 scriptTag = 'script',
45603 store.disabled = false;
45604 store.version = '1.3.20';
45605 store.set = function(key, value) {};
45606 store.get = function(key, defaultVal) {};
45607 store.has = function(key) { return store.get(key) !== undefined };
45608 store.remove = function(key) {};
45609 store.clear = function() {};
45610 store.transact = function(key, defaultVal, transactionFn) {
45611 if (transactionFn == null) {
45612 transactionFn = defaultVal;
45615 if (defaultVal == null) {
45618 var val = store.get(key, defaultVal);
45619 transactionFn(val);
45620 store.set(key, val);
45622 store.getAll = function() {};
45623 store.forEach = function() {};
45625 store.serialize = function(value) {
45626 return JSON.stringify(value)
45628 store.deserialize = function(value) {
45629 if (typeof value != 'string') { return undefined }
45630 try { return JSON.parse(value) }
45631 catch(e) { return value || undefined }
45634 // Functions to encapsulate questionable FireFox 3.6.13 behavior
45635 // when about.config::dom.storage.enabled === false
45636 // See https://github.com/marcuswestin/store.js/issues#issue/13
45637 function isLocalStorageNameSupported() {
45638 try { return (localStorageName in win && win[localStorageName]) }
45639 catch(err) { return false }
45642 if (isLocalStorageNameSupported()) {
45643 storage = win[localStorageName];
45644 store.set = function(key, val) {
45645 if (val === undefined) { return store.remove(key) }
45646 storage.setItem(key, store.serialize(val));
45649 store.get = function(key, defaultVal) {
45650 var val = store.deserialize(storage.getItem(key));
45651 return (val === undefined ? defaultVal : val)
45653 store.remove = function(key) { storage.removeItem(key); };
45654 store.clear = function() { storage.clear(); };
45655 store.getAll = function() {
45657 store.forEach(function(key, val) {
45662 store.forEach = function(callback) {
45663 for (var i=0; i<storage.length; i++) {
45664 var key = storage.key(i);
45665 callback(key, store.get(key));
45668 } else if (doc && doc.documentElement.addBehavior) {
45671 // Since #userData storage applies only to specific paths, we need to
45672 // somehow link our data to a specific path. We choose /favicon.ico
45673 // as a pretty safe option, since all browsers already make a request to
45674 // this URL anyway and being a 404 will not hurt us here. We wrap an
45675 // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
45676 // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
45677 // since the iframe access rules appear to allow direct access and
45678 // manipulation of the document element, even for a 404 page. This
45679 // document can be used instead of the current document (which would
45680 // have been limited to the current path) to perform #userData storage.
45682 storageContainer = new ActiveXObject('htmlfile');
45683 storageContainer.open();
45684 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
45685 storageContainer.close();
45686 storageOwner = storageContainer.w.frames[0].document;
45687 storage = storageOwner.createElement('div');
45689 // somehow ActiveXObject instantiation failed (perhaps some special
45690 // security settings or otherwse), fall back to per-path storage
45691 storage = doc.createElement('div');
45692 storageOwner = doc.body;
45694 var withIEStorage = function(storeFunction) {
45695 return function() {
45696 var args = Array.prototype.slice.call(arguments, 0);
45697 args.unshift(storage);
45698 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
45699 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
45700 storageOwner.appendChild(storage);
45701 storage.addBehavior('#default#userData');
45702 storage.load(localStorageName);
45703 var result = storeFunction.apply(store, args);
45704 storageOwner.removeChild(storage);
45709 // In IE7, keys cannot start with a digit or contain certain chars.
45710 // See https://github.com/marcuswestin/store.js/issues/40
45711 // See https://github.com/marcuswestin/store.js/issues/83
45712 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
45713 var ieKeyFix = function(key) {
45714 return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')
45716 store.set = withIEStorage(function(storage, key, val) {
45717 key = ieKeyFix(key);
45718 if (val === undefined) { return store.remove(key) }
45719 storage.setAttribute(key, store.serialize(val));
45720 storage.save(localStorageName);
45723 store.get = withIEStorage(function(storage, key, defaultVal) {
45724 key = ieKeyFix(key);
45725 var val = store.deserialize(storage.getAttribute(key));
45726 return (val === undefined ? defaultVal : val)
45728 store.remove = withIEStorage(function(storage, key) {
45729 key = ieKeyFix(key);
45730 storage.removeAttribute(key);
45731 storage.save(localStorageName);
45733 store.clear = withIEStorage(function(storage) {
45734 var attributes = storage.XMLDocument.documentElement.attributes;
45735 storage.load(localStorageName);
45736 for (var i=attributes.length-1; i>=0; i--) {
45737 storage.removeAttribute(attributes[i].name);
45739 storage.save(localStorageName);
45741 store.getAll = function(storage) {
45743 store.forEach(function(key, val) {
45748 store.forEach = withIEStorage(function(storage, callback) {
45749 var attributes = storage.XMLDocument.documentElement.attributes;
45750 for (var i=0, attr; attr=attributes[i]; ++i) {
45751 callback(attr.name, store.deserialize(storage.getAttribute(attr.name)));
45757 var testKey = '__storejs__';
45758 store.set(testKey, testKey);
45759 if (store.get(testKey) != testKey) { store.disabled = true; }
45760 store.remove(testKey);
45762 store.disabled = true;
45764 store.enabled = !store.disabled;
45770 var ohauth = index$12;
45771 var xtend = immutable;
45772 var store = store$1;
45776 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
45777 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
45778 // does not support custom headers, which this uses everywhere.
45779 var index$11 = function(o) {
45783 // authenticated users will also have a request token secret, but it's
45784 // not used in transactions with the server
45785 oauth.authenticated = function() {
45786 return !!(token('oauth_token') && token('oauth_token_secret'));
45789 oauth.logout = function() {
45790 token('oauth_token', '');
45791 token('oauth_token_secret', '');
45792 token('oauth_request_token_secret', '');
45796 // TODO: detect lack of click event
45797 oauth.authenticate = function(callback) {
45798 if (oauth.authenticated()) return callback();
45802 // ## Getting a request token
45803 var params = timenonce(getAuth(o)),
45804 url = o.url + '/oauth/request_token';
45806 params.oauth_signature = ohauth.signature(
45807 o.oauth_secret, '',
45808 ohauth.baseString('POST', url, params));
45810 if (!o.singlepage) {
45811 // Create a 600x550 popup window in the center of the screen
45812 var w = 600, h = 550,
45814 ['width', w], ['height', h],
45815 ['left', screen.width / 2 - w / 2],
45816 ['top', screen.height / 2 - h / 2]].map(function(x) {
45817 return x.join('=');
45819 popup = window.open('about:blank', 'oauth_window', settings);
45822 // Request a request token. When this is complete, the popup
45823 // window is redirected to OSM's authorization page.
45824 ohauth.xhr('POST', url, params, null, {}, reqTokenDone);
45827 function reqTokenDone(err, xhr) {
45829 if (err) return callback(err);
45830 var resp = ohauth.stringQs(xhr.response);
45831 token('oauth_request_token_secret', resp.oauth_token_secret);
45832 var authorize_url = o.url + '/oauth/authorize?' + ohauth.qsString({
45833 oauth_token: resp.oauth_token,
45834 oauth_callback: location.href.replace('index.html', '')
45835 .replace(/#.*/, '').replace(location.search, '') + o.landing
45838 if (o.singlepage) {
45839 location.href = authorize_url;
45841 popup.location = authorize_url;
45845 // Called by a function in a landing page, in the popup window. The
45846 // window closes itself.
45847 window.authComplete = function(token) {
45848 var oauth_token = ohauth.stringQs(token.split('?')[1]);
45849 get_access_token(oauth_token.oauth_token);
45850 delete window.authComplete;
45853 // ## Getting an request token
45855 // At this point we have an `oauth_token`, brought in from a function
45856 // call on a landing page popup.
45857 function get_access_token(oauth_token) {
45858 var url = o.url + '/oauth/access_token',
45859 params = timenonce(getAuth(o)),
45860 request_token_secret = token('oauth_request_token_secret');
45861 params.oauth_token = oauth_token;
45862 params.oauth_signature = ohauth.signature(
45864 request_token_secret,
45865 ohauth.baseString('POST', url, params));
45867 // ## Getting an access token
45869 // The final token required for authentication. At this point
45870 // we have a `request token secret`
45871 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
45875 function accessTokenDone(err, xhr) {
45877 if (err) return callback(err);
45878 var access_token = ohauth.stringQs(xhr.response);
45879 token('oauth_token', access_token.oauth_token);
45880 token('oauth_token_secret', access_token.oauth_token_secret);
45881 callback(null, oauth);
45885 oauth.bootstrapToken = function(oauth_token, callback) {
45886 // ## Getting an request token
45887 // At this point we have an `oauth_token`, brought in from a function
45888 // call on a landing page popup.
45889 function get_access_token(oauth_token) {
45890 var url = o.url + '/oauth/access_token',
45891 params = timenonce(getAuth(o)),
45892 request_token_secret = token('oauth_request_token_secret');
45893 params.oauth_token = oauth_token;
45894 params.oauth_signature = ohauth.signature(
45896 request_token_secret,
45897 ohauth.baseString('POST', url, params));
45899 // ## Getting an access token
45900 // The final token required for authentication. At this point
45901 // we have a `request token secret`
45902 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
45906 function accessTokenDone(err, xhr) {
45908 if (err) return callback(err);
45909 var access_token = ohauth.stringQs(xhr.response);
45910 token('oauth_token', access_token.oauth_token);
45911 token('oauth_token_secret', access_token.oauth_token_secret);
45912 callback(null, oauth);
45915 get_access_token(oauth_token);
45920 // A single XMLHttpRequest wrapper that does authenticated calls if the
45921 // user has logged in.
45922 oauth.xhr = function(options, callback) {
45923 if (!oauth.authenticated()) {
45925 return oauth.authenticate(run);
45927 callback('not authenticated', null);
45935 var params = timenonce(getAuth(o)),
45936 oauth_token_secret = token('oauth_token_secret'),
45937 url = (options.prefix !== false) ? o.url + options.path : options.path,
45938 url_parts = url.replace(/#.*$/, '').split('?', 2),
45939 base_url = url_parts[0],
45940 query = (url_parts.length === 2) ? url_parts[1] : '';
45942 // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
45943 if ((!options.options || !options.options.header ||
45944 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
45946 params = xtend(params, ohauth.stringQs(options.content));
45949 params.oauth_token = token('oauth_token');
45950 params.oauth_signature = ohauth.signature(
45952 oauth_token_secret,
45953 ohauth.baseString(options.method, base_url, xtend(params, ohauth.stringQs(query)))
45956 return ohauth.xhr(options.method, url, params, options.content, options.options, done);
45959 function done(err, xhr) {
45960 if (err) return callback(err);
45961 else if (xhr.responseXML) return callback(err, xhr.responseXML);
45962 else return callback(err, xhr.response);
45966 // pre-authorize this object, if we can just get a token and token_secret
45968 oauth.preauth = function(c) {
45970 if (c.oauth_token) token('oauth_token', c.oauth_token);
45971 if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
45975 oauth.options = function(_) {
45976 if (!arguments.length) return o;
45979 o.url = o.url || 'http://www.openstreetmap.org';
45980 o.landing = o.landing || 'land.html';
45981 o.singlepage = o.singlepage || false;
45983 // Optional loading and loading-done functions for nice UI feedback.
45984 // by default, no-ops
45985 o.loading = o.loading || function() {};
45986 o.done = o.done || function() {};
45988 return oauth.preauth(o);
45991 // 'stamp' an authentication object from `getAuth()`
45992 // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
45994 function timenonce(o) {
45995 o.oauth_timestamp = ohauth.timestamp();
45996 o.oauth_nonce = ohauth.nonce();
46000 // get/set tokens. These are prefixed with the base URL so that `osm-auth`
46001 // can be used with multiple APIs and the keys in `localStorage`
46005 if (store.enabled) {
46006 token = function (x, y) {
46007 if (arguments.length === 1) return store.get(o.url + x);
46008 else if (arguments.length === 2) return store.set(o.url + x, y);
46012 token = function (x, y) {
46013 if (arguments.length === 1) return storage[o.url + x];
46014 else if (arguments.length === 2) return storage[o.url + x] = y;
46018 // Get an authentication object. If you just add and remove properties
46019 // from a single object, you'll need to use `delete` to make sure that
46020 // it doesn't contain undesired properties for authentication
46021 function getAuth(o) {
46023 oauth_consumer_key: o.oauth_consumer_key,
46024 oauth_signature_method: 'HMAC-SHA1'
46028 // potentially pre-authorize
46034 var JXON = new (function () {
46036 sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
46037 aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
46039 function parseText (sValue) {
46040 if (rIsNull.test(sValue)) { return null; }
46041 if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
46042 if (isFinite(sValue)) { return parseFloat(sValue); }
46043 if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
46047 function EmptyTree () { }
46048 EmptyTree.prototype.toString = function () { return 'null'; };
46049 EmptyTree.prototype.valueOf = function () { return null; };
46051 function objectify (vValue) {
46052 return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
46055 function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
46057 nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
46058 bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
46061 sProp, vContent, nLength = 0, sCollectedTxt = '',
46062 vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
46065 for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
46066 oNode = oParentNode.childNodes.item(nItem);
46067 if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
46068 else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
46069 else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
46073 var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
46075 if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
46077 for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
46078 sProp = aCache[nElId].nodeName.toLowerCase();
46079 vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
46080 if (vResult.hasOwnProperty(sProp)) {
46081 if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
46082 vResult[sProp].push(vContent);
46084 vResult[sProp] = vContent;
46091 nAttrLen = oParentNode.attributes.length,
46092 sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
46094 for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
46095 oAttrib = oParentNode.attributes.item(nAttrib);
46096 oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
46100 if (bFreeze) { Object.freeze(oAttrParent); }
46101 vResult[sAttributesProp] = oAttrParent;
46102 nLength -= nAttrLen - 1;
46106 if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
46107 vResult[sValueProp] = vBuiltVal;
46108 } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
46109 vResult = vBuiltVal;
46112 if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
46114 aCache.length = nLevelStart;
46119 function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
46120 var vValue, oChild;
46122 if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
46123 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
46124 } else if (oParentObj.constructor === Date) {
46125 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
46128 for (var sName in oParentObj) {
46129 vValue = oParentObj[sName];
46130 if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
46131 if (sName === sValueProp) {
46132 if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
46133 } else if (sName === sAttributesProp) { /* verbosity level is 3 */
46134 for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
46135 } else if (sName.charAt(0) === sAttrPref) {
46136 oParentEl.setAttribute(sName.slice(1), vValue);
46137 } else if (vValue.constructor === Array) {
46138 for (var nItem = 0; nItem < vValue.length; nItem++) {
46139 oChild = oXMLDoc.createElement(sName);
46140 loadObjTree(oXMLDoc, oChild, vValue[nItem]);
46141 oParentEl.appendChild(oChild);
46144 oChild = oXMLDoc.createElement(sName);
46145 if (vValue instanceof Object) {
46146 loadObjTree(oXMLDoc, oChild, vValue);
46147 } else if (vValue !== null && vValue !== true) {
46148 oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
46150 oParentEl.appendChild(oChild);
46155 this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
46156 var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
46157 return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);
46160 this.unbuild = function (oObjTree) {
46161 var oNewDoc = document.implementation.createDocument('', '', null);
46162 loadObjTree(oNewDoc, oNewDoc, oObjTree);
46166 this.stringify = function (oObjTree) {
46167 return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
46171 // var myObject = JXON.build(doc);
46172 // we got our javascript object! try: alert(JSON.stringify(myObject));
46174 // var newDoc = JXON.unbuild(myObject);
46175 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
46177 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
46178 var useHttps = window.location.protocol === 'https:';
46179 var protocol = useHttps ? 'https:' : 'http:';
46180 var urlroot = protocol + '//www.openstreetmap.org';
46181 var blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
46183 var loadedTiles = {};
46184 var tileZoom$1 = 16;
46185 var oauth = index$11({
46187 oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
46188 oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
46189 loading: authLoading,
46192 var rateLimitError;
46197 function authLoading() {
46198 dispatch$3.call('authLoading');
46202 function authDone() {
46203 dispatch$3.call('authDone');
46207 function abortRequest$1(i) {
46214 function getLoc(attrs) {
46215 var lon = attrs.lon && attrs.lon.value,
46216 lat = attrs.lat && attrs.lat.value;
46217 return [parseFloat(lon), parseFloat(lat)];
46221 function getNodes(obj) {
46222 var elems = obj.getElementsByTagName('nd'),
46223 nodes = new Array(elems.length);
46224 for (var i = 0, l = elems.length; i < l; i++) {
46225 nodes[i] = 'n' + elems[i].attributes.ref.value;
46231 function getTags(obj) {
46232 var elems = obj.getElementsByTagName('tag'),
46234 for (var i = 0, l = elems.length; i < l; i++) {
46235 var attrs = elems[i].attributes;
46236 tags[attrs.k.value] = attrs.v.value;
46242 function getMembers(obj) {
46243 var elems = obj.getElementsByTagName('member'),
46244 members = new Array(elems.length);
46245 for (var i = 0, l = elems.length; i < l; i++) {
46246 var attrs = elems[i].attributes;
46248 id: attrs.type.value[0] + attrs.ref.value,
46249 type: attrs.type.value,
46250 role: attrs.role.value
46257 function getVisible(attrs) {
46258 return (!attrs.visible || attrs.visible.value !== 'false');
46263 node: function nodeData(obj) {
46264 var attrs = obj.attributes;
46265 return new osmNode({
46266 id: osmEntity$$1.id.fromOSM('node', attrs.id.value),
46267 loc: getLoc(attrs),
46268 version: attrs.version.value,
46269 user: attrs.user && attrs.user.value,
46270 tags: getTags(obj),
46271 visible: getVisible(attrs)
46275 way: function wayData(obj) {
46276 var attrs = obj.attributes;
46277 return new osmWay({
46278 id: osmEntity$$1.id.fromOSM('way', attrs.id.value),
46279 version: attrs.version.value,
46280 user: attrs.user && attrs.user.value,
46281 tags: getTags(obj),
46282 nodes: getNodes(obj),
46283 visible: getVisible(attrs)
46287 relation: function relationData(obj) {
46288 var attrs = obj.attributes;
46289 return new osmRelation({
46290 id: osmEntity$$1.id.fromOSM('relation', attrs.id.value),
46291 version: attrs.version.value,
46292 user: attrs.user && attrs.user.value,
46293 tags: getTags(obj),
46294 members: getMembers(obj),
46295 visible: getVisible(attrs)
46301 function parse(xml$$1) {
46302 if (!xml$$1 || !xml$$1.childNodes) return;
46304 var root = xml$$1.childNodes[0],
46305 children = root.childNodes,
46308 for (var i = 0, l = children.length; i < l; i++) {
46309 var child = children[i],
46310 parser = parsers[child.nodeName];
46312 entities.push(parser(child));
46323 utilRebind(this, dispatch$3, 'on');
46327 reset: function() {
46328 userDetails = undefined;
46329 rateLimitError = undefined;
46330 lodash.forEach(inflight, abortRequest$1);
46337 changesetURL: function(changesetId) {
46338 return urlroot + '/changeset/' + changesetId;
46342 changesetsURL: function(center, zoom$$1) {
46343 var precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2));
46344 return urlroot + '/history#map=' +
46345 Math.floor(zoom$$1) + '/' +
46346 center[1].toFixed(precision) + '/' +
46347 center[0].toFixed(precision);
46351 entityURL: function(entity) {
46352 return urlroot + '/' + entity.type + '/' + entity.osmId();
46356 userURL: function(username) {
46357 return urlroot + '/user/' + username;
46361 loadFromAPI: function(path$$1, callback) {
46364 function done(err, xml$$1) {
46365 var isAuthenticated = that.authenticated();
46367 // 400 Bad Request, 401 Unauthorized, 403 Forbidden
46368 // Logout and retry the request..
46369 if (isAuthenticated && err &&
46370 (err.status === 400 || err.status === 401 || err.status === 403)) {
46372 that.loadFromAPI(path$$1, callback);
46374 // else, no retry..
46376 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
46377 // Set the rateLimitError flag and trigger a warning..
46378 if (!isAuthenticated && !rateLimitError && err &&
46379 (err.status === 509 || err.status === 429)) {
46380 rateLimitError = err;
46381 dispatch$3.call('change');
46385 callback(err, parse(xml$$1));
46390 if (this.authenticated()) {
46391 return oauth.xhr({ method: 'GET', path: path$$1 }, done);
46393 var url = urlroot + path$$1;
46394 return xml(url).get(done);
46399 loadEntity: function(id, callback) {
46400 var type = osmEntity$$1.id.type(id),
46401 osmID = osmEntity$$1.id.toOSM(id);
46404 '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
46405 function(err, entities) {
46406 if (callback) callback(err, { data: entities });
46412 loadEntityVersion: function(id, version$$1, callback) {
46413 var type = osmEntity$$1.id.type(id),
46414 osmID = osmEntity$$1.id.toOSM(id);
46417 '/api/0.6/' + type + '/' + osmID + '/' + version$$1,
46418 function(err, entities) {
46419 if (callback) callback(err, { data: entities });
46425 loadMultiple: function(ids, callback) {
46427 lodash.each(lodash.groupBy(lodash.uniq(ids), osmEntity$$1.id.type), function(v, k) {
46428 var type = k + 's',
46429 osmIDs = lodash.map(v, osmEntity$$1.id.toOSM);
46431 lodash.each(lodash.chunk(osmIDs, 150), function(arr) {
46433 '/api/0.6/' + type + '?' + type + '=' + arr.join(),
46434 function(err, entities) {
46435 if (callback) callback(err, { data: entities });
46443 authenticated: function() {
46444 return oauth.authenticated();
46448 // Generate Changeset XML. Returns a string.
46449 changesetJXON: function(tags) {
46453 tag: lodash.map(tags, function(value, key) {
46454 return { '@k': key, '@v': value };
46464 // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
46465 // XML. Returns a string.
46466 osmChangeJXON: function(changeset_id, changes) {
46467 function nest$$1(x, order) {
46469 for (var i = 0; i < x.length; i++) {
46470 var tagName = Object.keys(x[i])[0];
46471 if (!groups[tagName]) groups[tagName] = [];
46472 groups[tagName].push(x[i][tagName]);
46475 order.forEach(function(o) {
46476 if (groups[o]) ordered[o] = groups[o];
46481 function rep(entity) {
46482 return entity.asJXON(changeset_id);
46488 '@generator': 'iD',
46489 'create': nest$$1(changes.created.map(rep), ['node', 'way', 'relation']),
46490 'modify': nest$$1(changes.modified.map(rep), ['node', 'way', 'relation']),
46491 'delete': lodash.extend(nest$$1(changes.deleted.map(rep), ['relation', 'way', 'node']), {'@if-unused': true})
46497 changesetTags: function(version$$1, comment, imageryUsed) {
46498 var detected = utilDetect(),
46500 created_by: ('iD ' + version$$1).substr(0, 255),
46501 imagery_used: imageryUsed.join(';').substr(0, 255),
46502 host: detected.host.substr(0, 255),
46503 locale: detected.locale.substr(0, 255)
46507 tags.comment = comment.substr(0, 255);
46514 putChangeset: function(changes, version$$1, comment, imageryUsed, callback) {
46518 path: '/api/0.6/changeset/create',
46519 options: { header: { 'Content-Type': 'text/xml' } },
46520 content: JXON.stringify(that.changesetJXON(that.changesetTags(version$$1, comment, imageryUsed)))
46521 }, function(err, changeset_id) {
46522 if (err) return callback(err);
46525 path: '/api/0.6/changeset/' + changeset_id + '/upload',
46526 options: { header: { 'Content-Type': 'text/xml' } },
46527 content: JXON.stringify(that.osmChangeJXON(changeset_id, changes))
46529 if (err) return callback(err);
46530 // POST was successful, safe to call the callback.
46531 // Still attempt to close changeset, but ignore response because #2667
46532 // Add delay to allow for postgres replication #1646 #2678
46533 window.setTimeout(function() { callback(null, changeset_id); }, 2500);
46536 path: '/api/0.6/changeset/' + changeset_id + '/close',
46537 options: { header: { 'Content-Type': 'text/xml' } }
46538 }, function() { return true; });
46544 userDetails: function(callback) {
46546 callback(undefined, userDetails);
46550 function done(err, user_details) {
46551 if (err) return callback(err);
46553 var u = user_details.getElementsByTagName('user')[0],
46554 img = u.getElementsByTagName('img'),
46557 if (img && img[0] && img[0].getAttribute('href')) {
46558 image_url = img[0].getAttribute('href');
46562 display_name: u.attributes.display_name.value,
46563 image_url: image_url,
46564 id: u.attributes.id.value
46567 callback(undefined, userDetails);
46570 oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
46574 userChangesets: function(callback) {
46575 this.userDetails(function(err, user) {
46581 function done(err, changesets) {
46585 callback(undefined, Array.prototype.map.call(changesets.getElementsByTagName('changeset'),
46586 function (changeset) {
46587 return { tags: getTags(changeset) };
46593 oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
46598 status: function(callback) {
46599 function done(xml$$1) {
46600 // update blacklists
46601 var elements = xml$$1.getElementsByTagName('blacklist'),
46603 for (var i = 0; i < elements.length; i++) {
46604 var regex = elements[i].getAttribute('regex'); // needs unencode?
46606 regexes.push(regex);
46609 if (regexes.length) {
46610 blacklists = regexes;
46614 if (rateLimitError) {
46615 callback(rateLimitError, 'rateLimited');
46617 var apiStatus = xml$$1.getElementsByTagName('status'),
46618 val = apiStatus[0].getAttribute('api');
46620 callback(undefined, val);
46624 xml(urlroot + '/api/capabilities').get()
46626 .on('error', callback);
46630 imageryBlacklists: function() {
46635 tileZoom: function(_) {
46636 if (!arguments.length) return tileZoom$1;
46642 loadTiles: function(projection, dimensions, callback) {
46646 s = projection.scale() * 2 * Math.PI,
46647 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
46648 ts = 256 * Math.pow(2, z - tileZoom$1),
46650 s / 2 - projection.translate()[0],
46651 s / 2 - projection.translate()[1]
46654 var tiles = d3geoTile()
46655 .scaleExtent([tileZoom$1, tileZoom$1])
46658 .translate(projection.translate())()
46659 .map(function(tile) {
46660 var x = tile[0] * ts - origin[0],
46661 y = tile[1] * ts - origin[1];
46664 id: tile.toString(),
46665 extent: geoExtent$$1(
46666 projection.invert([x, y + ts]),
46667 projection.invert([x + ts, y]))
46671 lodash.filter(inflight, function(v, i) {
46672 var wanted = lodash.find(tiles, function(tile) {
46673 return i === tile.id;
46675 if (!wanted) delete inflight[i];
46677 }).map(abortRequest$1);
46679 tiles.forEach(function(tile) {
46682 if (loadedTiles[id] || inflight[id]) return;
46684 if (lodash.isEmpty(inflight)) {
46685 dispatch$3.call('loading');
46688 inflight[id] = that.loadFromAPI(
46689 '/api/0.6/map?bbox=' + tile.extent.toParam(),
46690 function(err, parsed) {
46691 delete inflight[id];
46693 loadedTiles[id] = true;
46697 callback(err, lodash.extend({ data: parsed }, tile));
46700 if (lodash.isEmpty(inflight)) {
46701 dispatch$3.call('loaded');
46709 switch: function(options) {
46710 urlroot = options.urlroot;
46712 oauth.options(lodash.extend({
46714 loading: authLoading,
46717 dispatch$3.call('change');
46723 toggle: function(_) {
46729 loadedTiles: function(_) {
46730 if (!arguments.length) return loadedTiles;
46736 logout: function() {
46737 userDetails = undefined;
46739 dispatch$3.call('change');
46744 authenticate: function(callback) {
46745 userDetails = undefined;
46746 function done(err, res) {
46747 rateLimitError = undefined;
46748 dispatch$3.call('change');
46749 if (callback) callback(err, res);
46751 return oauth.authenticate(done);
46755 var endpoint$1 = 'https://taginfo.openstreetmap.org/api/4/';
46756 var taginfoCache = {};
46758 point: 'count_nodes',
46759 vertex: 'count_nodes',
46760 area: 'count_ways',
46763 var tag_sort_members = {
46764 point: 'count_node_members',
46765 vertex: 'count_node_members',
46766 area: 'count_way_members',
46767 line: 'count_way_members',
46768 relation: 'count_relation_members'
46770 var tag_filters = {
46776 var tag_members_fractions = {
46777 point: 'count_node_members_fraction',
46778 vertex: 'count_node_members_fraction',
46779 area: 'count_way_members_fraction',
46780 line: 'count_way_members_fraction',
46781 relation: 'count_relation_members_fraction'
46785 function sets(parameters, n, o) {
46786 if (parameters.geometry && o[parameters.geometry]) {
46787 parameters[n] = o[parameters.geometry];
46793 function setFilter(parameters) {
46794 return sets(parameters, 'filter', tag_filters);
46798 function setSort(parameters) {
46799 return sets(parameters, 'sortname', tag_sorts);
46803 function setSortMembers(parameters) {
46804 return sets(parameters, 'sortname', tag_sort_members);
46808 function clean(parameters) {
46809 return lodash.omit(parameters, 'geometry', 'debounce');
46813 function filterKeys(type) {
46814 var count_type = type ? 'count_' + type : 'count_all';
46815 return function(d) {
46816 return parseFloat(d[count_type]) > 2500 || d.in_wiki;
46821 function filterMultikeys(prefix) {
46822 return function(d) {
46823 // d.key begins with prefix, and d.key contains no additional ':'s
46824 var re = new RegExp('^' + prefix + '(.*)$');
46825 var matches = d.key.match(re) || [];
46826 return (matches.length === 2 && matches[1].indexOf(':') === -1);
46831 function filterValues(allowUpperCase) {
46832 return function(d) {
46833 if (d.value.match(/[;,]/) !== null) return false; // exclude some punctuation
46834 if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false; // exclude uppercase letters
46835 return parseFloat(d.fraction) > 0.0 || d.in_wiki;
46840 function filterRoles(geometry) {
46841 return function(d) {
46842 if (d.role === '') return false; // exclude empty role
46843 if (d.role.match(/[A-Z*;,]/) !== null) return false; // exclude uppercase letters and some punctuation
46844 return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
46849 function valKey(d) {
46857 function valKeyDescription(d) {
46860 title: d.description || d.value
46865 function roleKey(d) {
46873 // sort keys with ':' lower than keys without ':'
46874 function sortKeys(a, b) {
46875 return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
46876 : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
46881 var debounced = lodash.debounce(json, 100, true);
46884 function request$1(url, debounce, callback) {
46885 if (taginfoCache[url]) {
46886 callback(null, taginfoCache[url]);
46887 } else if (debounce) {
46888 debounced(url, done);
46893 function done(err, data) {
46895 taginfoCache[url] = data;
46897 callback(err, data);
46902 var serviceTaginfo = {
46904 init: function() { taginfoCache = {}; },
46905 reset: function() { taginfoCache = {}; },
46908 keys: function(parameters, callback) {
46909 var debounce = parameters.debounce;
46910 parameters = clean(setSort(parameters));
46911 request$1(endpoint$1 + 'keys/all?' +
46912 utilQsString(lodash.extend({
46914 sortname: 'count_all',
46917 }, parameters)), debounce, function(err, d) {
46921 var f = filterKeys(parameters.filter);
46922 callback(null, d.data.filter(f).sort(sortKeys).map(valKey));
46929 multikeys: function(parameters, callback) {
46930 var debounce = parameters.debounce;
46931 parameters = clean(setSort(parameters));
46932 var prefix = parameters.query;
46933 request$1(endpoint$1 + 'keys/all?' +
46934 utilQsString(lodash.extend({
46936 sortname: 'count_all',
46939 }, parameters)), debounce, function(err, d) {
46943 var f = filterMultikeys(prefix);
46944 callback(null, d.data.filter(f).map(valKey));
46951 values: function(parameters, callback) {
46952 var debounce = parameters.debounce;
46953 parameters = clean(setSort(setFilter(parameters)));
46954 request$1(endpoint$1 + 'key/values?' +
46955 utilQsString(lodash.extend({
46957 sortname: 'count_all',
46960 }, parameters)), debounce, function(err, d) {
46964 // In most cases we prefer taginfo value results with lowercase letters.
46965 // A few OSM keys expect values to contain uppercase values (see #3377).
46966 // This is not an exhaustive list (e.g. `name` also has uppercase values)
46967 // but these are the fields where taginfo value lookup is most useful.
46968 var re = /network|taxon|genus|species/;
46969 var allowUpperCase = (parameters.key.match(re) !== null);
46970 var f = filterValues(allowUpperCase);
46971 callback(null, d.data.filter(f).map(valKeyDescription));
46978 roles: function(parameters, callback) {
46979 var debounce = parameters.debounce;
46980 var geometry = parameters.geometry;
46981 parameters = clean(setSortMembers(parameters));
46982 request$1(endpoint$1 + 'relation/roles?' +
46983 utilQsString(lodash.extend({
46985 sortname: 'count_all_members',
46988 }, parameters)), debounce, function(err, d) {
46992 var f = filterRoles(geometry);
46993 callback(null, d.data.filter(f).map(roleKey));
47000 docs: function(parameters, callback) {
47001 var debounce = parameters.debounce;
47002 parameters = clean(setSort(parameters));
47004 var path$$1 = 'key/wiki_pages?';
47005 if (parameters.value) path$$1 = 'tag/wiki_pages?';
47006 else if (parameters.rtype) path$$1 = 'relation/wiki_pages?';
47008 request$1(endpoint$1 + path$$1 + utilQsString(parameters), debounce, function(err, d) {
47012 callback(null, d.data);
47018 endpoint: function(_) {
47019 if (!arguments.length) return endpoint$1;
47026 var jsonpCache = {};
47027 window.jsonpCache = jsonpCache;
47029 function jsonpRequest(url, callback) {
47031 if (window.JSONP_FIX) {
47032 if (window.JSONP_DELAY === 0) {
47033 callback(window.JSONP_FIX);
47035 setTimeout(function() {
47036 callback(window.JSONP_FIX);
47037 }, window.JSONP_DELAY || 0);
47043 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
47045 while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
47049 function create(url) {
47050 var e = url.match(/callback=(\w+)/),
47051 c = e ? e[1] : rand();
47052 jsonpCache[c] = function(data) {
47054 delete jsonpCache[c];
47057 return 'jsonpCache.' + c;
47060 var cb = create(url),
47061 script = select('head')
47063 .attr('type', 'text/javascript')
47064 .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
47067 var endpoint$2 = 'https://www.wikidata.org/w/api.php?';
47069 var serviceWikidata = {
47071 init: function() {},
47072 reset: function() {},
47075 // Given a Wikipedia language and article title, return an array of
47076 // corresponding Wikidata entities.
47077 itemsByTitle: function(lang, title, callback) {
47083 lang = lang || 'en';
47084 jsonpRequest(endpoint$2 + utilQsString({
47085 action: 'wbgetentities',
47087 sites: lang.replace(/-/g, '_') + 'wiki',
47089 languages: 'en', // shrink response by filtering to one language
47090 callback: '{callback}'
47091 }), function(data) {
47092 if (!data || data.error) {
47095 callback(title, data.entities || {});
47102 var endpoint$3 = 'https://en.wikipedia.org/w/api.php?';
47104 var serviceWikipedia = {
47106 init: function() {},
47107 reset: function() {},
47110 search: function(lang, query, callback) {
47116 lang = lang || 'en';
47117 jsonpRequest(endpoint$3.replace('en', lang) +
47122 srinfo: 'suggestion',
47124 callback: '{callback}',
47126 }), function(data) {
47127 if (!data || !data.query || !data.query.search || data.error) {
47130 var results = data.query.search.map(function(d) { return d.title; });
47131 callback(query, results);
47138 suggestions: function(lang, query, callback) {
47144 lang = lang || 'en';
47145 jsonpRequest(endpoint$3.replace('en', lang) +
47147 action: 'opensearch',
47151 callback: '{callback}',
47153 }), function(data) {
47154 if (!data || data.error) {
47157 callback(data[0], data[1] || []);
47164 translations: function(lang, title, callback) {
47170 jsonpRequest(endpoint$3.replace('en', lang) +
47175 callback: '{callback}',
47178 }), function(data) {
47179 if (!data || !data.query || !data.query.pages || data.error) {
47182 var list = data.query.pages[Object.keys(data.query.pages)[0]],
47184 if (list && list.langlinks) {
47185 list.langlinks.forEach(function(d) {
47186 translations[d.lang] = d['*'];
47189 callback(translations);
47198 mapillary: serviceMapillary,
47199 nominatim: serviceNominatim,
47201 taginfo: serviceTaginfo,
47202 wikidata: serviceWikidata,
47203 wikipedia: serviceWikipedia
47206 function svgMapillaryImages(projection, context, dispatch$$1) {
47207 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47209 minViewfieldZoom = 17,
47210 layer = select(null),
47215 if (svgMapillaryImages.initialized) return; // run once
47216 svgMapillaryImages.enabled = false;
47217 svgMapillaryImages.initialized = true;
47221 function getMapillary() {
47222 if (services.mapillary && !_mapillary) {
47223 _mapillary = services.mapillary;
47224 _mapillary.event.on('loadedImages', throttledRedraw);
47225 } else if (!services.mapillary && _mapillary) {
47233 function showLayer() {
47234 var mapillary = getMapillary();
47235 if (!mapillary) return;
47237 mapillary.loadViewer(context);
47241 .style('opacity', 0)
47244 .style('opacity', 1)
47245 .on('end', function () { dispatch$$1.call('change'); });
47249 function hideLayer() {
47250 var mapillary = getMapillary();
47252 mapillary.hideViewer();
47255 throttledRedraw.cancel();
47260 .style('opacity', 0)
47261 .on('end', editOff);
47265 function editOn() {
47266 layer.style('display', 'block');
47270 function editOff() {
47271 layer.selectAll('.viewfield-group').remove();
47272 layer.style('display', 'none');
47276 function click(d) {
47277 var mapillary = getMapillary();
47278 if (!mapillary) return;
47280 context.map().centerEase(d.loc);
47283 .selectedImage(d.key, true)
47284 .updateViewer(d.key, context)
47289 function transform(d) {
47290 var t = svgPointTransform(projection)(d);
47291 if (d.ca) t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
47296 function update() {
47297 var mapillary = getMapillary(),
47298 data = (mapillary ? mapillary.images(projection) : []),
47299 imageKey = mapillary ? mapillary.selectedImage() : null;
47301 var markers = layer.selectAll('.viewfield-group')
47302 .data(data, function(d) { return d.key; });
47307 var enter = markers.enter()
47309 .attr('class', 'viewfield-group')
47310 .classed('selected', function(d) { return d.key === imageKey; })
47311 .on('click', click);
47315 .attr('transform', transform);
47318 var viewfields = markers.selectAll('.viewfield')
47319 .data(~~context.map().zoom() >= minViewfieldZoom ? [0] : []);
47326 .attr('class', 'viewfield')
47327 .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
47328 .attr('d', 'M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z');
47330 markers.selectAll('circle')
47340 function drawImages(selection$$1) {
47341 var enabled = svgMapillaryImages.enabled,
47342 mapillary = getMapillary();
47344 layer = selection$$1.selectAll('.layer-mapillary-images')
47345 .data(mapillary ? [0] : []);
47350 layer = layer.enter()
47352 .attr('class', 'layer-mapillary-images')
47353 .style('display', enabled ? 'block' : 'none')
47357 if (mapillary && ~~context.map().zoom() >= minZoom) {
47360 mapillary.loadImages(projection);
47368 drawImages.enabled = function(_) {
47369 if (!arguments.length) return svgMapillaryImages.enabled;
47370 svgMapillaryImages.enabled = _;
47371 if (svgMapillaryImages.enabled) {
47376 dispatch$$1.call('change');
47381 drawImages.supported = function() {
47382 return !!getMapillary();
47390 function svgMapillarySigns(projection, context, dispatch$$1) {
47391 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47393 layer = select(null),
47398 if (svgMapillarySigns.initialized) return; // run once
47399 svgMapillarySigns.enabled = false;
47400 svgMapillarySigns.initialized = true;
47404 function getMapillary() {
47405 if (services.mapillary && !_mapillary) {
47406 _mapillary = services.mapillary;
47407 _mapillary.event.on('loadedSigns', throttledRedraw);
47408 } else if (!services.mapillary && _mapillary) {
47415 function showLayer() {
47420 function hideLayer() {
47421 throttledRedraw.cancel();
47426 function editOn() {
47427 layer.style('display', 'block');
47431 function editOff() {
47432 layer.selectAll('.icon-sign').remove();
47433 layer.style('display', 'none');
47437 function click(d) {
47438 var mapillary = getMapillary();
47439 if (!mapillary) return;
47441 context.map().centerEase(d.loc);
47444 .selectedImage(d.key, true)
47445 .updateViewer(d.key, context)
47450 function update() {
47451 var mapillary = getMapillary(),
47452 data = (mapillary ? mapillary.signs(projection) : []),
47453 imageKey = mapillary ? mapillary.selectedImage() : null;
47455 var signs = layer.selectAll('.icon-sign')
47456 .data(data, function(d) { return d.key; });
47461 var enter = signs.enter()
47462 .append('foreignObject')
47463 .attr('class', 'icon-sign')
47464 .attr('width', '32px') // for Firefox
47465 .attr('height', '32px') // for Firefox
47466 .classed('selected', function(d) { return d.key === imageKey; })
47467 .on('click', click);
47470 .append('xhtml:body')
47471 .attr('class', 'icon-sign-body')
47472 .html(mapillary.signHTML);
47476 .attr('x', function(d) { return projection(d.loc)[0] - 16; }) // offset by -16px to
47477 .attr('y', function(d) { return projection(d.loc)[1] - 16; }); // center signs on loc
47481 function drawSigns(selection$$1) {
47482 var enabled = svgMapillarySigns.enabled,
47483 mapillary = getMapillary();
47485 layer = selection$$1.selectAll('.layer-mapillary-signs')
47486 .data(mapillary ? [0] : []);
47491 layer = layer.enter()
47493 .attr('class', 'layer-mapillary-signs')
47494 .style('display', enabled ? 'block' : 'none')
47498 if (mapillary && ~~context.map().zoom() >= minZoom) {
47501 mapillary.loadSigns(context, projection);
47509 drawSigns.enabled = function(_) {
47510 if (!arguments.length) return svgMapillarySigns.enabled;
47511 svgMapillarySigns.enabled = _;
47512 if (svgMapillarySigns.enabled) {
47517 dispatch$$1.call('change');
47522 drawSigns.supported = function() {
47523 var mapillary = getMapillary();
47524 return (mapillary && mapillary.signsSupported());
47532 function svgOsm() {
47533 return function drawOsm(selection) {
47534 var layers = selection.selectAll('.layer-osm')
47535 .data(['areas', 'lines', 'hit', 'halo', 'label']);
47539 .attr('class', function(d) { return 'layer-osm layer-' + d; });
47543 function svgLayers(projection, context) {
47544 var dispatch$$1 = dispatch('change'),
47545 svg = select(null),
47547 { id: 'osm', layer: svgOsm(projection, context, dispatch$$1) },
47548 { id: 'gpx', layer: svgGpx(projection, context, dispatch$$1) },
47549 { id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch$$1) },
47550 { id: 'mapillary-signs', layer: svgMapillarySigns(projection, context, dispatch$$1) },
47551 { id: 'debug', layer: svgDebug(projection, context, dispatch$$1) }
47555 function drawLayers(selection$$1) {
47556 svg = selection$$1.selectAll('.surface')
47561 .attr('class', 'surface')
47564 var defs = svg.selectAll('.surface-defs')
47569 .attr('class', 'surface-defs');
47571 var groups = svg.selectAll('.data-layer')
47579 .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
47581 .each(function(d) { select(this).call(d.layer); });
47585 drawLayers.all = function() {
47590 drawLayers.layer = function(id) {
47591 var obj = lodash.find(layers, function(o) {return o.id === id;});
47592 return obj && obj.layer;
47596 drawLayers.only = function(what) {
47597 var arr = [].concat(what);
47598 drawLayers.remove(lodash.difference(lodash.map(layers, 'id'), arr));
47603 drawLayers.remove = function(what) {
47604 var arr = [].concat(what);
47605 arr.forEach(function(id) {
47606 layers = lodash.reject(layers, function(o) {return o.id === id;});
47608 dispatch$$1.call('change');
47613 drawLayers.add = function(what) {
47614 var arr = [].concat(what);
47615 arr.forEach(function(obj) {
47616 if ('id' in obj && 'layer' in obj) {
47620 dispatch$$1.call('change');
47625 drawLayers.dimensions = function(_) {
47626 if (!arguments.length) return utilGetDimensions(svg);
47627 utilSetDimensions(svg, _);
47632 return utilRebind(drawLayers, dispatch$$1, 'on');
47635 function svgLines$$1(projection) {
47636 var detected = utilDetect();
47638 var highway_stack = {
47653 function waystack(a, b) {
47654 var as = 0, bs = 0;
47655 if (a.tags.highway) { as -= highway_stack[a.tags.highway]; }
47656 if (b.tags.highway) { bs -= highway_stack[b.tags.highway]; }
47661 return function drawLines(selection$$1, graph, entities, filter) {
47662 var ways = [], pathdata = {}, onewaydata = {},
47663 getPath = svgPath(projection, graph);
47665 for (var i = 0; i < entities.length; i++) {
47666 var entity = entities[i],
47667 outer = osmSimpleMultipolygonOuterMember(entity, graph);
47669 ways.push(entity.mergeTags(outer.tags));
47670 } else if (entity.geometry(graph) === 'line') {
47675 ways = ways.filter(getPath);
47677 pathdata = lodash.groupBy(ways, function(way) { return way.layer(); });
47679 lodash.forOwn(pathdata, function(v, k) {
47680 onewaydata[k] = lodash(v)
47681 .filter(function(d) { return d.isOneWay(); })
47682 .map(svgOneWaySegments(projection, graph, 35))
47687 var layer = selection$$1.selectAll('.layer-lines');
47689 var layergroup = layer
47690 .selectAll('g.layergroup')
47691 .data(range(-10, 11));
47693 layergroup = layergroup.enter()
47695 .attr('class', function(d) { return 'layergroup layer' + String(d); })
47696 .merge(layergroup);
47699 var linegroup = layergroup
47700 .selectAll('g.linegroup')
47701 .data(['shadow', 'casing', 'stroke']);
47703 linegroup = linegroup.enter()
47705 .attr('class', function(d) { return 'linegroup line-' + d; })
47709 var lines = linegroup
47713 function() { return pathdata[this.parentNode.__data__] || []; },
47720 // Optimization: call simple TagClasses only on enter selection. This
47721 // works because osmEntity.key is defined to include the entity v attribute.
47724 .attr('class', function(d) { return 'way line ' + this.parentNode.__data__ + ' ' + d.id; })
47725 .call(svgTagClasses())
47728 .attr('d', getPath)
47729 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
47732 var onewaygroup = layergroup
47733 .selectAll('g.onewaygroup')
47736 onewaygroup = onewaygroup.enter()
47738 .attr('class', 'onewaygroup')
47739 .merge(onewaygroup);
47742 var oneways = onewaygroup
47746 function() { return onewaydata[this.parentNode.__data__] || []; },
47747 function(d) { return [d.id, d.index]; }
47753 oneways = oneways.enter()
47755 .attr('class', 'oneway')
47756 .attr('marker-mid', 'url(#oneway-marker)')
47758 .attr('d', function(d) { return d.d; });
47761 oneways.each(function() { this.parentNode.insertBefore(this, this); });
47766 function svgMidpoints$$1(projection, context) {
47768 return function drawMidpoints(selection, graph, entities, filter, extent) {
47769 var poly = extent.polygon(),
47772 for (var i = 0; i < entities.length; i++) {
47773 var entity = entities[i];
47775 if (entity.type !== 'way')
47777 if (!filter(entity))
47779 if (context.selectedIDs().indexOf(entity.id) < 0)
47782 var nodes = graph.childNodes(entity);
47783 for (var j = 0; j < nodes.length - 1; j++) {
47787 id = [a.id, b.id].sort().join('-');
47789 if (midpoints[id]) {
47790 midpoints[id].parents.push(entity);
47792 if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
47793 var point = geoInterp(a.loc, b.loc, 0.5),
47796 if (extent.intersects(point)) {
47799 for (var k = 0; k < 4; k++) {
47800 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
47802 geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
47803 geoEuclideanDistance(projection(b.loc), projection(point)) > 20)
47816 edge: [a.id, b.id],
47826 function midpointFilter(d) {
47827 if (midpoints[d.id])
47830 for (var i = 0; i < d.parents.length; i++) {
47831 if (filter(d.parents[i])) {
47840 var layer = selection.selectAll('.layer-hit');
47843 .selectAll('g.midpoint')
47844 .filter(midpointFilter)
47845 .data(lodash.values(midpoints), function(d) { return d.id; });
47850 var enter = groups.enter()
47851 .insert('g', ':first-child')
47852 .attr('class', 'midpoint');
47854 enter.append('polygon')
47855 .attr('points', '-6,8 10,0 -6,-8')
47856 .attr('class', 'shadow');
47858 enter.append('polygon')
47859 .attr('points', '-3,4 5,0 -3,-4')
47860 .attr('class', 'fill');
47864 .attr('transform', function(d) {
47865 var translate = svgPointTransform(projection),
47866 a = graph.entity(d.edge[0]),
47867 b = graph.entity(d.edge[1]),
47868 angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
47869 return translate(d) + ' rotate(' + angleVal + ')';
47871 .call(svgTagClasses().tags(
47872 function(d) { return d.parents[0].tags; }
47875 // Propagate data bindings.
47876 groups.select('polygon.shadow');
47877 groups.select('polygon.fill');
47882 function svgOneWaySegments(projection, graph, dt) {
47883 return function(entity) {
47889 clip = identity$8().clipExtent(projection.clipExtent()).stream,
47890 coordinates = graph.childNodes(entity).map(function(n) {
47894 if (entity.tags.oneway === '-1') coordinates.reverse();
47897 type: 'LineString',
47898 coordinates: coordinates
47899 }, projection.stream(clip({
47900 lineStart: function() {},
47901 lineEnd: function() {
47904 point: function(x, y) {
47908 var span = geoEuclideanDistance(a, b) - offset;
47911 var angle = Math.atan2(b[1] - a[1], b[0] - a[0]),
47912 dx = dt * Math.cos(angle),
47913 dy = dt * Math.sin(angle),
47914 p = [a[0] + offset * Math.cos(angle),
47915 a[1] + offset * Math.sin(angle)];
47917 var segment = 'M' + a[0] + ',' + a[1] +
47918 'L' + p[0] + ',' + p[1];
47920 for (span -= dt; span >= 0; span -= dt) {
47923 segment += 'L' + p[0] + ',' + p[1];
47926 segment += 'L' + b[0] + ',' + b[1];
47927 segments.push({id: entity.id, index: i, d: segment});
47942 function svgPath(projection, graph, isArea) {
47944 // Explanation of magic numbers:
47945 // "padding" here allows space for strokes to extend beyond the viewport,
47946 // so that the stroke isn't drawn along the edge of the viewport when
47947 // the shape is clipped.
47949 // When drawing lines, pad viewport by 5px.
47950 // When drawing areas, pad viewport by 65px in each direction to allow
47951 // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
47954 padding = isArea ? 65 : 5,
47955 viewport = projection.clipExtent(),
47957 [viewport[0][0] - padding, viewport[0][1] - padding],
47958 [viewport[1][0] + padding, viewport[1][1] + padding]
47960 clip = identity$8().clipExtent(paddedExtent).stream,
47961 project = projection.stream,
47962 path$$1 = index$5()
47963 .projection({stream: function(output) { return project(clip(output)); }});
47965 return function(entity) {
47966 if (entity.id in cache) {
47967 return cache[entity.id];
47969 return cache[entity.id] = path$$1(entity.asGeoJSON(graph));
47974 function svgPoints$$1(projection, context) {
47976 function markerPath(selection, klass) {
47978 .attr('class', klass)
47979 .attr('transform', 'translate(-8, -23)')
47980 .attr('d', 'M 17,8 C 17,13 11,21 8.5,23.5 C 6,21 0,13 0,8 C 0,4 4,-0.5 8.5,-0.5 C 13,-0.5 17,4 17,8 z');
47983 function sortY(a, b) {
47984 return b.loc[1] - a.loc[1];
47988 return function drawPoints(selection, graph, entities, filter) {
47989 var wireframe = context.surface().classed('fill-wireframe'),
47990 points = wireframe ? [] : lodash.filter(entities, function(e) {
47991 return e.geometry(graph) === 'point';
47994 points.sort(sortY);
47996 var layer = selection.selectAll('.layer-hit');
47998 var groups = layer.selectAll('g.point')
48000 .data(points, osmEntity$$1.key);
48005 var enter = groups.enter()
48007 .attr('class', function(d) { return 'node point ' + d.id; })
48010 enter.append('path')
48011 .call(markerPath, 'shadow');
48013 enter.append('path')
48014 .call(markerPath, 'stroke');
48016 enter.append('use')
48017 .attr('transform', 'translate(-6, -20)')
48018 .attr('class', 'icon')
48019 .attr('width', '12px')
48020 .attr('height', '12px');
48024 .attr('transform', svgPointTransform(projection))
48025 .call(svgTagClasses());
48027 // Selecting the following implicitly
48028 // sets the data (point entity) on the element
48029 groups.select('.shadow');
48030 groups.select('.stroke');
48031 groups.select('.icon')
48032 .attr('xlink:href', function(entity) {
48033 var preset = context.presets().match(entity, graph);
48034 return (preset && preset.icon) ? '#' + preset.icon + '-12' : '';
48039 function svgRelationMemberTags(graph) {
48040 return function(entity) {
48041 var tags = entity.tags;
48042 graph.parentRelations(entity).forEach(function(relation) {
48043 var type = relation.tags.type;
48044 if (type === 'multipolygon' || type === 'boundary') {
48045 tags = lodash.extend({}, relation.tags, tags);
48052 function svgTagClasses() {
48054 'building', 'highway', 'railway', 'waterway', 'aeroway',
48055 'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
48059 'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
48060 'razed', 'demolished', 'obliterated'
48063 'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
48064 'surface', 'tracktype', 'crossing'
48066 tagClassRe = /^tag-/,
48067 tags = function(entity) { return entity.tags; };
48070 var tagClasses = function(selection$$1) {
48071 selection$$1.each(function tagClassesEach(entity) {
48072 var value = this.className,
48073 classes, primary, status;
48075 if (value.baseVal !== undefined) value = value.baseVal;
48077 classes = value.trim().split(/\s+/).filter(function(name) {
48078 return name.length && !tagClassRe.test(name);
48081 var t = tags(entity), i, k, v;
48083 // pick at most one primary classification tag..
48084 for (i = 0; i < primaries.length; i++) {
48087 if (!v || v === 'no') continue;
48090 if (statuses.indexOf(v) !== -1) { // e.g. `railway=abandoned`
48092 classes += ' tag-' + k;
48094 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48100 // add at most one status tag, only if relates to primary tag..
48102 for (i = 0; i < statuses.length; i++) {
48105 if (!v || v === 'no') continue;
48107 if (v === 'yes') { // e.g. `railway=rail + abandoned=yes`
48110 else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
48112 } else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway`
48115 classes += ' tag-' + v;
48116 } // else ignore e.g. `highway=path + abandoned=railway`
48123 classes += ' tag-status tag-status-' + status;
48126 // add any secondary (structure) tags
48127 for (i = 0; i < secondaries.length; i++) {
48128 k = secondaries[i];
48130 if (!v || v === 'no') continue;
48131 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48134 // For highways, look for surface tagging..
48135 if (primary === 'highway') {
48136 var paved = (t.highway !== 'track');
48139 if (k in osmPavedTags) {
48140 paved = !!osmPavedTags[k][v];
48145 classes += ' tag-unpaved';
48149 classes = classes.trim();
48151 if (classes !== value) {
48152 select(this).attr('class', classes);
48158 tagClasses.tags = function(_) {
48159 if (!arguments.length) return tags;
48167 function svgTurns(projection) {
48169 return function drawTurns(selection, graph, turns) {
48171 function key(turn) {
48172 return [turn.from.node + turn.via.node + turn.to.node].join('-');
48175 function icon(turn) {
48176 var u = turn.u ? '-u' : '';
48177 if (!turn.restriction)
48178 return '#turn-yes' + u;
48179 var restriction = graph.entity(turn.restriction).tags.restriction;
48181 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
48184 var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
48191 var enter = groups.enter()
48193 .attr('class', 'turn');
48196 .filter(function (turn) { return !turn.u; });
48198 nEnter.append('rect')
48199 .attr('transform', 'translate(-22, -12)')
48200 .attr('width', '44')
48201 .attr('height', '24');
48203 nEnter.append('use')
48204 .attr('transform', 'translate(-22, -12)')
48205 .attr('width', '44')
48206 .attr('height', '24');
48210 .filter(function (turn) { return turn.u; });
48212 uEnter.append('circle')
48215 uEnter.append('use')
48216 .attr('transform', 'translate(-16, -16)')
48217 .attr('width', '32')
48218 .attr('height', '32');
48225 .attr('transform', function (turn) {
48226 var v = graph.entity(turn.via.node),
48227 t = graph.entity(turn.to.node),
48228 a = geoAngle(v, t, projection),
48229 p = projection(v.loc),
48230 r = turn.u ? 0 : 60;
48232 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
48233 'rotate(' + a * 180 / Math.PI + ')';
48236 groups.select('use')
48237 .attr('xlink:href', icon);
48239 groups.select('rect');
48240 groups.select('circle');
48246 function svgVertices$$1(projection, context) {
48248 // z16-, z17, z18+, tagged
48249 shadow: [6, 7.5, 7.5, 11.5],
48250 stroke: [2.5, 3.5, 3.5, 7],
48251 fill: [1, 1.5, 1.5, 1.5]
48256 function siblingAndChildVertices(ids, graph, extent$$1) {
48259 function addChildVertices(entity) {
48260 if (!context.features().isHiddenFeature(entity, graph, entity.geometry(graph))) {
48262 if (entity.type === 'way') {
48263 for (i = 0; i < entity.nodes.length; i++) {
48264 addChildVertices(graph.entity(entity.nodes[i]));
48266 } else if (entity.type === 'relation') {
48267 for (i = 0; i < entity.members.length; i++) {
48268 var member = context.hasEntity(entity.members[i].id);
48270 addChildVertices(member);
48273 } else if (entity.intersects(extent$$1, graph)) {
48274 vertices[entity.id] = entity;
48279 ids.forEach(function(id) {
48280 var entity = context.hasEntity(id);
48281 if (entity && entity.type === 'node') {
48282 vertices[entity.id] = entity;
48283 context.graph().parentWays(entity).forEach(function(entity) {
48284 addChildVertices(entity);
48286 } else if (entity) {
48287 addChildVertices(entity);
48295 function draw(selection$$1, vertices, klass, graph, zoom$$1) {
48297 function icon(entity) {
48298 if (entity.id in icons) return icons[entity.id];
48300 entity.hasInterestingTags() &&
48301 context.presets().match(entity, graph).icon;
48302 return icons[entity.id];
48305 function setClass(klass) {
48306 return function(entity) {
48307 this.setAttribute('class', 'node vertex ' + klass + ' ' + entity.id);
48311 function setAttributes(selection$$1) {
48312 ['shadow','stroke','fill'].forEach(function(klass) {
48313 var rads = radiuses[klass];
48314 selection$$1.selectAll('.' + klass)
48315 .each(function(entity) {
48316 var i = z && icon(entity),
48318 r = rads[i ? 3 : z];
48319 this.setAttribute('cx', c);
48320 this.setAttribute('cy', -c);
48321 this.setAttribute('r', r);
48322 if (i && klass === 'fill') {
48323 this.setAttribute('visibility', 'hidden');
48325 this.removeAttribute('visibility');
48330 selection$$1.selectAll('use')
48333 this.removeAttribute('visibility');
48335 this.setAttribute('visibility', 'hidden');
48342 z = (zoom$$1 < 17 ? 0 : zoom$$1 < 18 ? 1 : 2);
48344 var groups = selection$$1
48345 .data(vertices, osmEntity$$1.key);
48350 var enter = groups.enter()
48352 .attr('class', function(d) { return 'node vertex ' + klass + ' ' + d.id; });
48354 enter.append('circle')
48355 .each(setClass('shadow'));
48357 enter.append('circle')
48358 .each(setClass('stroke'));
48360 // Vertices with icons get a `use`.
48361 enter.filter(function(d) { return icon(d); })
48363 .attr('transform', 'translate(-6, -6)')
48364 .attr('xlink:href', function(d) { return '#' + icon(d) + '-12'; })
48365 .attr('width', '12px')
48366 .attr('height', '12px')
48367 .each(setClass('icon'));
48369 // Vertices with tags get a fill.
48370 enter.filter(function(d) { return d.hasInterestingTags(); })
48372 .each(setClass('fill'));
48376 .attr('transform', svgPointTransform(projection))
48377 .classed('shared', function(entity) { return graph.isShared(entity); })
48378 .call(setAttributes);
48382 function drawVertices(selection$$1, graph, entities, filter, extent$$1, zoom$$1) {
48383 var selected = siblingAndChildVertices(context.selectedIDs(), graph, extent$$1),
48384 wireframe = context.surface().classed('fill-wireframe'),
48387 for (var i = 0; i < entities.length; i++) {
48388 var entity = entities[i],
48389 geometry = entity.geometry(graph);
48391 if (wireframe && geometry === 'point') {
48392 vertices.push(entity);
48396 if (geometry !== 'vertex')
48399 if (entity.id in selected ||
48400 entity.hasInterestingTags() ||
48401 entity.isIntersection(graph)) {
48402 vertices.push(entity);
48406 var layer = selection$$1.selectAll('.layer-hit');
48407 layer.selectAll('g.vertex.vertex-persistent')
48409 .call(draw, vertices, 'vertex-persistent', graph, zoom$$1);
48411 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48415 function drawHover(selection$$1, graph, extent$$1, zoom$$1) {
48416 var hovered = hover ? siblingAndChildVertices([hover.id], graph, extent$$1) : {};
48417 var layer = selection$$1.selectAll('.layer-hit');
48419 layer.selectAll('g.vertex.vertex-hover')
48420 .call(draw, values(hovered), 'vertex-hover', graph, zoom$$1);
48424 drawVertices.drawHover = function(selection$$1, graph, target, extent$$1, zoom$$1) {
48425 if (target === hover) return;
48427 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48430 return drawVertices;
48433 function behaviorEdit(context) {
48437 .minzoom(context.minEditableZoom());
48441 edit.off = function() {
48451 The hover behavior adds the `.hover` class on mouseover to all elements to which
48452 the identical datum is bound, and removes it on mouseout.
48454 The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
48455 representation may consist of several elements scattered throughout the DOM hierarchy.
48456 Only one of these elements can have the :hover pseudo-class, but all of them will
48457 have the .hover class.
48459 function behaviorHover() {
48460 var dispatch$$1 = dispatch('hover'),
48461 selection$$1 = select(null),
48467 function keydown() {
48468 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
48469 dispatch$$1.call('hover', this, null);
48470 selection$$1.selectAll('.hover')
48471 .classed('hover-suppressed', true)
48472 .classed('hover', false);
48478 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
48479 dispatch$$1.call('hover', this, target ? target.id : null);
48480 selection$$1.selectAll('.hover-suppressed')
48481 .classed('hover-suppressed', false)
48482 .classed('hover', true);
48487 var hover = function(__) {
48491 .on('mouseover.hover', mouseover)
48492 .on('mouseout.hover', mouseout)
48493 .on('mousedown.hover', mousedown);
48496 .on('keydown.hover', keydown)
48497 .on('keyup.hover', keyup);
48500 function mouseover() {
48501 if (buttonDown) return;
48502 var target = event.target;
48503 enter(target ? target.__data__ : null);
48507 function mouseout() {
48508 if (buttonDown) return;
48509 var target = event.relatedTarget;
48510 enter(target ? target.__data__ : null);
48514 function mousedown() {
48517 .on('mouseup.hover', mouseup, true);
48521 function mouseup() {
48522 buttonDown = false;
48524 .on('mouseup.hover', null, true);
48528 function enter(d) {
48529 if (d === target) return;
48532 selection$$1.selectAll('.hover')
48533 .classed('hover', false);
48534 selection$$1.selectAll('.hover-suppressed')
48535 .classed('hover-suppressed', false);
48537 if (target instanceof osmEntity$$1) {
48538 var selector$$1 = '.' + target.id;
48540 if (target.type === 'relation') {
48541 target.members.forEach(function(member) {
48542 selector$$1 += ', .' + member.id;
48546 var suppressed = altDisables && event && event.altKey;
48548 selection$$1.selectAll(selector$$1)
48549 .classed(suppressed ? 'hover-suppressed' : 'hover', true);
48551 dispatch$$1.call('hover', this, target.id);
48553 dispatch$$1.call('hover', this, null);
48560 hover.off = function(selection$$1) {
48561 selection$$1.selectAll('.hover')
48562 .classed('hover', false);
48563 selection$$1.selectAll('.hover-suppressed')
48564 .classed('hover-suppressed', false);
48567 .on('mouseover.hover', null)
48568 .on('mouseout.hover', null)
48569 .on('mousedown.hover', null);
48572 .on('keydown.hover', null)
48573 .on('keyup.hover', null);
48577 hover.altDisables = function(_) {
48578 if (!arguments.length) return altDisables;
48584 return utilRebind(hover, dispatch$$1, 'on');
48587 function behaviorTail() {
48591 tooltipSize = [0, 0],
48592 selectionSize = [0, 0];
48595 function tail(selection$$1) {
48596 if (!text$$1) return;
48599 .on('resize.tail', function() { selectionSize = utilGetDimensions(selection$$1); });
48601 container = select(document.body)
48603 .style('display', 'none')
48604 .attr('class', 'tail tooltip-inner');
48606 container.append('div')
48610 .on('mousemove.tail', mousemove)
48611 .on('mouseenter.tail', mouseenter)
48612 .on('mouseleave.tail', mouseleave);
48615 .on('mousemove.tail', mousemove);
48617 tooltipSize = utilGetDimensions(container);
48618 selectionSize = utilGetDimensions(selection$$1);
48622 container.style('display', 'block');
48623 tooltipSize = utilGetDimensions(container);
48627 function mousemove() {
48628 if (container.style('display') === 'none') show();
48629 var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
48630 -tooltipSize[0] - xmargin : xmargin;
48631 container.classed('left', xoffset > 0);
48632 utilSetTransform(container, event.clientX + xoffset, event.clientY);
48636 function mouseleave() {
48637 if (event.relatedTarget !== container.node()) {
48638 container.style('display', 'none');
48643 function mouseenter() {
48644 if (event.relatedTarget !== container.node()) {
48651 tail.off = function(selection$$1) {
48652 if (!text$$1) return;
48655 .on('mousemove.tail', null)
48659 .on('mousemove.tail', null)
48660 .on('mouseenter.tail', null)
48661 .on('mouseleave.tail', null);
48664 .on('resize.tail', null);
48668 tail.text = function(_) {
48669 if (!arguments.length) return text$$1;
48678 behaviorDraw.usedTails = {};
48679 behaviorDraw.disableSpace = false;
48680 behaviorDraw.lastSpace = null;
48683 function behaviorDraw(context) {
48684 var dispatch$$1 = dispatch('move', 'click', 'clickWay',
48685 'clickNode', 'undo', 'cancel', 'finish'),
48686 keybinding = d3keybinding('draw'),
48687 hover = behaviorHover(context)
48689 .on('hover', context.ui().sidebar.hover),
48690 tail = behaviorTail(),
48691 edit = behaviorEdit(context),
48692 closeTolerance = 4,
48694 mouseLeave = false,
48696 cached = behaviorDraw;
48700 if (event.altKey) return {};
48702 if (event.type === 'keydown') {
48703 return (lastMouse && lastMouse.target.__data__) || {};
48705 return event.target.__data__ || {};
48710 function mousedown() {
48713 var p = context.container().node();
48714 return touchId !== null ? touches(p).filter(function(p) {
48715 return p.identifier === touchId;
48719 var element = select(this),
48720 touchId = event.touches ? event.changedTouches[0].identifier : null,
48724 element.on('mousemove.draw', null);
48726 select(window).on('mouseup.draw', function() {
48727 var t2 = +new Date(),
48729 dist = geoEuclideanDistance(p1, p2);
48731 element.on('mousemove.draw', mousemove);
48732 select(window).on('mouseup.draw', null);
48734 if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
48735 // Prevent a quick second click
48736 select(window).on('click.draw-block', function() {
48737 event.stopPropagation();
48740 context.map().dblclickEnable(false);
48742 window.setTimeout(function() {
48743 context.map().dblclickEnable(true);
48744 select(window).on('click.draw-block', null);
48753 function mousemove() {
48755 dispatch$$1.call('move', this, datum());
48759 function mouseenter() {
48760 mouseLeave = false;
48764 function mouseleave() {
48771 if (d.type === 'way') {
48772 var dims = context.map().dimensions(),
48773 mouse$$1 = context.mouse(),
48775 trySnap = mouse$$1[0] > pad && mouse$$1[0] < dims[0] - pad &&
48776 mouse$$1[1] > pad && mouse$$1[1] < dims[1] - pad;
48779 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection),
48780 edge = [d.nodes[choice.index - 1], d.nodes[choice.index]];
48781 dispatch$$1.call('clickWay', this, choice.loc, edge);
48783 dispatch$$1.call('click', this, context.map().mouseCoordinates());
48786 } else if (d.type === 'node') {
48787 dispatch$$1.call('clickNode', this, d);
48790 dispatch$$1.call('click', this, context.map().mouseCoordinates());
48796 var currSpace = context.mouse();
48797 if (cached.disableSpace && cached.lastSpace) {
48798 var dist = geoEuclideanDistance(cached.lastSpace, currSpace);
48799 if (dist > tolerance) {
48800 cached.disableSpace = false;
48804 if (cached.disableSpace || mouseLeave || !lastMouse) return;
48806 // user must move mouse or release space bar to allow another click
48807 cached.lastSpace = currSpace;
48808 cached.disableSpace = true;
48810 select(window).on('keyup.space-block', function() {
48811 cached.disableSpace = false;
48812 select(window).on('keyup.space-block', null);
48815 event.preventDefault();
48820 function backspace() {
48821 event.preventDefault();
48822 dispatch$$1.call('undo');
48827 event.preventDefault();
48828 dispatch$$1.call('cancel');
48833 event.preventDefault();
48834 dispatch$$1.call('finish');
48838 function draw(selection$$1) {
48839 context.install(hover);
48840 context.install(edit);
48842 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
48843 context.install(tail);
48847 .on('⌫', backspace)
48851 .on('space', space)
48852 .on('⌥space', space);
48855 .on('mouseenter.draw', mouseenter)
48856 .on('mouseleave.draw', mouseleave)
48857 .on('mousedown.draw', mousedown)
48858 .on('mousemove.draw', mousemove);
48867 draw.off = function(selection$$1) {
48868 context.ui().sidebar.hover.cancel();
48869 context.uninstall(hover);
48870 context.uninstall(edit);
48872 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
48873 context.uninstall(tail);
48874 cached.usedTails[tail.text()] = true;
48878 .on('mouseenter.draw', null)
48879 .on('mouseleave.draw', null)
48880 .on('mousedown.draw', null)
48881 .on('mousemove.draw', null);
48884 .on('mouseup.draw', null);
48885 // note: keyup.space-block, click.draw-block should remain
48888 .call(keybinding.off);
48892 draw.tail = function(_) {
48898 return utilRebind(draw, dispatch$$1, 'on');
48901 function behaviorAddWay(context) {
48902 var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
48903 draw = behaviorDraw(context);
48905 var addWay = function(surface) {
48906 draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
48907 .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
48908 .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
48909 .on('cancel', addWay.cancel)
48910 .on('finish', addWay.cancel);
48913 .dblclickEnable(false);
48915 surface.call(draw);
48919 addWay.off = function(surface) {
48920 surface.call(draw.off);
48924 addWay.cancel = function() {
48925 window.setTimeout(function() {
48926 context.map().dblclickEnable(true);
48929 context.enter(modeBrowse$$1(context));
48933 addWay.tail = function(text$$1) {
48934 draw.tail(text$$1);
48939 return utilRebind(addWay, dispatch$$1, 'on');
48942 function behaviorBreathe() {
48943 var duration = 800,
48945 selector$$1 = '.selected.shadow, .selected .shadow',
48946 selected = select(null),
48953 // This is a workaround for a bug in rollup v0.36
48954 // https://github.com/rollup/rollup/issues/984
48955 // The symbol for this default export is not used anywhere, but it
48956 // needs to be called in order to be included in the bundle.
48957 var t = transition();
48960 function ratchetyInterpolator(a, b, steps, units) {
48963 var sample = quantize$1()
48965 .range(quantize(interpolateNumber(a, b), steps));
48967 return function(t) {
48968 return String(sample(t)) + (units || '');
48973 function reset(selection$$1) {
48975 .style('stroke-opacity', null)
48976 .style('stroke-width', null)
48977 .style('fill-opacity', null)
48982 function setAnimationParams(transition$$1, fromTo) {
48983 var toFrom = (fromTo === 'from' ? 'to' : 'from');
48986 .styleTween('stroke-opacity', function(d) {
48987 return ratchetyInterpolator(
48988 params[d.id][toFrom].opacity,
48989 params[d.id][fromTo].opacity,
48993 .styleTween('stroke-width', function(d) {
48994 return ratchetyInterpolator(
48995 params[d.id][toFrom].width,
48996 params[d.id][fromTo].width,
49001 .styleTween('fill-opacity', function(d) {
49002 return ratchetyInterpolator(
49003 params[d.id][toFrom].opacity,
49004 params[d.id][fromTo].opacity,
49008 .styleTween('r', function(d) {
49009 return ratchetyInterpolator(
49010 params[d.id][toFrom].width,
49011 params[d.id][fromTo].width,
49019 function calcAnimationParams(selection$$1) {
49022 .each(function(d) {
49023 var s = select(this),
49024 tag = s.node().tagName,
49025 p = {'from': {}, 'to': {}},
49028 // determine base opacity and width
49029 if (tag === 'circle') {
49030 opacity = parseFloat(s.style('fill-opacity') || 0.5);
49031 width = parseFloat(s.style('r') || 15.5);
49033 opacity = parseFloat(s.style('stroke-opacity') || 0.7);
49034 width = parseFloat(s.style('stroke-width') || 10);
49037 // calculate from/to interpolation params..
49039 p.from.opacity = opacity * 0.6;
49040 p.to.opacity = opacity * 1.25;
49041 p.from.width = width * 0.9;
49042 p.to.width = width * (tag === 'circle' ? 1.5 : 1.25);
49048 function run(surface, fromTo) {
49049 var toFrom = (fromTo === 'from' ? 'to' : 'from'),
49050 currSelected = surface.selectAll(selector$$1),
49051 currClassed = surface.attr('class');
49053 if (done || currSelected.empty()) {
49054 selected.call(reset);
49058 if (!lodash.isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
49059 selected.call(reset);
49060 classed = currClassed;
49061 selected = currSelected.call(calcAnimationParams);
49066 .duration(duration)
49067 .call(setAnimationParams, fromTo)
49068 .on('end', function() {
49069 surface.call(run, toFrom);
49074 var breathe = function(surface) {
49076 timer$$1 = timer(function() {
49077 // wait for elements to actually become selected
49078 if (surface.selectAll(selector$$1).empty()) {
49082 surface.call(run, 'from');
49089 breathe.off = function() {
49103 function behaviorCopy(context) {
49104 var keybinding = d3keybinding('copy');
49107 function groupEntities(ids, graph) {
49108 var entities = ids.map(function (id) { return graph.entity(id); });
49109 return lodash.extend({relation: [], way: [], node: []},
49110 lodash.groupBy(entities, function(entity) { return entity.type; }));
49114 function getDescendants(id, graph, descendants) {
49115 var entity = graph.entity(id),
49118 descendants = descendants || {};
49120 if (entity.type === 'relation') {
49121 children = lodash.map(entity.members, 'id');
49122 } else if (entity.type === 'way') {
49123 children = entity.nodes;
49128 for (i = 0; i < children.length; i++) {
49129 if (!descendants[children[i]]) {
49130 descendants[children[i]] = true;
49131 descendants = getDescendants(children[i], graph, descendants);
49135 return descendants;
49139 function doCopy() {
49140 event.preventDefault();
49141 if (context.inIntro()) return;
49143 var graph = context.graph(),
49144 selected = groupEntities(context.selectedIDs(), graph),
49149 for (i = 0; i < selected.relation.length; i++) {
49150 entity = selected.relation[i];
49151 if (!skip[entity.id] && entity.isComplete(graph)) {
49152 canCopy.push(entity.id);
49153 skip = getDescendants(entity.id, graph, skip);
49156 for (i = 0; i < selected.way.length; i++) {
49157 entity = selected.way[i];
49158 if (!skip[entity.id]) {
49159 canCopy.push(entity.id);
49160 skip = getDescendants(entity.id, graph, skip);
49163 for (i = 0; i < selected.node.length; i++) {
49164 entity = selected.node[i];
49165 if (!skip[entity.id]) {
49166 canCopy.push(entity.id);
49170 context.copyIDs(canCopy);
49175 keybinding.on(uiCmd('⌘C'), doCopy);
49176 select(document).call(keybinding);
49181 copy.off = function() {
49182 select(document).call(keybinding.off);
49190 `behaviorDrag` is like `d3.behavior.drag`, with the following differences:
49192 * The `origin` function is expected to return an [x, y] tuple rather than an
49194 * The events are `start`, `move`, and `end`.
49195 (https://github.com/mbostock/d3/issues/563)
49196 * The `start` event is not dispatched until the first cursor movement occurs.
49197 (https://github.com/mbostock/d3/pull/368)
49198 * The `move` event has a `point` and `delta` [x, y] tuple properties rather
49199 than `x`, `y`, `dx`, and `dy` properties.
49200 * The `end` event is not dispatched if no movement occurs.
49201 * An `off` function is available that unbinds the drag's internal event handlers.
49202 * Delegation is supported via the `delegate` function.
49205 function behaviorDrag() {
49206 var event$$1 = dispatch('start', 'move', 'end'),
49210 event_, target, surface;
49213 function d3_eventCancel() {
49214 event.stopPropagation();
49215 event.preventDefault();
49218 function eventOf(thiz, argumentz) {
49219 return function(e1) {
49220 e1.target = drag$$1;
49221 customEvent(e1, event$$1.apply, event$$1, [e1.type, thiz, argumentz]);
49225 var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect'),
49226 d3_event_userSelectSuppress = d3_event_userSelectProperty ?
49228 var selection$$1 = selection(),
49229 select$$1 = selection$$1.style(d3_event_userSelectProperty);
49230 selection$$1.style(d3_event_userSelectProperty, 'none');
49231 return function () {
49232 selection$$1.style(d3_event_userSelectProperty, select$$1);
49236 var w = select(window).on('selectstart.' + type, d3_eventCancel);
49237 return function () {
49238 w.on('selectstart.' + type, null);
49243 function mousedown() {
49245 event_ = eventOf(target, arguments);
49247 var eventTarget = event.target,
49248 touchId = event.touches ? event.changedTouches[0].identifier : null,
49252 selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
49254 var w = select(window)
49255 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
49256 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
49259 offset = origin.apply(target, arguments);
49260 offset = [offset[0] - origin_[0], offset[1] - origin_[1]];
49265 if (touchId === null) event.stopPropagation();
49268 var p = target.parentNode || surface;
49269 return touchId !== null ? touches(p).filter(function(p) {
49270 return p.identifier === touchId;
49275 function dragmove() {
49277 dx = p[0] - origin_[0],
49278 dy = p[1] - origin_[1];
49280 if (dx === 0 && dy === 0)
49295 point: [p[0] + offset[0], p[1] + offset[1]],
49301 function dragend() {
49308 if (event.target === eventTarget) w.on('click.drag', click, true);
49311 w.on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
49312 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
49319 w.on('click.drag', null);
49324 function drag$$1(selection$$1) {
49325 var matchesSelector = utilPrefixDOMProperty('matchesSelector'),
49326 delegate = mousedown;
49329 delegate = function() {
49331 target = event.target;
49332 for (; target && target !== root; target = target.parentNode) {
49333 if (target[matchesSelector](selector$$1) &&
49334 (!filter || filter(target.__data__))) {
49335 return mousedown.call(target, target.__data__);
49341 selection$$1.on('mousedown.drag' + selector$$1, delegate)
49342 .on('touchstart.drag' + selector$$1, delegate);
49346 drag$$1.off = function(selection$$1) {
49347 selection$$1.on('mousedown.drag' + selector$$1, null)
49348 .on('touchstart.drag' + selector$$1, null);
49352 drag$$1.delegate = function(_) {
49353 if (!arguments.length) return selector$$1;
49359 drag$$1.filter = function(_) {
49360 if (!arguments.length) return origin;
49366 drag$$1.origin = function (_) {
49367 if (!arguments.length) return origin;
49373 drag$$1.cancel = function() {
49375 .on('mousemove.drag', null)
49376 .on('mouseup.drag', null);
49381 drag$$1.target = function() {
49382 if (!arguments.length) return target;
49383 target = arguments[0];
49384 event_ = eventOf(target, Array.prototype.slice.call(arguments, 1));
49389 drag$$1.surface = function() {
49390 if (!arguments.length) return surface;
49391 surface = arguments[0];
49396 return utilRebind(drag$$1, event$$1, 'on');
49399 function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
49401 var way = context.entity(wayId),
49402 isArea = context.geometry(wayId) === 'area',
49404 annotation = t((way.isDegenerate() ?
49405 'operations.start.annotation.' :
49406 'operations.continue.annotation.') + context.geometry(wayId)),
49407 draw = behaviorDraw(context);
49409 var startIndex = typeof index === 'undefined' ? way.nodes.length - 1 : 0,
49410 start = osmNode({loc: context.graph().entity(way.nodes[startIndex]).loc}),
49411 end = osmNode({loc: context.map().mouseCoordinates()}),
49413 nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
49414 tags: lodash.clone(way.tags)
49417 var fn = context[way.isDegenerate() ? 'replace' : 'perform'];
49419 fn(actionAddEntity(end),
49420 actionAddVertex(wayId, end.id, index)
49423 fn(actionAddEntity(start),
49424 actionAddEntity(end),
49425 actionAddEntity(segment)
49430 function move(datum) {
49433 if (datum.type === 'node' && datum.id !== end.id) {
49436 } else if (datum.type === 'way' && datum.id !== segment.id) {
49437 var dims = context.map().dimensions(),
49438 mouse = context.mouse(),
49440 trySnap = mouse[0] > pad && mouse[0] < dims[0] - pad &&
49441 mouse[1] > pad && mouse[1] < dims[1] - pad;
49444 loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
49449 loc = context.map().mouseCoordinates();
49452 context.replace(actionMoveNode(end.id, loc));
49456 function undone() {
49458 context.enter(modeBrowse$$1(context));
49462 function setActiveElements() {
49463 var active = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
49464 context.surface().selectAll(utilEntitySelector(active))
49465 .classed('active', true);
49469 var drawWay = function(surface) {
49470 draw.on('move', move)
49471 .on('click', drawWay.add)
49472 .on('clickWay', drawWay.addWay)
49473 .on('clickNode', drawWay.addNode)
49474 .on('undo', context.undo)
49475 .on('cancel', drawWay.cancel)
49476 .on('finish', drawWay.finish);
49479 .dblclickEnable(false)
49480 .on('drawn.draw', setActiveElements);
49482 setActiveElements();
49484 surface.call(draw);
49487 .on('undone.draw', undone);
49491 drawWay.off = function(surface) {
49496 .on('drawn.draw', null);
49498 surface.call(draw.off)
49499 .selectAll('.active')
49500 .classed('active', false);
49503 .on('undone.draw', null);
49507 function ReplaceTemporaryNode(newNode) {
49508 return function(graph) {
49511 .replace(way.addNode(newNode.id, index))
49516 .replace(graph.entity(wayId).addNode(newNode.id, index))
49525 // Accept the current position of the temporary node and continue drawing.
49526 drawWay.add = function(loc) {
49527 // prevent duplicate nodes
49528 var last = context.hasEntity(way.nodes[way.nodes.length - (isArea ? 2 : 1)]);
49529 if (last && last.loc[0] === loc[0] && last.loc[1] === loc[1]) return;
49531 var newNode = osmNode({loc: loc});
49534 actionAddEntity(newNode),
49535 ReplaceTemporaryNode(newNode),
49540 context.enter(mode);
49544 // Connect the way to an existing way.
49545 drawWay.addWay = function(loc, edge) {
49546 var previousEdge = startIndex ?
49547 [way.nodes[startIndex], way.nodes[startIndex - 1]] :
49548 [way.nodes[0], way.nodes[1]];
49550 // Avoid creating duplicate segments
49551 if (!isArea && geoEdgeEqual(edge, previousEdge))
49554 var newNode = osmNode({ loc: loc });
49557 actionAddMidpoint({ loc: loc, edge: edge}, newNode),
49558 ReplaceTemporaryNode(newNode),
49563 context.enter(mode);
49567 // Connect the way to an existing node and continue drawing.
49568 drawWay.addNode = function(node) {
49569 // Avoid creating duplicate segments
49570 if (way.areAdjacent(node.id, way.nodes[way.nodes.length - 1])) return;
49573 ReplaceTemporaryNode(node),
49578 context.enter(mode);
49582 // Finish the draw operation, removing the temporary node. If the way has enough
49583 // nodes to be valid, it's selected. Otherwise, return to browse mode.
49584 drawWay.finish = function() {
49588 window.setTimeout(function() {
49589 context.map().dblclickEnable(true);
49592 if (context.hasEntity(wayId)) {
49594 modeSelect(context, [wayId]).suppressMenu(true).newFeature(true)
49597 context.enter(modeBrowse$$1(context));
49602 // Cancel the draw operation and return to browse, deleting everything drawn.
49603 drawWay.cancel = function() {
49605 utilFunctor(baseGraph),
49606 t('operations.cancel_draw.annotation'));
49608 window.setTimeout(function() {
49609 context.map().dblclickEnable(true);
49613 context.enter(modeBrowse$$1(context));
49617 drawWay.tail = function(text) {
49626 function behaviorHash(context) {
49627 var s0 = null, // cached window.location.hash
49628 lat = 90 - 1e-8; // allowable latitude range
49631 var parser = function(map$$1, s) {
49632 var q = utilStringQs(s);
49633 var args = (q.map || '').split('/').map(Number);
49634 if (args.length < 3 || args.some(isNaN)) {
49635 return true; // replace bogus hash
49636 } else if (s !== formatter(map$$1).slice(1)) {
49637 map$$1.centerZoom([args[2],
49638 Math.min(lat, Math.max(-lat, args[1]))], args[0]);
49643 var formatter = function(map$$1) {
49644 var mode = context.mode(),
49645 center = map$$1.center(),
49646 zoom$$1 = map$$1.zoom(),
49647 precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2)),
49648 q = lodash.omit(utilStringQs(window.location.hash.substring(1)), 'comment'),
49651 if (mode && mode.id === 'browse') {
49654 var selected = context.selectedIDs().filter(function(id) {
49655 return !context.entity(id).isNew();
49657 if (selected.length) {
49658 newParams.id = selected.join(',');
49662 newParams.map = zoom$$1.toFixed(2) +
49663 '/' + center[1].toFixed(precision) +
49664 '/' + center[0].toFixed(precision);
49666 return '#' + utilQsString(lodash.assign(q, newParams), true);
49670 function update() {
49671 if (context.inIntro()) return;
49672 var s1 = formatter(context.map());
49674 window.location.replace(s0 = s1); // don't recenter the map!
49679 var throttledUpdate = lodash.throttle(update, 500);
49682 function hashchange() {
49683 if (window.location.hash === s0) return; // ignore spurious hashchange events
49684 if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
49685 update(); // replace bogus hash
49692 .on('move.hash', throttledUpdate);
49695 .on('enter.hash', throttledUpdate);
49698 .on('hashchange.hash', hashchange);
49700 if (window.location.hash) {
49701 var q = utilStringQs(window.location.hash.substring(1));
49702 if (q.id) context.zoomToEntity(q.id.split(',')[0], !q.map);
49703 if (q.comment) context.storage('comment', q.comment);
49705 if (q.map) hash.hadHash = true;
49710 hash.off = function() {
49711 throttledUpdate.cancel();
49714 .on('move.hash', null);
49717 .on('enter.hash', null);
49720 .on('hashchange.hash', null);
49722 window.location.hash = '';
49729 function behaviorLasso(context) {
49731 var behavior = function(selection$$1) {
49735 function mousedown() {
49736 var button = 0; // left
49737 if (event.button === button && event.shiftKey === true) {
49741 .on('mousemove.lasso', mousemove)
49742 .on('mouseup.lasso', mouseup);
49744 event.stopPropagation();
49749 function mousemove() {
49751 lasso = uiLasso(context);
49752 context.surface().call(lasso);
49755 lasso.p(context.mouse());
49759 function normalize(a, b) {
49761 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
49762 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
49766 function lassoed() {
49767 if (!lasso) return [];
49769 var graph = context.graph(),
49770 bounds = lasso.extent().map(context.projection.invert),
49771 extent$$1 = geoExtent$$1(normalize(bounds[0], bounds[1]));
49773 return lodash.map(context.intersects(extent$$1).filter(function(entity) {
49774 return entity.type === 'node' &&
49775 geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
49776 !context.features().isHidden(entity, graph, entity.geometry(graph));
49781 function mouseup() {
49783 .on('mousemove.lasso', null)
49784 .on('mouseup.lasso', null);
49786 if (!lasso) return;
49788 var ids = lassoed();
49792 context.enter(modeSelect(context, ids));
49797 .on('mousedown.lasso', mousedown);
49801 behavior.off = function(selection$$1) {
49802 selection$$1.on('mousedown.lasso', null);
49809 function behaviorPaste(context) {
49810 var keybinding = d3keybinding('paste');
49812 function omitTag(v, k) {
49820 k === 'description' ||
49821 k.indexOf('name') !== -1 ||
49822 k.indexOf('wiki') === 0 ||
49823 k.indexOf('addr:') === 0 ||
49824 k.indexOf('contact:') === 0
49829 function doPaste() {
49830 event.preventDefault();
49831 if (context.inIntro()) return;
49833 var baseGraph = context.graph(),
49834 mouse$$1 = context.mouse(),
49835 projection = context.projection,
49836 viewport = geoExtent$$1(projection.clipExtent()).polygon();
49838 if (!geoPointInPolygon(mouse$$1, viewport)) return;
49840 var extent$$1 = geoExtent$$1(),
49841 oldIDs = context.copyIDs(),
49842 oldGraph = context.copyGraph(),
49845 if (!oldIDs.length) return;
49847 var action = actionCopyEntities(oldIDs, oldGraph);
49848 context.perform(action);
49850 var copies = action.copies();
49851 for (var id in copies) {
49852 var oldEntity = oldGraph.entity(id),
49853 newEntity = copies[id];
49855 extent$$1._extend(oldEntity.extent(oldGraph));
49856 newIDs.push(newEntity.id);
49858 actionChangeTags(newEntity.id, lodash.omit(newEntity.tags, omitTag))
49862 // Put pasted objects where mouse pointer is..
49863 var center = projection(extent$$1.center()),
49864 delta = [ mouse$$1[0] - center[0], mouse$$1[1] - center[1] ];
49866 context.perform(actionMove(newIDs, delta, projection));
49867 context.enter(modeMove$$1(context, newIDs, baseGraph));
49872 keybinding.on(uiCmd('⌘V'), doPaste);
49873 select(document).call(keybinding);
49878 paste.off = function() {
49879 select(document).call(keybinding.off);
49886 function behaviorSelect(context) {
49888 function keydown() {
49889 if (event && event.shiftKey) {
49891 .classed('behavior-multiselect', true);
49897 if (!event || !event.shiftKey) {
49899 .classed('behavior-multiselect', false);
49905 var datum = event.target.__data__,
49906 lasso = select('#surface .lasso').node(),
49907 mode = context.mode();
49909 if (!(datum instanceof osmEntity$$1)) {
49910 if (!event.shiftKey && !lasso && mode.id !== 'browse')
49911 context.enter(modeBrowse$$1(context));
49913 } else if (!event.shiftKey && !lasso) {
49914 // Avoid re-entering Select mode with same entity.
49915 if (context.selectedIDs().length !== 1 || context.selectedIDs()[0] !== datum.id) {
49916 context.enter(modeSelect(context, [datum.id]));
49918 mode.suppressMenu(false).reselect();
49920 } else if (context.selectedIDs().indexOf(datum.id) >= 0) {
49921 var selectedIDs = lodash.without(context.selectedIDs(), datum.id);
49922 context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse$$1(context));
49925 context.enter(modeSelect(context, context.selectedIDs().concat([datum.id])));
49930 var behavior = function(selection$$1) {
49932 .on('keydown.select', keydown)
49933 .on('keyup.select', keyup);
49935 selection$$1.on('click.select', click);
49941 behavior.off = function(selection$$1) {
49943 .on('keydown.select', null)
49944 .on('keyup.select', null);
49946 selection$$1.on('click.select', null);
49955 function modeAddArea$$1(context) {
49959 title: t('modes.add_area.title'),
49960 description: t('modes.add_area.description'),
49964 var behavior = behaviorAddWay(context)
49965 .tail(t('modes.add_area.tail'))
49966 .on('start', start)
49967 .on('startFromWay', startFromWay)
49968 .on('startFromNode', startFromNode),
49969 defaultTags = { area: 'yes' };
49972 function start(loc) {
49973 var graph = context.graph(),
49974 node = osmNode({ loc: loc }),
49975 way = osmWay({ tags: defaultTags });
49978 actionAddEntity(node),
49979 actionAddEntity(way),
49980 actionAddVertex(way.id, node.id),
49981 actionAddVertex(way.id, node.id)
49984 context.enter(modeDrawArea(context, way.id, graph));
49988 function startFromWay(loc, edge) {
49989 var graph = context.graph(),
49990 node = osmNode({ loc: loc }),
49991 way = osmWay({ tags: defaultTags });
49994 actionAddEntity(node),
49995 actionAddEntity(way),
49996 actionAddVertex(way.id, node.id),
49997 actionAddVertex(way.id, node.id),
49998 actionAddMidpoint({ loc: loc, edge: edge }, node)
50001 context.enter(modeDrawArea(context, way.id, graph));
50005 function startFromNode(node) {
50006 var graph = context.graph(),
50007 way = osmWay({ tags: defaultTags });
50010 actionAddEntity(way),
50011 actionAddVertex(way.id, node.id),
50012 actionAddVertex(way.id, node.id)
50015 context.enter(modeDrawArea(context, way.id, graph));
50019 mode.enter = function() {
50020 context.install(behavior);
50024 mode.exit = function() {
50025 context.uninstall(behavior);
50032 function modeAddLine$$1(context) {
50036 title: t('modes.add_line.title'),
50037 description: t('modes.add_line.description'),
50041 var behavior = behaviorAddWay(context)
50042 .tail(t('modes.add_line.tail'))
50043 .on('start', start)
50044 .on('startFromWay', startFromWay)
50045 .on('startFromNode', startFromNode);
50048 function start(loc) {
50049 var baseGraph = context.graph(),
50050 node = osmNode({ loc: loc }),
50054 actionAddEntity(node),
50055 actionAddEntity(way),
50056 actionAddVertex(way.id, node.id)
50059 context.enter(modeDrawLine(context, way.id, baseGraph));
50063 function startFromWay(loc, edge) {
50064 var baseGraph = context.graph(),
50065 node = osmNode({ loc: loc }),
50069 actionAddEntity(node),
50070 actionAddEntity(way),
50071 actionAddVertex(way.id, node.id),
50072 actionAddMidpoint({ loc: loc, edge: edge }, node)
50075 context.enter(modeDrawLine(context, way.id, baseGraph));
50079 function startFromNode(node) {
50080 var baseGraph = context.graph(),
50084 actionAddEntity(way),
50085 actionAddVertex(way.id, node.id)
50088 context.enter(modeDrawLine(context, way.id, baseGraph));
50092 mode.enter = function() {
50093 context.install(behavior);
50097 mode.exit = function() {
50098 context.uninstall(behavior);
50104 function modeAddPoint$$1(context) {
50108 title: t('modes.add_point.title'),
50109 description: t('modes.add_point.description'),
50113 var behavior = behaviorDraw(context)
50114 .tail(t('modes.add_point.tail'))
50116 .on('clickWay', addWay)
50117 .on('clickNode', addNode)
50118 .on('cancel', cancel)
50119 .on('finish', cancel);
50122 function add(loc) {
50123 var node = osmNode({ loc: loc });
50126 actionAddEntity(node),
50127 t('operations.add.annotation.point')
50131 modeSelect(context, [node.id]).suppressMenu(true).newFeature(true)
50136 function addWay(loc) {
50141 function addNode(node) {
50146 function cancel() {
50147 context.enter(modeBrowse$$1(context));
50151 mode.enter = function() {
50152 context.install(behavior);
50156 mode.exit = function() {
50157 context.uninstall(behavior);
50164 function modeBrowse$$1(context) {
50168 title: t('modes.browse.title'),
50169 description: t('modes.browse.description')
50173 behaviorPaste(context),
50174 behaviorHover(context).on('hover', context.ui().sidebar.hover),
50175 behaviorSelect(context),
50176 behaviorLasso(context),
50177 modeDragNode$$1(context).behavior
50181 mode.enter = function() {
50182 behaviors.forEach(function(behavior) {
50183 context.install(behavior);
50186 // Get focus on the body.
50187 if (document.activeElement && document.activeElement.blur) {
50188 document.activeElement.blur();
50192 context.ui().sidebar.show(sidebar);
50194 context.ui().sidebar.select(null);
50199 mode.exit = function() {
50200 context.ui().sidebar.hover.cancel();
50201 behaviors.forEach(function(behavior) {
50202 context.uninstall(behavior);
50206 context.ui().sidebar.hide();
50211 mode.sidebar = function(_) {
50212 if (!arguments.length) return sidebar;
50221 function modeDragNode$$1(context) {
50232 hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover),
50233 edit = behaviorEdit(context);
50236 function edge(point, size) {
50237 var pad = [30, 100, 30, 100];
50238 if (point[0] > size[0] - pad[0]) return [-10, 0];
50239 else if (point[0] < pad[2]) return [10, 0];
50240 else if (point[1] > size[1] - pad[1]) return [0, -10];
50241 else if (point[1] < pad[3]) return [0, 10];
50246 function startNudge(nudge) {
50247 if (nudgeInterval) window.clearInterval(nudgeInterval);
50248 nudgeInterval = window.setInterval(function() {
50249 context.pan(nudge);
50254 function stopNudge() {
50255 if (nudgeInterval) window.clearInterval(nudgeInterval);
50256 nudgeInterval = null;
50260 function moveAnnotation(entity) {
50261 return t('operations.move.annotation.' + entity.geometry(context.graph()));
50265 function connectAnnotation(entity) {
50266 return t('operations.connect.annotation.' + entity.geometry(context.graph()));
50270 function origin(entity) {
50271 return context.projection(entity.loc);
50275 function start(entity) {
50276 isCancelled = event.sourceEvent.shiftKey ||
50277 context.features().hasHiddenConnections(entity, context.graph());
50279 if (isCancelled) return behavior.cancel();
50281 wasMidpoint = entity.type === 'midpoint';
50283 var midpoint = entity;
50284 entity = osmNode();
50285 context.perform(actionAddMidpoint(midpoint, entity));
50287 var vertex = context.surface().selectAll('.' + entity.id);
50288 behavior.target(vertex.node(), entity);
50291 context.perform(actionNoop());
50294 activeIDs = lodash.map(context.graph().parentWays(entity), 'id');
50295 activeIDs.push(entity.id);
50296 context.enter(mode);
50301 if (event.sourceEvent.altKey) {
50305 return event.sourceEvent.target.__data__ || {};
50309 // via https://gist.github.com/shawnbot/4166283
50310 function childOf(p, c) {
50311 if (p === c) return false;
50312 while (c && c !== p) c = c.parentNode;
50317 function move(entity) {
50318 if (isCancelled) return;
50319 event.sourceEvent.stopPropagation();
50321 var nudge = childOf(context.container().node(),
50322 event.sourceEvent.toElement) &&
50323 edge(event.point, context.map().dimensions());
50325 if (nudge) startNudge(nudge);
50328 var loc = context.projection.invert(event.point);
50331 if (d.type === 'node' && d.id !== entity.id) {
50333 } else if (d.type === 'way' && !select(event.sourceEvent.target).classed('fill')) {
50334 loc = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection).loc;
50338 actionMoveNode(entity.id, loc),
50339 moveAnnotation(entity)
50344 function end(entity) {
50345 if (isCancelled) return;
50349 if (d.type === 'way') {
50350 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
50352 actionAddMidpoint({ loc: choice.loc, edge: [d.nodes[choice.index - 1], d.nodes[choice.index]] }, entity),
50353 connectAnnotation(d)
50356 } else if (d.type === 'node' && d.id !== entity.id) {
50358 actionConnect([d.id, entity.id]),
50359 connectAnnotation(d)
50362 } else if (wasMidpoint) {
50365 t('operations.add.annotation.vertex')
50371 moveAnnotation(entity)
50375 var reselection = selectedIDs.filter(function(id) {
50376 return context.graph().hasEntity(id);
50379 if (reselection.length) {
50380 context.enter(modeSelect(context, reselection).suppressMenu(true));
50382 context.enter(modeBrowse$$1(context));
50387 function cancel() {
50389 context.enter(modeBrowse$$1(context));
50393 function setActiveElements() {
50394 context.surface().selectAll(utilEntitySelector(activeIDs))
50395 .classed('active', true);
50399 var behavior = behaviorDrag()
50400 .delegate('g.node, g.point, g.midpoint')
50401 .surface(context.surface().node())
50403 .on('start', start)
50408 mode.enter = function() {
50409 context.install(hover);
50410 context.install(edit);
50413 .on('undone.drag-node', cancel);
50416 .on('drawn.drag-node', setActiveElements);
50418 setActiveElements();
50422 mode.exit = function() {
50423 context.ui().sidebar.hover.cancel();
50424 context.uninstall(hover);
50425 context.uninstall(edit);
50428 .on('undone.drag-node', null);
50431 .on('drawn.drag-node', null);
50434 .selectAll('.active')
50435 .classed('active', false);
50441 mode.selectedIDs = function(_) {
50442 if (!arguments.length) return selectedIDs;
50448 mode.behavior = behavior;
50454 function modeDrawArea(context, wayId, baseGraph) {
50463 mode.enter = function() {
50464 var way = context.entity(wayId),
50465 headId = way.nodes[way.nodes.length - 2],
50466 tailId = way.first();
50468 behavior = behaviorDrawWay(context, wayId, -1, mode, baseGraph)
50469 .tail(t('modes.draw_area.tail'));
50471 var addNode = behavior.addNode;
50473 behavior.addNode = function(node) {
50474 if (node.id === headId || node.id === tailId) {
50481 context.install(behavior);
50485 mode.exit = function() {
50486 context.uninstall(behavior);
50490 mode.selectedIDs = function() {
50498 function modeDrawLine(context, wayId, baseGraph, affix) {
50507 mode.enter = function() {
50508 var way = context.entity(wayId),
50509 index = (affix === 'prefix') ? 0 : undefined,
50510 headId = (affix === 'prefix') ? way.first() : way.last();
50512 behavior = behaviorDrawWay(context, wayId, index, mode, baseGraph)
50513 .tail(t('modes.draw_line.tail'));
50515 var addNode = behavior.addNode;
50517 behavior.addNode = function(node) {
50518 if (node.id === headId) {
50525 context.install(behavior);
50529 mode.exit = function() {
50530 context.uninstall(behavior);
50534 mode.selectedIDs = function() {
50542 function modeMove$$1(context, entityIDs, baseGraph) {
50548 var keybinding = d3keybinding('move'),
50549 edit = behaviorEdit(context),
50550 annotation = entityIDs.length === 1 ?
50551 t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
50552 t('operations.move.annotation.multiple'),
50558 function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
50561 function edge(point, size) {
50562 var pad = [30, 100, 30, 100];
50563 if (point[0] > size[0] - pad[0]) return [-10, 0];
50564 else if (point[0] < pad[2]) return [10, 0];
50565 else if (point[1] > size[1] - pad[1]) return [0, -10];
50566 else if (point[1] < pad[3]) return [0, 10];
50571 function startNudge(nudge) {
50572 if (nudgeInterval) window.clearInterval(nudgeInterval);
50573 nudgeInterval = window.setInterval(function() {
50574 context.pan(nudge);
50576 var currMouse = context.mouse(),
50577 origMouse = context.projection(origin),
50578 delta = vecSub(vecSub(currMouse, origMouse), nudge),
50579 action = actionMove(entityIDs, delta, context.projection, cache);
50581 context.overwrite(action, annotation);
50587 function stopNudge() {
50588 if (nudgeInterval) window.clearInterval(nudgeInterval);
50589 nudgeInterval = null;
50594 var currMouse = context.mouse(),
50595 origMouse = context.projection(origin),
50596 delta = vecSub(currMouse, origMouse),
50597 action = actionMove(entityIDs, delta, context.projection, cache);
50599 context.overwrite(action, annotation);
50601 var nudge = edge(currMouse, context.map().dimensions());
50602 if (nudge) startNudge(nudge);
50607 function finish() {
50608 event.stopPropagation();
50609 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
50614 function cancel() {
50616 while (context.graph() !== baseGraph) context.pop();
50617 context.enter(modeBrowse$$1(context));
50620 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
50626 function undone() {
50627 context.enter(modeBrowse$$1(context));
50631 mode.enter = function() {
50632 origin = context.map().mouseCoordinates();
50635 context.install(edit);
50643 .on('mousemove.move', move)
50644 .on('click.move', finish);
50647 .on('undone.move', undone);
50658 mode.exit = function() {
50661 context.uninstall(edit);
50664 .on('mousemove.move', null)
50665 .on('click.move', null);
50668 .on('undone.move', null);
50677 function modeRotateWay$$1(context, wayId) {
50683 var keybinding = d3keybinding('rotate-way'),
50684 edit = behaviorEdit(context);
50687 mode.enter = function() {
50688 context.install(edit);
50690 var annotation = t('operations.rotate.annotation.' + context.geometry(wayId)),
50691 way = context.graph().entity(wayId),
50692 nodes = lodash.uniq(context.graph().childNodes(way)),
50693 points = nodes.map(function(n) { return context.projection(n.loc); }),
50694 pivot = d3polygonCentroid(points),
50703 .on('mousemove.rotate-way', rotate)
50704 .on('click.rotate-way', finish);
50707 .on('undone.rotate-way', undone);
50717 function rotate() {
50718 var mousePoint = context.mouse(),
50719 newAngle = Math.atan2(mousePoint[1] - pivot[1], mousePoint[0] - pivot[0]);
50721 if (typeof angle === 'undefined') angle = newAngle;
50724 actionRotateWay(wayId, pivot, newAngle - angle, context.projection),
50732 function finish() {
50733 event.stopPropagation();
50734 context.enter(modeSelect(context, [wayId]).suppressMenu(true));
50738 function cancel() {
50740 context.enter(modeSelect(context, [wayId]).suppressMenu(true));
50744 function undone() {
50745 context.enter(modeBrowse$$1(context));
50750 mode.exit = function() {
50751 context.uninstall(edit);
50754 .on('mousemove.rotate-way', null)
50755 .on('click.rotate-way', null);
50758 .on('undone.rotate-way', null);
50767 function modeSave$$1(context) {
50772 var ui = uiCommit(context)
50773 .on('cancel', cancel)
50777 function cancel() {
50778 context.enter(modeBrowse$$1(context));
50782 function save(e, tryAgain) {
50783 function withChildNodes(ids, graph) {
50784 return lodash.uniq(lodash.reduce(ids, function(result, id) {
50785 var e = graph.entity(id);
50786 if (e.type === 'way') {
50788 var cn = graph.childNodes(e);
50789 result.push.apply(result, lodash.map(lodash.filter(cn, 'version'), 'id'));
50791 /* eslint-disable no-console */
50792 if (typeof console !== 'undefined') console.error(err);
50793 /* eslint-enable no-console */
50797 }, lodash.clone(ids)));
50800 var loading = uiLoading(context).message(t('save.uploading')).blocking(true),
50801 history = context.history(),
50802 origChanges = history.changes(actionDiscardTags(history.difference())),
50803 localGraph = context.graph(),
50804 remoteGraph = coreGraph$$1(history.base(), true),
50805 modified = lodash.filter(history.difference().summary(), {changeType: 'modified'}),
50806 toCheck = lodash.map(lodash.map(modified, 'entity'), 'id'),
50807 toLoad = withChildNodes(toCheck, localGraph),
50811 if (!tryAgain) history.perform(actionNoop()); // checkpoint
50812 context.container().call(loading);
50814 if (toCheck.length) {
50815 context.connection().loadMultiple(toLoad, loaded);
50821 // Reload modified entities into an alternate graph and check for conflicts..
50822 function loaded(err, result) {
50823 if (errors.length) return;
50827 msg: err.responseText,
50828 details: [ t('save.status_code', { code: err.status }) ]
50834 lodash.each(result.data, function(entity) {
50835 remoteGraph.replace(entity);
50836 toLoad = lodash.without(toLoad, entity.id);
50838 // Because loadMultiple doesn't download /full like loadEntity,
50839 // need to also load children that aren't already being checked..
50840 if (!entity.visible) return;
50841 if (entity.type === 'way') {
50842 loadMore.push.apply(loadMore,
50843 lodash.difference(entity.nodes, toCheck, toLoad, loadMore));
50844 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
50845 loadMore.push.apply(loadMore,
50846 lodash.difference(lodash.map(entity.members, 'id'), toCheck, toLoad, loadMore));
50850 if (loadMore.length) {
50851 toLoad.push.apply(toLoad, loadMore);
50852 context.connection().loadMultiple(loadMore, loaded);
50855 if (!toLoad.length) {
50862 function checkConflicts() {
50863 function choice(id, text$$1, action) {
50864 return { id: id, text: text$$1, action: function() { history.replace(action); } };
50866 function formatUser(d) {
50867 return '<a href="' + context.connection().userURL(d) + '" target="_blank">' + d + '</a>';
50869 function entityName(entity) {
50870 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
50873 function compareVersions(local$$1, remote) {
50874 if (local$$1.version !== remote.version) return false;
50876 if (local$$1.type === 'way') {
50877 var children = lodash.union(local$$1.nodes, remote.nodes);
50879 for (var i = 0; i < children.length; i++) {
50880 var a = localGraph.hasEntity(children[i]),
50881 b = remoteGraph.hasEntity(children[i]);
50883 if (a && b && a.version !== b.version) return false;
50890 lodash.each(toCheck, function(id) {
50891 var local$$1 = localGraph.entity(id),
50892 remote = remoteGraph.entity(id);
50894 if (compareVersions(local$$1, remote)) return;
50896 var action = actionMergeRemoteChanges,
50897 merge$$1 = action(id, localGraph, remoteGraph, formatUser);
50899 history.replace(merge$$1);
50901 var mergeConflicts = merge$$1.conflicts();
50902 if (!mergeConflicts.length) return; // merged safely
50904 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
50905 forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote'),
50906 keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore')),
50907 keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
50911 name: entityName(local$$1),
50912 details: mergeConflicts,
50915 choice(id, keepMine, forceLocal),
50916 choice(id, keepTheirs, forceRemote)
50925 function finalize() {
50926 if (conflicts.length) {
50927 conflicts.sort(function(a,b) { return b.id.localeCompare(a.id); });
50929 } else if (errors.length) {
50932 var changes = history.changes(actionDiscardTags(history.difference()));
50933 if (changes.modified.length || changes.created.length || changes.deleted.length) {
50934 context.connection().putChangeset(
50938 history.imageryUsed(),
50939 function(err, changeset_id) {
50942 msg: err.responseText,
50943 details: [ t('save.status_code', { code: err.status }) ]
50947 history.clearSaved();
50948 success(e, changeset_id);
50949 // Add delay to allow for postgres replication #1646 #2678
50950 window.setTimeout(function() {
50956 } else { // changes were insignificant or reverted by user
50965 function showConflicts() {
50966 var selection$$1 = context.container()
50967 .select('#sidebar')
50969 .attr('class','sidebar-component');
50973 selection$$1.call(uiConflicts(context)
50975 .on('download', function() {
50976 var data = JXON.stringify(context.connection().osmChangeJXON('CHANGEME', origChanges)),
50977 win = window.open('data:text/xml,' + encodeURIComponent(data), '_blank');
50980 .on('cancel', function() {
50982 selection$$1.remove();
50984 .on('save', function() {
50985 for (var i = 0; i < conflicts.length; i++) {
50986 if (conflicts[i].chosen === 1) { // user chose "keep theirs"
50987 var entity = context.hasEntity(conflicts[i].id);
50988 if (entity && entity.type === 'way') {
50989 var children = lodash.uniq(entity.nodes);
50990 for (var j = 0; j < children.length; j++) {
50991 history.replace(actionRevert(children[j]));
50994 history.replace(actionRevert(conflicts[i].id));
50998 selection$$1.remove();
51005 function showErrors() {
51006 var selection$$1 = uiConfirm(context.container());
51012 .select('.modal-section.header')
51014 .text(t('save.error'));
51016 addErrors(selection$$1, errors);
51017 selection$$1.okButton();
51021 function addErrors(selection$$1, data) {
51022 var message = selection$$1
51023 .select('.modal-section.message-text');
51025 var items = message
51026 .selectAll('.error-container')
51029 var enter = items.enter()
51031 .attr('class', 'error-container');
51035 .attr('class', 'error-description')
51037 .classed('hide-toggle', true)
51038 .text(function(d) { return d.msg || t('save.unknown_error_details'); })
51039 .on('click', function() {
51040 var error = select(this),
51041 detail = select(this.nextElementSibling),
51042 exp = error.classed('expanded');
51044 detail.style('display', exp ? 'none' : 'block');
51045 error.classed('expanded', !exp);
51047 event.preventDefault();
51050 var details = enter
51052 .attr('class', 'error-detail-container')
51053 .style('display', 'none');
51057 .attr('class', 'error-detail-list')
51059 .data(function(d) { return d.details || []; })
51062 .attr('class', 'error-detail-item')
51063 .text(function(d) { return d; });
51072 function success(e, changeset_id) {
51073 context.enter(modeBrowse$$1(context)
51074 .sidebar(uiSuccess(context)
51079 .on('cancel', function() {
51080 context.ui().sidebar.hide();
51087 mode.enter = function() {
51088 context.connection().authenticate(function(err) {
51092 context.ui().sidebar.show(ui);
51098 mode.exit = function() {
51099 context.ui().sidebar.hide();
51105 function operationCircularize(selectedIDs, context) {
51106 var entityId = selectedIDs[0],
51107 entity = context.entity(entityId),
51108 extent = entity.extent(context.graph()),
51109 geometry = context.geometry(entityId),
51110 action = actionCircularize(entityId, context.projection);
51112 var operation = function() {
51113 var annotation = t('operations.circularize.annotation.' + geometry);
51114 context.perform(action, annotation);
51118 operation.available = function() {
51119 return selectedIDs.length === 1 &&
51120 entity.type === 'way' &&
51121 lodash.uniq(entity.nodes).length > 1;
51125 operation.disabled = function() {
51127 if (extent.percentContainedIn(context.extent()) < 0.8) {
51128 reason = 'too_large';
51129 } else if (context.hasHiddenConnections(entityId)) {
51130 reason = 'connected_to_hidden';
51132 return action.disabled(context.graph()) || reason;
51136 operation.tooltip = function() {
51137 var disable = operation.disabled();
51139 t('operations.circularize.' + disable) :
51140 t('operations.circularize.description.' + geometry);
51144 operation.id = 'circularize';
51145 operation.keys = [t('operations.circularize.key')];
51146 operation.title = t('operations.circularize.title');
51152 function operationContinue(selectedIDs, context) {
51153 var graph = context.graph(),
51154 entities = selectedIDs.map(function(id) { return graph.entity(id); }),
51155 geometries = lodash.extend({ line: [], vertex: [] },
51156 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); })),
51157 vertex = geometries.vertex[0];
51160 function candidateWays() {
51161 return graph.parentWays(vertex).filter(function(parent) {
51162 return parent.geometry(graph) === 'line' &&
51163 parent.affix(vertex.id) &&
51164 (geometries.line.length === 0 || geometries.line[0] === parent);
51169 var operation = function() {
51170 var candidate = candidateWays()[0];
51172 modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
51177 operation.available = function() {
51178 return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
51179 !context.features().hasHiddenConnections(vertex, context.graph());
51183 operation.disabled = function() {
51184 var candidates = candidateWays();
51185 if (candidates.length === 0)
51186 return 'not_eligible';
51187 if (candidates.length > 1)
51192 operation.tooltip = function() {
51193 var disable = operation.disabled();
51195 t('operations.continue.' + disable) :
51196 t('operations.continue.description');
51200 operation.id = 'continue';
51201 operation.keys = [t('operations.continue.key')];
51202 operation.title = t('operations.continue.title');
51208 function operationDelete(selectedIDs, context) {
51209 var action = actionDeleteMultiple(selectedIDs);
51211 var operation = function() {
51215 if (selectedIDs.length > 1) {
51216 annotation = t('operations.delete.annotation.multiple', { n: selectedIDs.length });
51219 var id = selectedIDs[0],
51220 entity = context.entity(id),
51221 geometry = context.geometry(id),
51222 parents = context.graph().parentWays(entity),
51223 parent = parents[0];
51225 annotation = t('operations.delete.annotation.' + geometry);
51227 // Select the next closest node in the way.
51228 if (geometry === 'vertex' && parent.nodes.length > 2) {
51229 var nodes = parent.nodes,
51230 i = nodes.indexOf(id);
51234 } else if (i === nodes.length - 1) {
51237 var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
51238 b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
51239 i = a < b ? i - 1 : i + 1;
51242 nextSelectedID = nodes[i];
51246 context.perform(action, annotation);
51248 if (nextSelectedID && context.hasEntity(nextSelectedID)) {
51250 modeSelect(context, [nextSelectedID]).follow(true).suppressMenu(true)
51253 context.enter(modeBrowse$$1(context));
51259 operation.available = function() {
51264 operation.disabled = function() {
51266 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51267 reason = 'connected_to_hidden';
51269 return action.disabled(context.graph()) || reason;
51273 operation.tooltip = function() {
51274 var disable = operation.disabled();
51276 t('operations.delete.' + disable) :
51277 t('operations.delete.description');
51281 operation.id = 'delete';
51282 operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
51283 operation.title = t('operations.delete.title');
51289 function operationDisconnect(selectedIDs, context) {
51290 var vertices = lodash.filter(selectedIDs, function(entityId) {
51291 return context.geometry(entityId) === 'vertex';
51294 var entityId = vertices[0],
51295 action = actionDisconnect(entityId);
51297 if (selectedIDs.length > 1) {
51298 action.limitWays(lodash.without(selectedIDs, entityId));
51301 var operation = function() {
51302 context.perform(action, t('operations.disconnect.annotation'));
51306 operation.available = function() {
51307 return vertices.length === 1;
51311 operation.disabled = function() {
51313 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51314 reason = 'connected_to_hidden';
51316 return action.disabled(context.graph()) || reason;
51320 operation.tooltip = function() {
51321 var disable = operation.disabled();
51323 t('operations.disconnect.' + disable) :
51324 t('operations.disconnect.description');
51328 operation.id = 'disconnect';
51329 operation.keys = [t('operations.disconnect.key')];
51330 operation.title = t('operations.disconnect.title');
51336 function operationMerge(selectedIDs, context) {
51337 var join = actionJoin(selectedIDs),
51338 merge = actionMerge(selectedIDs),
51339 mergePolygon = actionMergePolygon(selectedIDs);
51341 var operation = function() {
51342 var annotation = t('operations.merge.annotation', {n: selectedIDs.length}),
51345 if (!join.disabled(context.graph())) {
51347 } else if (!merge.disabled(context.graph())) {
51350 action = mergePolygon;
51353 context.perform(action, annotation);
51354 var ids = selectedIDs.filter(function(id) { return context.hasEntity(id); });
51355 context.enter(modeSelect(context, ids).suppressMenu(true));
51359 operation.available = function() {
51360 return selectedIDs.length >= 2;
51364 operation.disabled = function() {
51365 return join.disabled(context.graph()) &&
51366 merge.disabled(context.graph()) &&
51367 mergePolygon.disabled(context.graph());
51371 operation.tooltip = function() {
51372 var j = join.disabled(context.graph()),
51373 m = merge.disabled(context.graph()),
51374 p = mergePolygon.disabled(context.graph());
51376 if (j === 'restriction' && m && p) {
51377 return t('operations.merge.restriction',
51378 { relation: context.presets().item('type/restriction').name() });
51381 if (p === 'incomplete_relation' && j && m) {
51382 return t('operations.merge.incomplete_relation');
51386 return t('operations.merge.' + j);
51389 return t('operations.merge.description');
51393 operation.id = 'merge';
51394 operation.keys = [t('operations.merge.key')];
51395 operation.title = t('operations.merge.title');
51401 function operationMove(selectedIDs, context) {
51402 var extent = selectedIDs.reduce(function(extent, id) {
51403 return extent.extend(context.entity(id).extent(context.graph()));
51404 }, geoExtent$$1());
51406 var operation = function() {
51407 context.enter(modeMove$$1(context, selectedIDs));
51411 operation.available = function() {
51412 return selectedIDs.length > 1 ||
51413 context.entity(selectedIDs[0]).type !== 'node';
51417 operation.disabled = function() {
51419 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51420 reason = 'too_large';
51421 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51422 reason = 'connected_to_hidden';
51425 return actionMove(selectedIDs).disabled(context.graph()) || reason;
51429 operation.tooltip = function() {
51430 var disable = operation.disabled();
51432 t('operations.move.' + disable) :
51433 t('operations.move.description');
51437 operation.id = 'move';
51438 operation.keys = [t('operations.move.key')];
51439 operation.title = t('operations.move.title');
51445 function operationOrthogonalize(selectedIDs, context) {
51446 var entityId = selectedIDs[0],
51447 entity = context.entity(entityId),
51448 extent = entity.extent(context.graph()),
51449 geometry = context.geometry(entityId),
51450 action = actionOrthogonalize(entityId, context.projection);
51452 var operation = function() {
51453 var annotation = t('operations.orthogonalize.annotation.' + geometry);
51454 context.perform(action, annotation);
51458 operation.available = function() {
51459 return selectedIDs.length === 1 &&
51460 entity.type === 'way' &&
51461 entity.isClosed() &&
51462 lodash.uniq(entity.nodes).length > 2;
51466 operation.disabled = function() {
51468 if (extent.percentContainedIn(context.extent()) < 0.8) {
51469 reason = 'too_large';
51470 } else if (context.hasHiddenConnections(entityId)) {
51471 reason = 'connected_to_hidden';
51473 return action.disabled(context.graph()) || reason;
51477 operation.tooltip = function() {
51478 var disable = operation.disabled();
51480 t('operations.orthogonalize.' + disable) :
51481 t('operations.orthogonalize.description.' + geometry);
51485 operation.id = 'orthogonalize';
51486 operation.keys = [t('operations.orthogonalize.key')];
51487 operation.title = t('operations.orthogonalize.title');
51493 function operationReverse(selectedIDs, context) {
51494 var entityId = selectedIDs[0];
51496 var operation = function() {
51498 actionReverse(entityId),
51499 t('operations.reverse.annotation')
51504 operation.available = function() {
51505 return selectedIDs.length === 1 &&
51506 context.geometry(entityId) === 'line';
51510 operation.disabled = function() {
51515 operation.tooltip = function() {
51516 return t('operations.reverse.description');
51520 operation.id = 'reverse';
51521 operation.keys = [t('operations.reverse.key')];
51522 operation.title = t('operations.reverse.title');
51528 function operationRotate(selectedIDs, context) {
51529 var entityId = selectedIDs[0],
51530 entity = context.entity(entityId),
51531 extent = entity.extent(context.graph()),
51532 geometry = context.geometry(entityId);
51534 var operation = function() {
51535 context.enter(modeRotateWay$$1(context, entityId));
51539 operation.available = function() {
51540 if (selectedIDs.length !== 1 || entity.type !== 'way')
51542 if (geometry === 'area')
51544 if (entity.isClosed() &&
51545 context.graph().parentRelations(entity).some(function(r) { return r.isMultipolygon(); }))
51551 operation.disabled = function() {
51552 if (extent.percentContainedIn(context.extent()) < 0.8) {
51553 return 'too_large';
51554 } else if (context.hasHiddenConnections(entityId)) {
51555 return 'connected_to_hidden';
51562 operation.tooltip = function() {
51563 var disable = operation.disabled();
51565 t('operations.rotate.' + disable) :
51566 t('operations.rotate.description');
51570 operation.id = 'rotate';
51571 operation.keys = [t('operations.rotate.key')];
51572 operation.title = t('operations.rotate.title');
51578 function operationSplit(selectedIDs, context) {
51579 var vertices = lodash.filter(selectedIDs, function(entityId) {
51580 return context.geometry(entityId) === 'vertex';
51583 var entityId = vertices[0],
51584 action = actionSplit(entityId);
51586 if (selectedIDs.length > 1) {
51587 action.limitWays(lodash.without(selectedIDs, entityId));
51591 var operation = function() {
51594 var ways = action.ways(context.graph());
51595 if (ways.length === 1) {
51596 annotation = t('operations.split.annotation.' + context.geometry(ways[0].id));
51598 annotation = t('operations.split.annotation.multiple', {n: ways.length});
51601 var difference = context.perform(action, annotation);
51602 context.enter(modeSelect(context, difference.extantIDs()));
51606 operation.available = function() {
51607 return vertices.length === 1;
51611 operation.disabled = function() {
51613 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51614 reason = 'connected_to_hidden';
51616 return action.disabled(context.graph()) || reason;
51620 operation.tooltip = function() {
51621 var disable = operation.disabled();
51623 return t('operations.split.' + disable);
51626 var ways = action.ways(context.graph());
51627 if (ways.length === 1) {
51628 return t('operations.split.description.' + context.geometry(ways[0].id));
51630 return t('operations.split.description.multiple');
51635 operation.id = 'split';
51636 operation.keys = [t('operations.split.key')];
51637 operation.title = t('operations.split.title');
51643 function operationStraighten(selectedIDs, context) {
51644 var entityId = selectedIDs[0],
51645 action = actionStraighten(entityId, context.projection);
51648 function operation() {
51649 var annotation = t('operations.straighten.annotation');
51650 context.perform(action, annotation);
51654 operation.available = function() {
51655 var entity = context.entity(entityId);
51656 return selectedIDs.length === 1 &&
51657 entity.type === 'way' &&
51658 !entity.isClosed() &&
51659 lodash.uniq(entity.nodes).length > 2;
51663 operation.disabled = function() {
51665 if (context.hasHiddenConnections(entityId)) {
51666 reason = 'connected_to_hidden';
51668 return action.disabled(context.graph()) || reason;
51672 operation.tooltip = function() {
51673 var disable = operation.disabled();
51675 t('operations.straighten.' + disable) :
51676 t('operations.straighten.description');
51680 operation.id = 'straighten';
51681 operation.keys = [t('operations.straighten.key')];
51682 operation.title = t('operations.straighten.title');
51690 var Operations = Object.freeze({
51691 operationCircularize: operationCircularize,
51692 operationContinue: operationContinue,
51693 operationDelete: operationDelete,
51694 operationDisconnect: operationDisconnect,
51695 operationMerge: operationMerge,
51696 operationMove: operationMove,
51697 operationOrthogonalize: operationOrthogonalize,
51698 operationReverse: operationReverse,
51699 operationRotate: operationRotate,
51700 operationSplit: operationSplit,
51701 operationStraighten: operationStraighten
51704 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
51705 // For example, ⌘Z -> Ctrl+Z
51706 function uiCmd(code) {
51707 var detected = utilDetect();
51709 if (detected.os === 'mac') {
51713 if (detected.os === 'win') {
51714 if (code === '⌘⇧Z') return 'Ctrl+Y';
51726 for (var i = 0; i < code.length; i++) {
51727 if (code[i] in replacements) {
51728 result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
51740 function modeSelect(context, selectedIDs) {
51746 var keybinding = d3keybinding('select'),
51749 behaviorCopy(context),
51750 behaviorPaste(context),
51751 behaviorBreathe(context),
51752 behaviorHover(context),
51753 behaviorSelect(context),
51754 behaviorLasso(context),
51755 modeDragNode$$1(context).selectedIDs(selectedIDs).behavior
51759 newFeature = false,
51760 suppressMenu = false,
51764 var wrap = context.container()
51765 .select('.inspector-wrap');
51768 function singular() {
51769 if (selectedIDs.length === 1) {
51770 return context.hasEntity(selectedIDs[0]);
51775 function checkSelectedIDs() {
51777 if (Array.isArray(selectedIDs)) {
51778 ids = selectedIDs.filter(function(id) {
51779 return context.hasEntity(id);
51786 context.enter(modeBrowse$$1(context));
51788 return !!ids.length;
51792 // find the common parent ways for nextVertex, previousVertex
51793 function commonParents() {
51794 var graph = context.graph(),
51795 commonParents = [];
51797 for (var i = 0; i < selectedIDs.length; i++) {
51798 var entity = context.hasEntity(selectedIDs[i]);
51799 if (!entity || entity.geometry(graph) !== 'vertex') {
51800 return []; // selection includes some not vertexes
51803 var currParents = lodash.map(graph.parentWays(entity), 'id');
51804 if (!commonParents.length) {
51805 commonParents = currParents;
51809 commonParents = lodash.intersection(commonParents, currParents);
51810 if (!commonParents.length) {
51815 return commonParents;
51819 function singularParent() {
51820 var parents = commonParents();
51822 relatedParent = null;
51826 // relatedParent is used when we visit a vertex with multiple
51827 // parents, and we want to remember which parent line we started on.
51829 if (parents.length === 1) {
51830 relatedParent = parents[0]; // remember this parent for later
51831 return relatedParent;
51834 if (parents.indexOf(relatedParent) !== -1) {
51835 return relatedParent; // prefer the previously seen parent
51842 function closeMenu() {
51844 context.surface().call(radialMenu.close);
51849 function positionMenu() {
51850 if (suppressMenu || !radialMenu) { return; }
51852 var entity = singular();
51853 if (entity && context.geometry(entity.id) === 'relation') {
51854 suppressMenu = true;
51855 } else if (entity && entity.type === 'node') {
51856 radialMenu.center(context.projection(entity.loc));
51858 var point = context.mouse(),
51859 viewport = geoExtent$$1(context.projection.clipExtent()).polygon();
51860 if (geoPointInPolygon(point, viewport)) {
51861 radialMenu.center(point);
51863 suppressMenu = true;
51869 function showMenu() {
51871 if (!suppressMenu && radialMenu) {
51872 context.surface().call(radialMenu);
51877 function toggleMenu() {
51878 if (select('.radial-menu').empty()) {
51886 mode.selectedIDs = function() {
51887 return selectedIDs;
51891 mode.reselect = function() {
51892 if (!checkSelectedIDs()) return;
51894 var surfaceNode = context.surface().node();
51895 if (surfaceNode.focus) { // FF doesn't support it
51896 surfaceNode.focus();
51904 mode.newFeature = function(_) {
51905 if (!arguments.length) return newFeature;
51911 mode.suppressMenu = function(_) {
51912 if (!arguments.length) return suppressMenu;
51918 mode.follow = function(_) {
51919 if (!arguments.length) return follow;
51925 mode.enter = function() {
51927 function update() {
51929 checkSelectedIDs();
51933 function dblclick() {
51934 var target = select(event.target),
51935 datum = target.datum();
51937 if (datum instanceof osmWay && !target.classed('fill')) {
51938 var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
51941 var prev = datum.nodes[choice.index - 1],
51942 next = datum.nodes[choice.index];
51945 actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, node),
51946 t('operations.add.annotation.vertex')
51949 event.preventDefault();
51950 event.stopPropagation();
51955 function selectElements(drawn) {
51956 if (!checkSelectedIDs()) return;
51958 var surface = context.surface(),
51959 entity = singular();
51961 if (entity && context.geometry(entity.id) === 'relation') {
51962 suppressMenu = true;
51966 surface.selectAll('.related')
51967 .classed('related', false);
51970 if (relatedParent) {
51971 surface.selectAll(utilEntitySelector([relatedParent]))
51972 .classed('related', true);
51975 var selection$$1 = context.surface()
51976 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
51978 if (selection$$1.empty()) {
51979 // Return to browse mode if selected DOM elements have
51980 // disappeared because the user moved them out of view..
51981 var source = event && event.type === 'zoom' && event.sourceEvent;
51982 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
51983 context.enter(modeBrowse$$1(context));
51987 .classed('selected', true);
51993 if (!context.inIntro()) {
51994 context.enter(modeBrowse$$1(context));
51999 function firstVertex() {
52000 event.preventDefault();
52001 var parent = singularParent();
52003 var way = context.entity(parent);
52005 modeSelect(context, [way.first()]).follow(true).suppressMenu(true)
52011 function lastVertex() {
52012 event.preventDefault();
52013 var parent = singularParent();
52015 var way = context.entity(parent);
52017 modeSelect(context, [way.last()]).follow(true).suppressMenu(true)
52023 function previousVertex() {
52024 event.preventDefault();
52025 var parent = singularParent();
52026 if (!parent) return;
52028 var way = context.entity(parent),
52029 length = way.nodes.length,
52030 curr = way.nodes.indexOf(selectedIDs[0]),
52035 } else if (way.isClosed()) {
52036 index = length - 2;
52039 if (index !== -1) {
52041 modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
52047 function nextVertex() {
52048 event.preventDefault();
52049 var parent = singularParent();
52050 if (!parent) return;
52052 var way = context.entity(parent),
52053 length = way.nodes.length,
52054 curr = way.nodes.indexOf(selectedIDs[0]),
52057 if (curr < length - 1) {
52059 } else if (way.isClosed()) {
52063 if (index !== -1) {
52065 modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
52071 function nextParent() {
52072 event.preventDefault();
52073 var parents = lodash.uniq(commonParents());
52074 if (!parents || parents.length < 2) return;
52076 var index = parents.indexOf(relatedParent);
52077 if (index < 0 || index > parents.length - 2) {
52078 relatedParent = parents[0];
52080 relatedParent = parents[index + 1];
52083 var surface = context.surface();
52084 surface.selectAll('.related')
52085 .classed('related', false);
52087 if (relatedParent) {
52088 surface.selectAll(utilEntitySelector([relatedParent]))
52089 .classed('related', true);
52094 if (!checkSelectedIDs()) return;
52096 behaviors.forEach(function(behavior) {
52097 context.install(behavior);
52100 var operations = lodash.without(values(Operations), operationDelete)
52101 .map(function(o) { return o(selectedIDs, context); })
52102 .filter(function(o) { return o.available(); });
52104 operations.unshift(operationDelete(selectedIDs, context));
52107 .on(['[','pgup'], previousVertex)
52108 .on([']', 'pgdown'], nextVertex)
52109 .on([uiCmd('⌘['), 'home'], firstVertex)
52110 .on([uiCmd('⌘]'), 'end'], lastVertex)
52111 .on(['\\', 'pause'], nextParent)
52112 .on('⎋', esc, true)
52113 .on('space', toggleMenu);
52115 operations.forEach(function(operation) {
52116 operation.keys.forEach(function(key) {
52117 keybinding.on(key, function() {
52118 if (!(context.inIntro() || operation.disabled())) {
52128 radialMenu = uiRadialMenu(context, operations);
52130 context.ui().sidebar
52131 .select(singular() ? singular().id : null, newFeature);
52134 .on('undone.select', update)
52135 .on('redone.select', update);
52138 .on('move.select', closeMenu)
52139 .on('drawn.select', selectElements);
52143 var show = event && !suppressMenu;
52150 var extent$$1 = geoExtent$$1(),
52151 graph = context.graph();
52152 selectedIDs.forEach(function(id) {
52153 var entity = context.entity(id);
52154 extent$$1._extend(entity.extent(graph));
52157 var loc = extent$$1.center();
52158 context.map().centerEase(loc);
52161 timeout$$1 = window.setTimeout(function() {
52167 .on('dblclick.select', dblclick);
52170 if (selectedIDs.length > 1) {
52171 var entities = uiSelectionList(context, selectedIDs);
52172 context.ui().sidebar.show(entities);
52177 mode.exit = function() {
52178 if (timeout$$1) window.clearTimeout(timeout$$1);
52180 if (inspector) wrap.call(inspector.close);
52182 behaviors.forEach(function(behavior) {
52183 context.uninstall(behavior);
52188 radialMenu = undefined;
52191 .on('undone.select', null)
52192 .on('redone.select', null);
52194 var surface = context.surface();
52197 .on('dblclick.select', null);
52200 .selectAll('.selected')
52201 .classed('selected', false);
52204 .selectAll('.related')
52205 .classed('related', false);
52207 context.map().on('drawn.select', null);
52208 context.ui().sidebar.hide();
52215 function uiAccount(context) {
52216 var connection = context.connection();
52219 function update(selection$$1) {
52220 if (!connection.authenticated()) {
52221 selection$$1.selectAll('#userLink, #logoutLink')
52222 .classed('hide', true);
52226 connection.userDetails(function(err, details) {
52227 var userLink = selection$$1.select('#userLink'),
52228 logoutLink = selection$$1.select('#logoutLink');
52231 logoutLink.html('');
52235 selection$$1.selectAll('#userLink, #logoutLink')
52236 .classed('hide', false);
52239 userLink.append('a')
52240 .attr('href', connection.userURL(details.display_name))
52241 .attr('target', '_blank');
52243 // Add thumbnail or dont
52244 if (details.image_url) {
52245 userLink.append('img')
52246 .attr('class', 'icon pre-text user-icon')
52247 .attr('src', details.image_url);
52250 .call(svgIcon('#icon-avatar', 'pre-text light'));
52254 userLink.append('span')
52255 .attr('class', 'label')
52256 .text(details.display_name);
52258 logoutLink.append('a')
52259 .attr('class', 'logout')
52262 .on('click.logout', function() {
52263 event.preventDefault();
52264 connection.logout();
52270 return function(selection$$1) {
52271 selection$$1.append('li')
52272 .attr('id', 'logoutLink')
52273 .classed('hide', true);
52275 selection$$1.append('li')
52276 .attr('id', 'userLink')
52277 .classed('hide', true);
52280 .on('change.account', function() { update(selection$$1); });
52282 update(selection$$1);
52286 function uiAttribution(context) {
52290 function attribution(data, klass) {
52291 var div = selection$$1.selectAll('.' + klass)
52296 .attr('class', klass)
52300 var background = div.selectAll('.attribution')
52301 .data(data, function(d) { return d.name(); });
52306 background = background.enter()
52308 .attr('class', 'attribution')
52309 .each(function(d) {
52310 if (d.terms_html) {
52312 .html(d.terms_html);
52316 var source = d.terms_text || d.id || d.name();
52319 source = '<img class="source-image" src="' + context.imagePath(d.logo) + '">';
52325 .attr('href', d.terms_url)
52326 .attr('target', '_blank')
52333 .merge(background);
52336 var copyright = background.selectAll('.copyright-notice')
52337 .data(function(d) {
52338 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
52339 return notice ? [notice] : [];
52345 copyright = copyright.enter()
52347 .attr('class', 'copyright-notice')
52355 function update() {
52356 attribution([context.background().baseLayerSource()], 'base-layer-attribution');
52357 attribution(context.background().overlayLayerSources().filter(function (s) {
52358 return s.validZoom(context.map().zoom());
52359 }), 'overlay-layer-attribution');
52363 return function(select$$1) {
52364 selection$$1 = select$$1;
52366 context.background()
52367 .on('change.attribution', update);
52370 .on('move.attribution', lodash.throttle(update, 400, {leading: false}));
52376 function rendererBackgroundSource(data) {
52377 var source = lodash.clone(data),
52379 name = source.name,
52380 best = !!source.best;
52382 source.scaleExtent = data.scaleExtent || [0, 20];
52383 source.overzoom = data.overzoom !== false;
52386 source.offset = function(_) {
52387 if (!arguments.length) return offset;
52393 source.nudge = function(_, zoomlevel) {
52394 offset[0] += _[0] / Math.pow(2, zoomlevel);
52395 offset[1] += _[1] / Math.pow(2, zoomlevel);
52400 source.name = function() {
52405 source.best = function() {
52410 source.area = function() {
52411 if (!data.polygon) return Number.MAX_VALUE; // worldwide
52412 var area$$1 = area$1({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
52413 return isNaN(area$$1) ? 0 : area$$1;
52417 source.imageryUsed = function() {
52418 return name || source.id;
52422 source.url = function(coord) {
52423 return data.template
52424 .replace('{x}', coord[0])
52425 .replace('{y}', coord[1])
52426 // TMS-flipped y coordinate
52427 .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
52428 .replace(/\{z(oom)?\}/, coord[2])
52429 .replace(/\{switch:([^}]+)\}/, function(s, r) {
52430 var subdomains = r.split(',');
52431 return subdomains[(coord[0] + coord[1]) % subdomains.length];
52433 .replace('{u}', function() {
52435 for (var zoom$$1 = coord[2]; zoom$$1 > 0; zoom$$1--) {
52437 var mask = 1 << (zoom$$1 - 1);
52438 if ((coord[0] & mask) !== 0) b++;
52439 if ((coord[1] & mask) !== 0) b += 2;
52447 source.intersects = function(extent$$1) {
52448 extent$$1 = extent$$1.polygon();
52449 return !data.polygon || data.polygon.some(function(polygon) {
52450 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
52455 source.validZoom = function(z) {
52456 return source.scaleExtent[0] <= z &&
52457 (source.overzoom || source.scaleExtent[1] > z);
52461 source.isLocatorOverlay = function() {
52462 return source.id === 'mapbox_locator_overlay';
52466 source.copyrightNotices = function() {};
52473 rendererBackgroundSource.Bing = function(data, dispatch$$1) {
52474 // http://msdn.microsoft.com/en-us/library/ff701716.aspx
52475 // http://msdn.microsoft.com/en-us/library/ff701701.aspx
52477 data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
52479 var bing = rendererBackgroundSource(data),
52480 key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
52481 url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
52482 key + '&jsonp={callback}',
52485 jsonpRequest(url, function(json$$1) {
52486 providers = json$$1.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
52488 attribution: provider.attribution,
52489 areas: provider.coverageAreas.map(function(area$$1) {
52491 zoom: [area$$1.zoomMin, area$$1.zoomMax],
52492 extent: geoExtent$$1([area$$1.bbox[1], area$$1.bbox[0]], [area$$1.bbox[3], area$$1.bbox[2]])
52497 dispatch$$1.call('change');
52500 bing.copyrightNotices = function(zoom$$1, extent$$1) {
52501 zoom$$1 = Math.min(zoom$$1, 21);
52502 return providers.filter(function(provider) {
52503 return lodash.some(provider.areas, function(area$$1) {
52504 return extent$$1.intersects(area$$1.extent) &&
52505 area$$1.zoom[0] <= zoom$$1 &&
52506 area$$1.zoom[1] >= zoom$$1;
52508 }).map(function(provider) {
52509 return provider.attribution;
52513 bing.logo = 'bing_maps.png';
52514 bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
52520 rendererBackgroundSource.None = function() {
52521 var source = rendererBackgroundSource({ id: 'none', template: '' });
52523 source.name = function() {
52524 return t('background.none');
52527 source.imageryUsed = function() {
52531 source.area = function() {
52532 return -1; // sources in background pane are sorted by area
52539 rendererBackgroundSource.Custom = function(template) {
52540 var source = rendererBackgroundSource({ id: 'custom', template: template });
52542 source.name = function() {
52543 return t('background.custom');
52546 source.imageryUsed = function() {
52547 return 'Custom (' + template + ')';
52550 source.area = function() {
52551 return -2; // sources in background pane are sorted by area
52557 function rendererTileLayer(context) {
52558 var tileSize = 256,
52559 tile = d3geoTile(),
52564 transformProp = utilPrefixCSSProperty('Transform'),
52565 source = rendererBackgroundSource.None();
52568 // blacklist overlay tiles around Null Island..
52569 function nearNullIsland(x, y, z) {
52571 var center = Math.pow(2, z - 1),
52572 width = Math.pow(2, z - 6),
52573 min$$1 = center - (width / 2),
52574 max$$1 = center + (width / 2) - 1;
52575 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
52581 function tileSizeAtZoom(d, z) {
52582 var epsilon = 0.002;
52583 return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + epsilon;
52587 function atZoom(t, distance) {
52588 var power = Math.pow(2, distance);
52590 Math.floor(t[0] * power),
52591 Math.floor(t[1] * power),
52596 function lookUp(d) {
52597 for (var up = -1; up > -d[2]; up--) {
52598 var tile = atZoom(d, up);
52599 if (cache[source.url(tile)] !== false) {
52606 function uniqueBy(a, n) {
52607 var o = [], seen = {};
52608 for (var i = 0; i < a.length; i++) {
52609 if (seen[a[i][n]] === undefined) {
52611 seen[a[i][n]] = true;
52618 function addSource(d) {
52619 d.push(source.url(d));
52624 // Update tiles based on current state of `projection`.
52625 function background(selection$$1) {
52626 tile.scale(projection.scale() * 2 * Math.PI)
52627 .translate(projection.translate());
52630 projection.scale() * Math.PI - projection.translate()[0],
52631 projection.scale() * Math.PI - projection.translate()[1]];
52633 z = Math.max(Math.log(projection.scale() * 2 * Math.PI) / Math.log(2) - 8, 0);
52635 render(selection$$1);
52639 // Derive the tiles onscreen, remove those offscreen and position them.
52640 // Important that this part not depend on `projection` because it's
52641 // rentered when tiles load/error (see #644).
52642 function render(selection$$1) {
52644 var showDebug = context.getDebug('tile') && !source.overlay;
52646 if (source.validZoom(z)) {
52647 tile().forEach(function(d) {
52649 if (d[3] === '') return;
52650 if (typeof d[3] !== 'string') return; // Workaround for chrome crash https://github.com/openstreetmap/iD/issues/2295
52652 if (cache[d[3]] === false && lookUp(d)) {
52653 requests.push(addSource(lookUp(d)));
52657 requests = uniqueBy(requests, 3).filter(function(r) {
52658 if (!!source.overlay && nearNullIsland(r[0], r[1], r[2])) {
52661 // don't re-request tiles which have failed in the past
52662 return cache[r[3]] !== false;
52666 var pixelOffset = [
52667 source.offset()[0] * Math.pow(2, z),
52668 source.offset()[1] * Math.pow(2, z)
52672 cache[d[3]] = true;
52676 .classed('tile-loaded', true);
52677 render(selection$$1);
52680 function error(d) {
52681 cache[d[3]] = false;
52686 render(selection$$1);
52689 function imageTransform(d) {
52690 var _ts = tileSize * Math.pow(2, z - d[2]);
52691 var scale = tileSizeAtZoom(d, z);
52692 return 'translate(' +
52693 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0]) + 'px,' +
52694 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1]) + 'px)' +
52695 'scale(' + scale + ',' + scale + ')';
52698 function debugTransform(d) {
52699 var _ts = tileSize * Math.pow(2, z - d[2]);
52700 var scale = tileSizeAtZoom(d, z);
52701 return 'translate(' +
52702 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0] + scale * (tileSize / 4)) + 'px,' +
52703 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1] + scale * (tileSize / 2)) + 'px)';
52707 var image = selection$$1.selectAll('img')
52708 .data(requests, function(d) { return d[3]; });
52711 .style(transformProp, imageTransform)
52712 .classed('tile-removing', true)
52714 var tile = select(this);
52715 window.setTimeout(function() {
52716 if (tile.classed('tile-removing')) {
52724 .attr('class', 'tile')
52725 .attr('src', function(d) { return d[3]; })
52726 .on('error', error)
52729 .style(transformProp, imageTransform)
52730 .classed('tile-debug', showDebug)
52731 .classed('tile-removing', false);
52734 var debug = selection$$1.selectAll('.tile-label-debug')
52735 .data(showDebug ? requests : [], function(d) { return d[3]; });
52742 .attr('class', 'tile-label-debug')
52744 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; })
52745 .style(transformProp, debugTransform);
52749 background.projection = function(_) {
52750 if (!arguments.length) return projection;
52756 background.dimensions = function(_) {
52757 if (!arguments.length) return tile.size();
52763 background.source = function(_) {
52764 if (!arguments.length) return source;
52767 tile.scaleExtent(source.scaleExtent);
52775 function rendererBackground(context) {
52776 var dispatch$$1 = dispatch('change'),
52777 baseLayer = rendererTileLayer(context).projection(context.projection),
52778 overlayLayers = [],
52782 function findSource(id) {
52783 return lodash.find(backgroundSources, function(d) {
52784 return d.id && d.id === id;
52789 function background(selection$$1) {
52790 var base = selection$$1.selectAll('.layer-background')
52794 .insert('div', '.layer-data')
52795 .attr('class', 'layer layer-background')
52799 var overlays = selection$$1.selectAll('.layer-overlay')
52800 .data(overlayLayers, function(d) { return d.source().name(); });
52806 .insert('div', '.layer-data')
52807 .attr('class', 'layer layer-overlay')
52809 .each(function(layer) { select(this).call(layer); });
52813 background.updateImagery = function() {
52814 var b = background.baseLayerSource(),
52816 .filter(function (d) { return !d.source().isLocatorOverlay(); })
52817 .map(function (d) { return d.source().id; })
52819 meters = geoOffsetToMeters(b.offset()),
52821 x = +meters[0].toFixed(2),
52822 y = +meters[1].toFixed(2),
52823 q = utilStringQs(window.location.hash.substring(1));
52826 if (id === 'custom') {
52827 id = 'custom:' + b.template;
52833 delete q.background;
52842 if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
52843 q.offset = x + ',' + y;
52848 window.location.replace('#' + utilQsString(q, true));
52850 var imageryUsed = [b.imageryUsed()];
52853 .filter(function (d) { return !d.source().isLocatorOverlay(); })
52854 .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
52856 var gpx = context.layers().layer('gpx');
52857 if (gpx && gpx.enabled() && gpx.hasGpx()) {
52858 imageryUsed.push('Local GPX');
52861 var mapillary_images = context.layers().layer('mapillary-images');
52862 if (mapillary_images && mapillary_images.enabled()) {
52863 imageryUsed.push('Mapillary Images');
52866 var mapillary_signs = context.layers().layer('mapillary-signs');
52867 if (mapillary_signs && mapillary_signs.enabled()) {
52868 imageryUsed.push('Mapillary Signs');
52871 context.history().imageryUsed(imageryUsed);
52875 background.sources = function(extent$$1) {
52876 return backgroundSources.filter(function(source) {
52877 return source.intersects(extent$$1);
52882 background.dimensions = function(_) {
52884 baseLayer.dimensions(_);
52886 overlayLayers.forEach(function(layer) {
52887 layer.dimensions(_);
52892 background.baseLayerSource = function(d) {
52893 if (!arguments.length) return baseLayer.source();
52895 // test source against OSM imagery blacklists..
52896 var blacklists = context.connection().imageryBlacklists();
52902 for (i = 0; i < blacklists; i++) {
52904 regex = new RegExp(blacklists[i]);
52905 fail = regex.test(d.template);
52913 // ensure at least one test was run.
52915 regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
52916 fail = regex.test(d.template);
52919 baseLayer.source(!fail ? d : rendererBackgroundSource.None());
52920 dispatch$$1.call('change');
52921 background.updateImagery();
52926 background.bing = function() {
52927 background.baseLayerSource(findSource('Bing'));
52931 background.showsLayer = function(d) {
52932 return d.id === baseLayer.source().id ||
52933 overlayLayers.some(function(layer) { return d.id === layer.source().id; });
52937 background.overlayLayerSources = function() {
52938 return overlayLayers.map(function (l) { return l.source(); });
52942 background.toggleOverlayLayer = function(d) {
52945 for (var i = 0; i < overlayLayers.length; i++) {
52946 layer = overlayLayers[i];
52947 if (layer.source() === d) {
52948 overlayLayers.splice(i, 1);
52949 dispatch$$1.call('change');
52950 background.updateImagery();
52955 layer = rendererTileLayer(context)
52957 .projection(context.projection)
52958 .dimensions(baseLayer.dimensions());
52960 overlayLayers.push(layer);
52961 dispatch$$1.call('change');
52962 background.updateImagery();
52966 background.nudge = function(d, zoom$$1) {
52967 baseLayer.source().nudge(d, zoom$$1);
52968 dispatch$$1.call('change');
52969 background.updateImagery();
52974 background.offset = function(d) {
52975 if (!arguments.length) return baseLayer.source().offset();
52976 baseLayer.source().offset(d);
52977 dispatch$$1.call('change');
52978 background.updateImagery();
52983 background.init = function() {
52984 function parseMap(qmap) {
52985 if (!qmap) return false;
52986 var args = qmap.split('/').map(Number);
52987 if (args.length < 3 || args.some(isNaN)) return false;
52988 return geoExtent$$1([args[2], args[1]]);
52991 var dataImagery = data.imagery || [],
52992 q = utilStringQs(window.location.hash.substring(1)),
52993 chosen = q.background || q.layer,
52994 extent$$1 = parseMap(q.map),
52997 backgroundSources = dataImagery.map(function(source) {
52998 if (source.type === 'bing') {
52999 return rendererBackgroundSource.Bing(source, dispatch$$1);
53001 return rendererBackgroundSource(source);
53005 backgroundSources.unshift(rendererBackgroundSource.None());
53007 if (!chosen && extent$$1) {
53008 best = lodash.find(this.sources(extent$$1), function(s) { return s.best(); });
53011 if (chosen && chosen.indexOf('custom:') === 0) {
53012 background.baseLayerSource(rendererBackgroundSource.Custom(chosen.replace(/^custom:/, '')));
53014 background.baseLayerSource(findSource(chosen) || best || findSource('Bing') || backgroundSources[1] || backgroundSources[0]);
53017 var locator = lodash.find(backgroundSources, function(d) {
53018 return d.overlay && d.default;
53022 background.toggleOverlayLayer(locator);
53025 var overlays = (q.overlays || '').split(',');
53026 overlays.forEach(function(overlay) {
53027 overlay = findSource(overlay);
53029 background.toggleOverlayLayer(overlay);
53034 var gpx = context.layers().layer('gpx');
53041 var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
53042 return !isNaN(n) && n;
53045 if (offset.length === 2) {
53046 background.offset(geoMetersToOffset(offset));
53052 return utilRebind(background, dispatch$$1, 'on');
53055 function rendererFeatures(context) {
53056 var traffic_roads = {
53058 'motorway_link': true,
53060 'trunk_link': true,
53062 'primary_link': true,
53064 'secondary_link': true,
53066 'tertiary_link': true,
53067 'residential': true,
53068 'unclassified': true,
53069 'living_street': true
53072 var service_roads = {
53084 'pedestrian': true,
53088 var past_futures = {
53090 'construction': true,
53092 'dismantled': true,
53095 'demolished': true,
53096 'obliterated': true
53099 var dispatch$$1 = dispatch('change', 'redraw'),
53108 function update() {
53109 _hidden = features.hidden();
53110 dispatch$$1.call('change');
53111 dispatch$$1.call('redraw');
53115 function defineFeature(k, filter, max$$1) {
53119 enabled: true, // whether the user wants it enabled..
53121 currentMax: (max$$1 || Infinity),
53122 defaultMax: (max$$1 || Infinity),
53123 enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
53124 disable: function() { this.enabled = false; this.currentMax = 0; },
53125 hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
53126 autoHidden: function() { return this.hidden() && this.currentMax > 0; }
53131 defineFeature('points', function isPoint(entity, resolver, geometry) {
53132 return geometry === 'point';
53135 defineFeature('traffic_roads', function isTrafficRoad(entity) {
53136 return traffic_roads[entity.tags.highway];
53139 defineFeature('service_roads', function isServiceRoad(entity) {
53140 return service_roads[entity.tags.highway];
53143 defineFeature('paths', function isPath(entity) {
53144 return paths[entity.tags.highway];
53147 defineFeature('buildings', function isBuilding(entity) {
53149 !!entity.tags['building:part'] ||
53150 (!!entity.tags.building && entity.tags.building !== 'no') ||
53151 entity.tags.amenity === 'shelter' ||
53152 entity.tags.parking === 'multi-storey' ||
53153 entity.tags.parking === 'sheds' ||
53154 entity.tags.parking === 'carports' ||
53155 entity.tags.parking === 'garage_boxes'
53159 defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
53160 return geometry === 'area' &&
53161 !_features.buildings.filter(entity) &&
53162 !_features.water.filter(entity);
53165 defineFeature('boundaries', function isBoundary(entity) {
53166 return !!entity.tags.boundary;
53169 defineFeature('water', function isWater(entity) {
53171 !!entity.tags.waterway ||
53172 entity.tags.natural === 'water' ||
53173 entity.tags.natural === 'coastline' ||
53174 entity.tags.natural === 'bay' ||
53175 entity.tags.landuse === 'pond' ||
53176 entity.tags.landuse === 'basin' ||
53177 entity.tags.landuse === 'reservoir' ||
53178 entity.tags.landuse === 'salt_pond'
53182 defineFeature('rail', function isRail(entity) {
53184 !!entity.tags.railway ||
53185 entity.tags.landuse === 'railway'
53187 traffic_roads[entity.tags.highway] ||
53188 service_roads[entity.tags.highway] ||
53189 paths[entity.tags.highway]
53193 defineFeature('power', function isPower(entity) {
53194 return !!entity.tags.power;
53197 // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
53198 defineFeature('past_future', function isPastFuture(entity) {
53200 traffic_roads[entity.tags.highway] ||
53201 service_roads[entity.tags.highway] ||
53202 paths[entity.tags.highway]
53203 ) { return false; }
53205 var strings = Object.keys(entity.tags);
53207 for (var i = 0; i < strings.length; i++) {
53208 var s = strings[i];
53209 if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
53214 // Lines or areas that don't match another feature filter.
53215 // IMPORTANT: The 'others' feature must be the last one defined,
53216 // so that code in getMatches can skip this test if `hasMatch = true`
53217 defineFeature('others', function isOther(entity, resolver, geometry) {
53218 return (geometry === 'line' || geometry === 'area');
53222 function features() {}
53225 features.features = function() {
53230 features.keys = function() {
53235 features.enabled = function(k) {
53236 if (!arguments.length) {
53237 return _keys.filter(function(k) { return _features[k].enabled; });
53239 return _features[k] && _features[k].enabled;
53243 features.disabled = function(k) {
53244 if (!arguments.length) {
53245 return _keys.filter(function(k) { return !_features[k].enabled; });
53247 return _features[k] && !_features[k].enabled;
53251 features.hidden = function(k) {
53252 if (!arguments.length) {
53253 return _keys.filter(function(k) { return _features[k].hidden(); });
53255 return _features[k] && _features[k].hidden();
53259 features.autoHidden = function(k) {
53260 if (!arguments.length) {
53261 return _keys.filter(function(k) { return _features[k].autoHidden(); });
53263 return _features[k] && _features[k].autoHidden();
53267 features.enable = function(k) {
53268 if (_features[k] && !_features[k].enabled) {
53269 _features[k].enable();
53275 features.disable = function(k) {
53276 if (_features[k] && _features[k].enabled) {
53277 _features[k].disable();
53283 features.toggle = function(k) {
53284 if (_features[k]) {
53285 (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
53291 features.resetStats = function() {
53292 for (var i = 0; i < _keys.length; i++) {
53293 _features[_keys[i]].count = 0;
53295 dispatch$$1.call('change');
53299 features.gatherStats = function(d, resolver, dimensions) {
53300 var needsRedraw = false,
53301 type = lodash.groupBy(d, function(ent) { return ent.type; }),
53302 entities = [].concat(type.relation || [], type.way || [], type.node || []),
53303 currHidden, geometry, matches, i, j;
53305 for (i = 0; i < _keys.length; i++) {
53306 _features[_keys[i]].count = 0;
53309 // adjust the threshold for point/building culling based on viewport size..
53310 // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
53311 _cullFactor = dimensions[0] * dimensions[1] / 1000000;
53313 for (i = 0; i < entities.length; i++) {
53314 geometry = entities[i].geometry(resolver);
53315 if (!(geometry === 'vertex' || geometry === 'relation')) {
53316 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
53317 for (j = 0; j < matches.length; j++) {
53318 _features[matches[j]].count++;
53323 currHidden = features.hidden();
53324 if (currHidden !== _hidden) {
53325 _hidden = currHidden;
53326 needsRedraw = true;
53327 dispatch$$1.call('change');
53330 return needsRedraw;
53334 features.stats = function() {
53335 for (var i = 0; i < _keys.length; i++) {
53336 _stats[_keys[i]] = _features[_keys[i]].count;
53343 features.clear = function(d) {
53344 for (var i = 0; i < d.length; i++) {
53345 features.clearEntity(d[i]);
53350 features.clearEntity = function(entity) {
53351 delete _cache[osmEntity$$1.key(entity)];
53355 features.reset = function() {
53360 features.getMatches = function(entity, resolver, geometry) {
53361 if (geometry === 'vertex' || geometry === 'relation') return {};
53363 var ent = osmEntity$$1.key(entity);
53364 if (!_cache[ent]) {
53368 if (!_cache[ent].matches) {
53372 for (var i = 0; i < _keys.length; i++) {
53373 if (_keys[i] === 'others') {
53374 if (hasMatch) continue;
53376 // Multipolygon members:
53378 // 1. is a way that hasn't matched other 'interesting' feature rules,
53379 // 2. and it belongs to a single parent multipolygon relation
53380 // ...then match whatever feature rules the parent multipolygon has matched.
53381 // see #2548, #2887
53384 // For this to work, getMatches must be called on relations before ways.
53386 if (entity.type === 'way') {
53387 var parents = features.getParents(entity, resolver, geometry);
53388 if (parents.length === 1 && parents[0].isMultipolygon()) {
53389 var pkey = osmEntity$$1.key(parents[0]);
53390 if (_cache[pkey] && _cache[pkey].matches) {
53391 matches = lodash.clone(_cache[pkey].matches);
53398 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
53399 matches[_keys[i]] = hasMatch = true;
53402 _cache[ent].matches = matches;
53405 return _cache[ent].matches;
53409 features.getParents = function(entity, resolver, geometry) {
53410 if (geometry === 'point') return [];
53412 var ent = osmEntity$$1.key(entity);
53413 if (!_cache[ent]) {
53417 if (!_cache[ent].parents) {
53419 if (geometry === 'vertex') {
53420 parents = resolver.parentWays(entity);
53421 } else { // 'line', 'area', 'relation'
53422 parents = resolver.parentRelations(entity);
53424 _cache[ent].parents = parents;
53426 return _cache[ent].parents;
53430 features.isHiddenFeature = function(entity, resolver, geometry) {
53431 if (!_hidden.length) return false;
53432 if (!entity.version) return false;
53434 var matches = features.getMatches(entity, resolver, geometry);
53436 for (var i = 0; i < _hidden.length; i++) {
53437 if (matches[_hidden[i]]) return true;
53443 features.isHiddenChild = function(entity, resolver, geometry) {
53444 if (!_hidden.length) return false;
53445 if (!entity.version || geometry === 'point') return false;
53447 var parents = features.getParents(entity, resolver, geometry);
53448 if (!parents.length) return false;
53450 for (var i = 0; i < parents.length; i++) {
53451 if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
53459 features.hasHiddenConnections = function(entity, resolver) {
53460 if (!_hidden.length) return false;
53461 var childNodes, connections;
53463 if (entity.type === 'midpoint') {
53464 childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
53467 childNodes = entity.nodes ? resolver.childNodes(entity) : [];
53468 connections = features.getParents(entity, resolver, entity.geometry(resolver));
53471 // gather ways connected to child nodes..
53472 connections = lodash.reduce(childNodes, function(result, e) {
53473 return resolver.isShared(e) ? lodash.union(result, resolver.parentWays(e)) : result;
53476 return connections.length ? lodash.some(connections, function(e) {
53477 return features.isHidden(e, resolver, e.geometry(resolver));
53482 features.isHidden = function(entity, resolver, geometry) {
53483 if (!_hidden.length) return false;
53484 if (!entity.version) return false;
53486 var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
53487 return fn(entity, resolver, geometry);
53491 features.filter = function(d, resolver) {
53492 if (!_hidden.length) return d;
53495 for (var i = 0; i < d.length; i++) {
53497 if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
53498 result.push(entity);
53505 return utilRebind(features, dispatch$$1, 'on');
53508 function utilBindOnce(target, type, listener, capture) {
53509 var typeOnce = type + '.once';
53511 target.on(typeOnce, null);
53512 listener.apply(this, arguments);
53514 target.on(typeOnce, one, capture);
53518 function rendererMap(context) {
53520 var dimensions = [1, 1],
53521 dispatch$$1 = dispatch('move', 'drawn'),
53522 projection = context.projection,
53523 dblclickEnabled = true,
53524 redrawEnabled = true,
53525 transformStart = projection.transform(),
53526 transformed = false,
53528 drawLayers = svgLayers(projection, context),
53529 drawPoints = svgPoints$$1(projection, context),
53530 drawVertices = svgVertices$$1(projection, context),
53531 drawLines = svgLines$$1(projection),
53532 drawAreas = svgAreas$$1(projection, context),
53533 drawMidpoints = svgMidpoints$$1(projection, context),
53534 drawLabels = svgLabels(projection, context),
53535 supersurface = select(null),
53536 wrapper = select(null),
53537 surface = select(null),
53541 var zoom$$1 = zoom()
53542 .scaleExtent([ztok(2), ztok(24)])
53543 .interpolate(interpolate)
53544 .filter(zoomEventFilter)
53545 .on('zoom', zoomPan);
53547 var _selection = select(null);
53550 function map$$1(selection$$1) {
53552 _selection = selection$$1;
53555 .on('change.map', immediateRedraw);
53557 context.connection()
53558 .on('change.map', immediateRedraw);
53561 .on('change.map', immediateRedraw)
53562 .on('undone.context redone.context', function(stack$$1) {
53563 var followSelected = false;
53564 if (Array.isArray(stack$$1.selectedIDs)) {
53565 followSelected = (stack$$1.selectedIDs.length === 1 && stack$$1.selectedIDs[0][0] === 'n');
53567 modeSelect(context, stack$$1.selectedIDs).suppressMenu(true).follow(followSelected)
53570 if (!followSelected && stack$$1.transform) {
53571 map$$1.transformEase(stack$$1.transform);
53575 context.background()
53576 .on('change.map', immediateRedraw);
53579 .on('redraw.map', immediateRedraw);
53582 .on('change.map', function() {
53583 context.background().updateImagery();
53588 .on('dblclick.map', dblClick)
53589 .call(zoom$$1, projection.transform());
53591 supersurface = selection$$1.append('div')
53592 .attr('id', 'supersurface')
53593 .call(utilSetTransform, 0, 0);
53595 // Need a wrapper div because Opera can't cope with an absolutely positioned
53596 // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
53597 wrapper = supersurface
53599 .attr('class', 'layer layer-data');
53601 map$$1.surface = surface = wrapper
53603 .selectAll('.surface')
53604 .attr('id', 'surface');
53607 .call(drawLabels.observe)
53608 .on('mousedown.zoom', function() {
53609 if (event.button === 2) {
53610 event.stopPropagation();
53613 .on('mouseup.zoom', function() {
53614 if (resetTransform()) immediateRedraw();
53616 .on('mousemove.map', function() {
53619 .on('mouseover.vertices', function() {
53620 if (map$$1.editable() && !transformed) {
53621 var hover = event.target.__data__;
53622 surface.selectAll('.data-layer-osm')
53623 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
53624 dispatch$$1.call('drawn', this, {full: false});
53627 .on('mouseout.vertices', function() {
53628 if (map$$1.editable() && !transformed) {
53629 var hover = event.relatedTarget && event.relatedTarget.__data__;
53630 surface.selectAll('.data-layer-osm')
53631 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
53632 dispatch$$1.call('drawn', this, {full: false});
53637 .call(context.background());
53639 context.on('enter.map', function() {
53640 if (map$$1.editable() && !transformed) {
53641 var all = context.intersects(map$$1.extent()),
53642 filter = utilFunctor(true),
53643 graph = context.graph();
53645 all = context.features().filter(all, graph);
53646 surface.selectAll('.data-layer-osm')
53647 .call(drawVertices, graph, all, filter, map$$1.extent(), map$$1.zoom())
53648 .call(drawMidpoints, graph, all, filter, map$$1.trimmedExtent());
53649 dispatch$$1.call('drawn', this, {full: false});
53653 map$$1.dimensions(utilGetDimensions(selection$$1));
53657 function zoomEventFilter() {
53658 // Fix for #2151, (see also d3/d3-zoom#60, d3/d3-brush#18)
53659 // Intercept `mousedown` and check if there is an orphaned zoom gesture.
53660 // This can happen if a previous `mousedown` occurred without a `mouseup`.
53661 // If we detect this, dispatch `mouseup` to complete the orphaned gesture,
53662 // so that d3-zoom won't stop propagation of new `mousedown` events.
53663 if (event.type === 'mousedown') {
53664 var hasOrphan = false;
53665 var listeners = window.__on;
53666 for (var i = 0; i < listeners.length; i++) {
53667 var listener = listeners[i];
53668 if (listener.name === 'zoom' && listener.type === 'mouseup') {
53674 var event$$1 = window.CustomEvent;
53676 event$$1 = new event$$1('mouseup');
53678 event$$1 = window.document.createEvent('Event');
53679 event$$1.initEvent('mouseup', false, false);
53681 // Event needs to be dispatched with an event.view property.
53682 event$$1.view = window;
53683 window.dispatchEvent(event$$1);
53687 return event.button !== 2; // ignore right clicks
53692 return 256 * Math.pow(2, z);
53696 return Math.max(Math.log(k) / Math.LN2 - 8, 0);
53699 function pxCenter() {
53700 return [dimensions[0] / 2, dimensions[1] / 2];
53704 function drawVector(difference, extent$$1) {
53705 var graph = context.graph(),
53706 features = context.features(),
53707 all = context.intersects(map$$1.extent()),
53711 var complete = difference.complete(map$$1.extent());
53712 data = lodash.compact(lodash.values(complete));
53713 filter = function(d) { return d.id in complete; };
53714 features.clear(data);
53717 // force a full redraw if gatherStats detects that a feature
53718 // should be auto-hidden (e.g. points or buildings)..
53719 if (features.gatherStats(all, graph, dimensions)) {
53720 extent$$1 = undefined;
53724 data = context.intersects(map$$1.extent().intersection(extent$$1));
53725 var set$$1 = set(lodash.map(data, 'id'));
53726 filter = function(d) { return set$$1.has(d.id); };
53730 filter = utilFunctor(true);
53734 data = features.filter(data, graph);
53736 surface.selectAll('.data-layer-osm')
53737 .call(drawVertices, graph, data, filter, map$$1.extent(), map$$1.zoom())
53738 .call(drawLines, graph, data, filter)
53739 .call(drawAreas, graph, data, filter)
53740 .call(drawMidpoints, graph, data, filter, map$$1.trimmedExtent())
53741 .call(drawLabels, graph, data, filter, dimensions, !difference && !extent$$1)
53742 .call(drawPoints, graph, data, filter);
53744 dispatch$$1.call('drawn', this, {full: true});
53748 function editOff() {
53749 context.features().resetStats();
53750 surface.selectAll('.layer-osm *').remove();
53751 dispatch$$1.call('drawn', this, {full: true});
53755 function dblClick() {
53756 if (!dblclickEnabled) {
53757 event.preventDefault();
53758 event.stopImmediatePropagation();
53763 function zoomPan(manualEvent) {
53764 var eventTransform = (manualEvent || event).transform;
53766 if (transformStart.x === eventTransform.x &&
53767 transformStart.y === eventTransform.y &&
53768 transformStart.k === eventTransform.k) {
53769 return; // no change
53772 if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
53773 surface.interrupt();
53774 uiFlash(context.container())
53775 .select('.content')
53776 .text(t('cannot_zoom'));
53777 setZoom(context.minEditableZoom(), true);
53779 dispatch$$1.call('move', this, map$$1);
53783 projection.transform(eventTransform);
53785 var scale = eventTransform.k / transformStart.k,
53786 tX = (eventTransform.x / scale - transformStart.x) * scale,
53787 tY = (eventTransform.y / scale - transformStart.y) * scale;
53789 transformed = true;
53790 utilSetTransform(supersurface, tX, tY, scale);
53793 dispatch$$1.call('move', this, map$$1);
53797 function resetTransform() {
53798 if (!transformed) return false;
53800 surface.selectAll('.radial-menu').interrupt().remove();
53801 utilSetTransform(supersurface, 0, 0);
53802 transformed = false;
53807 function redraw(difference, extent$$1) {
53808 if (surface.empty() || !redrawEnabled) return;
53810 // If we are in the middle of a zoom/pan, we can't do differenced redraws.
53811 // It would result in artifacts where differenced entities are redrawn with
53812 // one transform and unchanged entities with another.
53813 if (resetTransform()) {
53814 difference = extent$$1 = undefined;
53817 var z = String(~~map$$1.zoom());
53818 if (surface.attr('data-zoom') !== z) {
53819 surface.attr('data-zoom', z)
53820 .classed('low-zoom', z <= 16);
53824 supersurface.call(context.background());
53831 if (map$$1.editable()) {
53832 context.loadTiles(projection, dimensions);
53833 drawVector(difference, extent$$1);
53838 transformStart = projection.transform();
53844 var queueRedraw = lodash.throttle(redraw, 750);
53847 var immediateRedraw = function(difference, extent$$1) {
53848 if (!difference && !extent$$1) queueRedraw.cancel();
53849 redraw(difference, extent$$1);
53853 function pointLocation(p) {
53854 var translate = projection.translate(),
53855 scale = projection.scale() * 2 * Math.PI;
53856 return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
53860 function locationPoint(l) {
53861 var translate = projection.translate(),
53862 scale = projection.scale() * 2 * Math.PI;
53863 return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
53867 map$$1.mouse = function() {
53868 var event$$1 = mousemove || event;
53871 while ((s = event$$1.sourceEvent)) { event$$1 = s; }
53872 return mouse$$1(event$$1);
53878 map$$1.mouseCoordinates = function() {
53879 return projection.invert(map$$1.mouse());
53883 map$$1.dblclickEnable = function(_) {
53884 if (!arguments.length) return dblclickEnabled;
53885 dblclickEnabled = _;
53890 map$$1.redrawEnable = function(_) {
53891 if (!arguments.length) return redrawEnabled;
53897 function setTransform(t2, duration, force) {
53898 var t$$1 = projection.transform();
53899 if (!force && t2.k === t$$1.k && t2.x === t$$1.x && t2.y === t$$1.y) {
53906 .duration(duration)
53907 .on('start', function() { map$$1.startEase(); })
53908 .call(zoom$$1.transform, identity$6.translate(t2.x, t2.y).scale(t2.k));
53910 projection.transform(t2);
53911 transformStart = t2;
53912 _selection.call(zoom$$1.transform, transformStart);
53917 function setZoom(z2, force, duration) {
53918 if (z2 === map$$1.zoom() && !force) {
53922 var k = projection.scale(),
53923 k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
53924 center = pxCenter(),
53925 l = pointLocation(center);
53927 projection.scale(k2);
53929 var t$$1 = projection.translate();
53930 l = locationPoint(l);
53932 t$$1[0] += center[0] - l[0];
53933 t$$1[1] += center[1] - l[1];
53936 projection.scale(k); // reset scale
53939 .duration(duration)
53940 .on('start', function() { map$$1.startEase(); })
53941 .call(zoom$$1.transform, identity$6.translate(t$$1[0], t$$1[1]).scale(k2));
53943 projection.translate(t$$1);
53944 transformStart = projection.transform();
53945 _selection.call(zoom$$1.transform, transformStart);
53952 function setCenter(loc2, duration) {
53953 var c = map$$1.center();
53954 if (loc2[0] === c[0] && loc2[1] === c[1]) {
53958 var t$$1 = projection.translate(),
53959 k = projection.scale(),
53961 ll = projection(loc2);
53963 t$$1[0] = t$$1[0] - ll[0] + pxC[0];
53964 t$$1[1] = t$$1[1] - ll[1] + pxC[1];
53969 .duration(duration)
53970 .on('start', function() { map$$1.startEase(); })
53971 .call(zoom$$1.transform, identity$6.translate(t$$1[0], t$$1[1]).scale(k));
53973 projection.translate(t$$1);
53974 transformStart = projection.transform();
53975 _selection.call(zoom$$1.transform, transformStart);
53982 map$$1.pan = function(delta, duration) {
53983 var t$$1 = projection.translate(),
53984 k = projection.scale();
53986 t$$1[0] += delta[0];
53987 t$$1[1] += delta[1];
53992 .duration(duration)
53993 .on('start', function() { map$$1.startEase(); })
53994 .call(zoom$$1.transform, identity$6.translate(t$$1[0], t$$1[1]).scale(k));
53996 projection.translate(t$$1);
53997 transformStart = projection.transform();
53998 _selection.call(zoom$$1.transform, transformStart);
53999 dispatch$$1.call('move', this, map$$1);
54007 map$$1.dimensions = function(_) {
54008 if (!arguments.length) return dimensions;
54009 var center = map$$1.center();
54011 drawLayers.dimensions(dimensions);
54012 context.background().dimensions(dimensions);
54013 projection.clipExtent([[0, 0], dimensions]);
54014 mouse$$1 = utilFastMouse(supersurface.node());
54022 function zoomIn(delta) {
54023 setZoom(~~map$$1.zoom() + delta, true, 250);
54026 function zoomOut(delta) {
54027 setZoom(~~map$$1.zoom() - delta, true, 250);
54030 map$$1.zoomIn = function() { zoomIn(1); };
54031 map$$1.zoomInFurther = function() { zoomIn(4); };
54033 map$$1.zoomOut = function() { zoomOut(1); };
54034 map$$1.zoomOutFurther = function() { zoomOut(4); };
54037 map$$1.center = function(loc2) {
54038 if (!arguments.length) {
54039 return projection.invert(pxCenter());
54042 if (setCenter(loc2)) {
54043 dispatch$$1.call('move', this, map$$1);
54051 map$$1.zoom = function(z2) {
54052 if (!arguments.length) {
54053 return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
54056 if (z2 < minzoom) {
54057 surface.interrupt();
54058 uiFlash(context.container())
54059 .select('.content')
54060 .text(t('cannot_zoom'));
54061 z2 = context.minEditableZoom();
54065 dispatch$$1.call('move', this, map$$1);
54073 map$$1.zoomTo = function(entity, zoomLimits) {
54074 var extent$$1 = entity.extent(context.graph());
54075 if (!isFinite(extent$$1.area())) return;
54077 var z2 = map$$1.trimmedExtentZoom(extent$$1);
54078 zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
54079 map$$1.centerZoom(extent$$1.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
54083 map$$1.centerZoom = function(loc2, z2) {
54084 var centered = setCenter(loc2),
54085 zoomed = setZoom(z2);
54087 if (centered || zoomed) {
54088 dispatch$$1.call('move', this, map$$1);
54096 map$$1.centerEase = function(loc2, duration) {
54097 duration = duration || 250;
54098 setCenter(loc2, duration);
54103 map$$1.zoomEase = function(z2, duration) {
54104 duration = duration || 250;
54105 setZoom(z2, false, duration);
54110 map$$1.transformEase = function(t2, duration) {
54111 duration = duration || 250;
54112 setTransform(t2, duration, false);
54117 map$$1.startEase = function() {
54118 utilBindOnce(surface, 'mousedown.ease', function() {
54119 map$$1.cancelEase();
54125 map$$1.cancelEase = function() {
54126 _selection.interrupt();
54131 map$$1.extent = function(_) {
54132 if (!arguments.length) {
54133 return new geoExtent$$1(projection.invert([0, dimensions[1]]),
54134 projection.invert([dimensions[0], 0]));
54136 var extent$$1 = geoExtent$$1(_);
54137 map$$1.centerZoom(extent$$1.center(), map$$1.extentZoom(extent$$1));
54142 map$$1.trimmedExtent = function(_) {
54143 if (!arguments.length) {
54144 var headerY = 60, footerY = 30, pad = 10;
54145 return new geoExtent$$1(projection.invert([pad, dimensions[1] - footerY - pad]),
54146 projection.invert([dimensions[0] - pad, headerY + pad]));
54148 var extent$$1 = geoExtent$$1(_);
54149 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
54154 function calcZoom(extent$$1, dim) {
54155 var tl = projection([extent$$1[0][0], extent$$1[1][1]]),
54156 br = projection([extent$$1[1][0], extent$$1[0][1]]);
54158 // Calculate maximum zoom that fits extent
54159 var hFactor = (br[0] - tl[0]) / dim[0],
54160 vFactor = (br[1] - tl[1]) / dim[1],
54161 hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
54162 vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
54163 newZoom = map$$1.zoom() - Math.max(hZoomDiff, vZoomDiff);
54169 map$$1.extentZoom = function(_) {
54170 return calcZoom(geoExtent$$1(_), dimensions);
54174 map$$1.trimmedExtentZoom = function(_) {
54175 var trimY = 120, trimX = 40,
54176 trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
54177 return calcZoom(geoExtent$$1(_), trimmed);
54181 map$$1.editable = function() {
54182 return map$$1.zoom() >= context.minEditableZoom();
54186 map$$1.minzoom = function(_) {
54187 if (!arguments.length) return minzoom;
54193 map$$1.layers = drawLayers;
54196 return utilRebind(map$$1, dispatch$$1, 'on');
54199 var TAU = 2 * Math.PI;
54200 function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
54201 function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
54202 function vecSub(a, b) { return [ a[0] - b[0], a[1] - b[1] ]; }
54203 function vecScale(a, b) { return [ a[0] * b, a[1] * b ]; }
54206 function uiMapInMap(context) {
54210 function map_in_map(selection$$1) {
54211 var backgroundLayer = rendererTileLayer(context),
54212 overlayLayers = {},
54213 projection = geoRawMercator(),
54214 gpxLayer = svgGpx(projection, context).showLabels(false),
54215 debugLayer = svgDebug(projection, context),
54217 .scaleExtent([ztok(0.5), ztok(24)])
54218 .on('start', zoomStarted)
54219 .on('zoom', zoomed)
54220 .on('end', zoomEnded),
54221 isTransformed = false,
54223 skipEvents = false,
54225 zDiff = 6, // by default, minimap renders at (main zoom - 6)
54226 wrap = select(null),
54227 tiles = select(null),
54228 viewport = select(null),
54229 tStart, // transform at start of gesture
54230 tCurr, // transform at most recent event
54234 function zoomStarted() {
54235 if (skipEvents) return;
54236 tStart = tCurr = projection.transform();
54241 function zoomed() {
54242 if (skipEvents) return;
54244 var x = event.transform.x,
54245 y = event.transform.y,
54246 k = event.transform.k,
54247 isZooming = (k !== tStart.k),
54248 isPanning = (x !== tStart.x || y !== tStart.y);
54250 if (!isZooming && !isPanning) {
54251 return; // no change
54254 // lock in either zooming or panning, don't allow both in minimap.
54256 gesture = isZooming ? 'zoom' : 'pan';
54259 var tMini = projection.transform(),
54262 if (gesture === 'zoom') {
54263 var dMini = utilGetDimensions(wrap),
54264 cMini = vecScale(dMini, 0.5);
54265 scale = k / tMini.k;
54266 tX = (cMini[0] / scale - cMini[0]) * scale;
54267 tY = (cMini[1] / scale - cMini[1]) * scale;
54275 utilSetTransform(tiles, tX, tY, scale);
54276 utilSetTransform(viewport, 0, 0, scale);
54277 isTransformed = true;
54278 tCurr = identity$6.translate(x, y).scale(k);
54280 var zMain = ktoz(context.projection.scale()),
54283 zDiff = zMain - zMini;
54289 function zoomEnded() {
54290 if (skipEvents) return;
54291 if (gesture !== 'pan') return;
54293 updateProjection();
54295 var dMini = utilGetDimensions(wrap),
54296 cMini = vecScale(dMini, 0.5);
54297 context.map().center(projection.invert(cMini)); // recenter main map..
54301 function updateProjection() {
54302 var loc = context.map().center(),
54303 dMini = utilGetDimensions(wrap),
54304 cMini = vecScale(dMini, 0.5),
54305 tMain = context.projection.transform(),
54306 zMain = ktoz(tMain.k),
54307 zMini = Math.max(zMain - zDiff, 0.5),
54308 kMini = ztok(zMini);
54311 .translate([tMain.x, tMain.y])
54314 var point = projection(loc),
54315 mouse$$1 = (gesture === 'pan') ? vecSub([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0],
54316 xMini = cMini[0] - point[0] + tMain.x + mouse$$1[0],
54317 yMini = cMini[1] - point[1] + tMain.y + mouse$$1[1];
54320 .translate([xMini, yMini])
54321 .clipExtent([[0, 0], dMini]);
54323 tCurr = projection.transform();
54325 if (isTransformed) {
54326 utilSetTransform(tiles, 0, 0);
54327 utilSetTransform(viewport, 0, 0);
54328 isTransformed = false;
54332 .scaleExtent([ztok(0.5), ztok(zMain - 3)]);
54335 wrap.call(zoom$$1.transform, tCurr);
54336 skipEvents = false;
54340 function redraw() {
54341 clearTimeout(timeoutId);
54342 if (isHidden) return;
54344 updateProjection();
54346 var dMini = utilGetDimensions(wrap),
54347 zMini = ktoz(projection.scale());
54349 // setup tile container
54351 .selectAll('.map-in-map-tiles')
54354 tiles = tiles.enter()
54356 .attr('class', 'map-in-map-tiles')
54359 // redraw background
54361 .source(context.background().baseLayerSource())
54362 .projection(projection)
54363 .dimensions(dMini);
54365 var background = tiles
54366 .selectAll('.map-in-map-background')
54371 .attr('class', 'map-in-map-background')
54373 .call(backgroundLayer);
54377 var overlaySources = context.background().overlayLayerSources();
54378 var activeOverlayLayers = [];
54379 for (var i = 0; i < overlaySources.length; i++) {
54380 if (overlaySources[i].validZoom(zMini)) {
54381 if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
54382 activeOverlayLayers.push(overlayLayers[i]
54383 .source(overlaySources[i])
54384 .projection(projection)
54385 .dimensions(dMini));
54389 var overlay = tiles
54390 .selectAll('.map-in-map-overlay')
54393 overlay = overlay.enter()
54395 .attr('class', 'map-in-map-overlay')
54399 var overlays = overlay
54401 .data(activeOverlayLayers, function(d) { return d.source().name(); });
54406 overlays = overlays.enter()
54409 .each(function(layer) { select(this).call(layer); });
54412 var dataLayers = tiles
54413 .selectAll('.map-in-map-data')
54419 dataLayers = dataLayers.enter()
54421 .attr('class', 'map-in-map-data')
54427 // redraw viewport bounding box
54428 if (gesture !== 'pan') {
54429 var getPath = index$5(projection),
54430 bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
54432 viewport = wrap.selectAll('.map-in-map-viewport')
54435 viewport = viewport.enter()
54437 .attr('class', 'map-in-map-viewport')
54441 var path$$1 = viewport.selectAll('.map-in-map-bbox')
54446 .attr('class', 'map-in-map-bbox')
54448 .attr('d', getPath)
54449 .classed('thick', function(d) { return getPath.area(d) < 30; });
54454 function queueRedraw() {
54455 clearTimeout(timeoutId);
54456 timeoutId = setTimeout(function() { redraw(); }, 750);
54460 function toggle() {
54461 if (event) event.preventDefault();
54463 isHidden = !isHidden;
54465 var label = select('.minimap-toggle');
54466 label.classed('active', !isHidden)
54467 .select('input').property('checked', !isHidden);
54471 .style('display', 'block')
54472 .style('opacity', '1')
54475 .style('opacity', '0')
54476 .on('end', function() {
54477 selection$$1.selectAll('.map-in-map')
54478 .style('display', 'none');
54482 .style('display', 'block')
54483 .style('opacity', '0')
54486 .style('opacity', '1')
54487 .on('end', function() {
54494 uiMapInMap.toggle = toggle;
54496 wrap = selection$$1.selectAll('.map-in-map')
54499 wrap = wrap.enter()
54501 .attr('class', 'map-in-map')
54502 .style('display', (isHidden ? 'none' : 'block'))
54504 .on('dblclick.zoom', null)
54508 .on('drawn.map-in-map', function(drawn) {
54509 if (drawn.full === true) {
54516 var keybinding = d3keybinding('map-in-map')
54526 function uiTooltipHtml(text, key) {
54527 var s = '<span>' + text + '</span>';
54529 s += '<div class="keyhint-wrap">' +
54530 '<span> ' + (t('tooltip_keyhint')) + ' </span>' +
54531 '<span class="keyhint"> ' + key + '</span></div>';
54536 function uiBackground(context) {
54538 detected = utilDetect(),
54539 opacities = [1, 0.75, 0.5, 0.25],
54541 ['right', [0.5, 0]],
54542 ['top', [0, -0.5]],
54543 ['left', [-0.5, 0]],
54544 ['bottom', [0, 0.5]]],
54545 opacityDefault = (context.storage('background-opacity') !== null) ?
54546 (+context.storage('background-opacity')) : 1.0,
54547 customTemplate = context.storage('background-custom-template') || '',
54550 // Can be 0 from <1.3.0 use or due to issue #1923.
54551 if (opacityDefault === 0) opacityDefault = 1.0;
54554 function background(selection$$1) {
54556 function sortSources(a, b) {
54557 return a.best() && !b.best() ? -1
54558 : b.best() && !a.best() ? 1
54559 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0;
54563 function setOpacity(d) {
54564 var bg = context.container().selectAll('.layer-background')
54566 .style('opacity', d)
54567 .attr('data-opacity', d);
54569 if (!detected.opera) {
54570 utilSetTransform(bg, 0, 0);
54573 opacityList.selectAll('li')
54574 .classed('active', function(_) { return _ === d; });
54576 context.storage('background-opacity', d);
54580 function setTooltips(selection$$1) {
54581 selection$$1.each(function(d, i, nodes) {
54582 var item = select(this).select('label'),
54583 placement = (i < nodes.length / 2) ? 'bottom' : 'top';
54585 if (d === previous) {
54586 item.call(tooltip()
54587 .placement(placement)
54589 .title(function() {
54590 var tip = '<div>' + t('background.switch') + '</div>';
54591 return uiTooltipHtml(tip, uiCmd('⌘B'));
54594 } else if (d.description) {
54595 item.call(tooltip()
54596 .placement(placement)
54597 .title(d.description)
54600 item.call(tooltip().destroy);
54606 function selectLayer() {
54607 function active$$1(d) {
54608 return context.background().showsLayer(d);
54611 content.selectAll('.layer, .custom_layer')
54612 .classed('active', active$$1)
54613 .classed('switch', function(d) { return d === previous; })
54615 .selectAll('input')
54616 .property('checked', active$$1);
54620 function clickSetSource(d) {
54621 event.preventDefault();
54622 previous = context.background().baseLayerSource();
54623 context.background().baseLayerSource(d);
54625 document.activeElement.blur();
54629 function editCustom() {
54630 event.preventDefault();
54631 var template = window.prompt(t('background.custom_prompt'), customTemplate);
54633 setCustom(template);
54640 function setCustom(template) {
54641 context.storage('background-custom-template', template);
54642 var d = rendererBackgroundSource.Custom(template);
54643 content.selectAll('.custom_layer').datum(d);
54648 function clickSetOverlay(d) {
54649 event.preventDefault();
54650 context.background().toggleOverlayLayer(d);
54652 document.activeElement.blur();
54656 function drawList(layerList, type, change, filter) {
54657 var sources = context.background()
54658 .sources(context.map().extent())
54661 var layerLinks = layerList.selectAll('li.layer')
54662 .data(sources, function(d) { return d.name(); });
54667 var enter = layerLinks.enter()
54668 .insert('li', '.custom_layer')
54669 .attr('class', 'layer')
54670 .classed('best', function(d) { return d.best(); });
54672 enter.filter(function(d) { return d.best(); })
54674 .attr('class', 'best')
54676 .title(t('background.best_imagery'))
54677 .placement((textDirection === 'rtl') ? 'right' : 'left'))
54686 .attr('type', type)
54687 .attr('name', 'layers')
54688 .on('change', change);
54692 .text(function(d) { return d.name(); });
54695 layerList.selectAll('li.layer')
54697 .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
54701 function update() {
54702 backgroundList.call(drawList, 'radio', clickSetSource, function(d) { return !d.overlay; });
54703 overlayList.call(drawList, 'checkbox', clickSetOverlay, function(d) { return d.overlay; });
54707 var source = context.background().baseLayerSource();
54708 if (source.id === 'custom') {
54709 customTemplate = source.template;
54716 function updateOffsetVal() {
54717 var meters = geoOffsetToMeters(context.background().offset()),
54718 x = +meters[0].toFixed(2),
54719 y = +meters[1].toFixed(2);
54721 selectAll('.nudge-inner-rect')
54723 .classed('error', false)
54724 .property('value', x + ', ' + y);
54726 selectAll('.nudge-reset')
54727 .classed('disabled', function() {
54728 return (x === 0 && y === 0);
54733 function resetOffset() {
54734 if (event.button !== 0) return;
54735 context.background().offset([0, 0]);
54740 function nudge(d) {
54741 context.background().nudge(d, context.map().zoom());
54746 function buttonOffset(d) {
54747 if (event.button !== 0) return;
54748 var timeout$$1 = window.setTimeout(function() {
54749 interval$$1 = window.setInterval(nudge.bind(null, d), 100);
54753 function doneNudge() {
54754 window.clearTimeout(timeout$$1);
54755 window.clearInterval(interval$$1);
54757 .on('mouseup.buttonoffset', null, true)
54758 .on('mousedown.buttonoffset', null, true);
54762 .on('mouseup.buttonoffset', doneNudge, true)
54763 .on('mousedown.buttonoffset', doneNudge, true);
54769 function inputOffset() {
54770 if (event.button !== 0) return;
54771 var input = select(this);
54772 var d = input.node().value;
54774 if (d === '') return resetOffset();
54776 d = d.replace(/;/g, ',').split(',').map(function(n) {
54777 // if n is NaN, it will always get mapped to false.
54778 return !isNaN(n) && n;
54781 if (d.length !== 2 || !d[0] || !d[1]) {
54782 input.classed('error', true);
54786 context.background().offset(geoMetersToOffset(d));
54791 function dragOffset() {
54792 if (event.button !== 0) return;
54793 var origin = [event.clientX, event.clientY];
54795 context.container()
54797 .attr('class', 'nudge-surface');
54800 .on('mousemove.offset', function() {
54801 var latest = [event.clientX, event.clientY];
54803 -(origin[0] - latest[0]) / 4,
54804 -(origin[1] - latest[1]) / 4
54810 .on('mouseup.offset', function() {
54811 if (event.button !== 0) return;
54812 selectAll('.nudge-surface')
54816 .on('mousemove.offset', null)
54817 .on('mouseup.offset', null);
54820 event.preventDefault();
54829 function toggle() {
54830 if (event) event.preventDefault();
54831 tooltipBehavior.hide(button);
54832 setVisible(!button.classed('active'));
54836 function quickSwitch() {
54838 clickSetSource(previous);
54843 function setVisible(show) {
54844 if (show !== shown) {
54845 button.classed('active', show);
54849 selection$$1.on('mousedown.background-inside', function() {
54850 event.stopPropagation();
54853 .style('display', 'block')
54854 .style('right', '-300px')
54857 .style('right', '0px');
54860 .style('display', 'block')
54861 .style('right', '0px')
54864 .style('right', '-300px')
54865 .on('end', function() {
54866 select(this).style('display', 'none');
54868 selection$$1.on('mousedown.background-inside', null);
54874 var content = selection$$1
54876 .attr('class', 'fillL map-overlay col3 content hide'),
54877 tooltipBehavior = tooltip()
54878 .placement((textDirection === 'rtl') ? 'right' : 'left')
54880 .title(uiTooltipHtml(t('background.description'), key)),
54881 button = selection$$1
54883 .attr('tabindex', -1)
54884 .on('click', toggle)
54885 .call(svgIcon('#icon-layers', 'light'))
54886 .call(tooltipBehavior),
54890 /* opacity switcher */
54892 var opawrap = content
54894 .attr('class', 'opacity-options-wrapper');
54898 .text(t('background.title'));
54900 var opacityList = opawrap
54902 .attr('class', 'opacity-options');
54904 opacityList.selectAll('div.opacity')
54908 .attr('data-original-title', function(d) {
54909 return t('background.percent_brightness', { opacity: (d * 100) });
54911 .on('click.set-opacity', setOpacity)
54912 .html('<div class="select-box"></div>')
54914 .placement((textDirection === 'rtl') ? 'right' : 'left'))
54916 .attr('class', 'opacity')
54917 .style('opacity', function(d) { return 1.25 - d; });
54920 /* background switcher */
54922 var backgroundList = content
54924 .attr('class', 'layer-list')
54925 .attr('dir', 'auto');
54927 var custom = backgroundList
54929 .attr('class', 'custom_layer')
54930 .datum(rendererBackgroundSource.Custom());
54934 .attr('class', 'layer-browse')
54936 .title(t('background.custom_button'))
54937 .placement((textDirection === 'rtl') ? 'right' : 'left'))
54938 .on('click', editCustom)
54939 .call(svgIcon('#icon-search'));
54946 .attr('type', 'radio')
54947 .attr('name', 'layers')
54948 .on('change', function () {
54949 if (customTemplate) {
54950 setCustom(customTemplate);
54958 .text(t('background.custom'));
54962 .attr('class', 'imagery-faq')
54964 .attr('target', '_blank')
54965 .attr('tabindex', -1)
54966 .call(svgIcon('#icon-out-link', 'inline'))
54967 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
54969 .text(t('background.imagery_source_faq'));
54971 var overlayList = content
54973 .attr('class', 'layer-list');
54975 var controls = content
54977 .attr('class', 'controls-list');
54980 /* minimap toggle */
54982 var minimapLabel = controls
54986 .title(uiTooltipHtml(t('background.minimap.tooltip'), '/'))
54991 .classed('minimap-toggle', true)
54993 .attr('type', 'checkbox')
54994 .on('change', function() {
54995 uiMapInMap.toggle();
54996 event.preventDefault();
55001 .text(t('background.minimap.description'));
55004 /* imagery offset controls */
55006 var adjustments = content
55008 .attr('class', 'adjustments');
55012 .text(t('background.fix_misalignment'))
55014 .classed('hide-toggle', true)
55015 .classed('expanded', false)
55016 .on('click', function() {
55017 if (event.button !== 0) return;
55018 var exp = select(this).classed('expanded');
55019 nudgeContainer.style('display', exp ? 'none' : 'block');
55020 select(this).classed('expanded', !exp);
55021 event.preventDefault();
55024 var nudgeContainer = adjustments
55026 .attr('class', 'nudge-container cf')
55027 .style('display', 'none');
55031 .attr('class', 'nudge-instructions')
55032 .text(t('background.offset'));
55034 var nudgeRect = nudgeContainer
55036 .attr('class', 'nudge-outer-rect')
55037 .on('mousedown', dragOffset);
55041 .attr('class', 'nudge-inner-rect')
55043 .on('change', inputOffset)
55044 .on('mousedown', function() {
55045 if (event.button !== 0) return;
55046 event.stopPropagation();
55051 .selectAll('button')
55052 .data(directions).enter()
55054 .attr('class', function(d) { return d[0] + ' nudge'; })
55055 .on('mousedown', function(d) {
55056 if (event.button !== 0) return;
55057 buttonOffset(d[1]);
55062 .attr('title', t('background.reset'))
55063 .attr('class', 'nudge-reset disabled')
55064 .on('click', resetOffset)
55066 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
55070 .on('move.background-update', lodash.debounce(update, 1000));
55072 context.background()
55073 .on('change.background-update', update);
55077 setOpacity(opacityDefault);
55079 var keybinding = d3keybinding('background')
55081 .on(uiCmd('⌘B'), quickSwitch)
55088 context.surface().on('mousedown.background-outside', hide);
55089 context.container().on('mousedown.background-outside', hide);
55095 function uiContributors(context) {
55096 var debouncedUpdate = lodash.debounce(function() { update(); }, 1000),
55099 wrap = select(null);
55102 function update() {
55104 entities = context.intersects(context.map().extent());
55106 entities.forEach(function(entity) {
55107 if (entity && entity.user) users[entity.user] = true;
55110 var u = Object.keys(users),
55111 subset = u.slice(0, u.length > limit ? limit - 1 : limit);
55114 .call(svgIcon('#icon-nearby', 'pre-text light'));
55116 var userList = select(document.createElement('span'));
55118 userList.selectAll()
55122 .attr('class', 'user-link')
55123 .attr('href', function(d) { return context.connection().userURL(d); })
55124 .attr('target', '_blank')
55125 .attr('tabindex', -1)
55128 if (u.length > limit) {
55129 var count = select(document.createElement('span'));
55132 .attr('target', '_blank')
55133 .attr('tabindex', -1)
55134 .attr('href', function() {
55135 return context.connection().changesetsURL(context.map().center(), context.map().zoom());
55137 .text(u.length - limit + 1);
55139 wrap.append('span')
55140 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
55143 wrap.append('span')
55144 .html(t('contributors.list', { users: userList.html() }));
55151 .style('opacity', 0);
55153 } else if (hidden) {
55156 .style('opacity', 1);
55161 return function(selection$$1) {
55162 wrap = selection$$1;
55165 context.connection().on('loaded.contributors', debouncedUpdate);
55166 context.map().on('move.contributors', debouncedUpdate);
55170 function uiFeatureInfo(context) {
55171 function update(selection$$1) {
55172 var features = context.features(),
55173 stats = features.stats(),
55175 hiddenList = lodash.compact(lodash.map(features.hidden(), function(k) {
55178 return String(stats[k]) + ' ' + t('feature.' + k + '.description');
55182 selection$$1.html('');
55184 if (hiddenList.length) {
55185 var tooltipBehavior = tooltip()
55188 .title(function() {
55189 return uiTooltipHtml(hiddenList.join('<br/>'));
55192 var warning = selection$$1.append('a')
55194 .attr('tabindex', -1)
55195 .html(t('feature_info.hidden_warning', { count: count }))
55196 .call(tooltipBehavior)
55197 .on('click', function() {
55198 tooltipBehavior.hide(warning);
55199 // open map data panel?
55200 event.preventDefault();
55205 .classed('hide', !hiddenList.length);
55209 return function(selection$$1) {
55210 update(selection$$1);
55212 context.features().on('change.feature_info', function() {
55213 update(selection$$1);
55218 function uiFullScreen(context) {
55219 var element = context.container().node(),
55220 keybinding = d3keybinding('full-screen');
55224 function getFullScreenFn() {
55225 if (element.requestFullscreen) {
55226 return element.requestFullscreen;
55227 } else if (element.msRequestFullscreen) {
55228 return element.msRequestFullscreen;
55229 } else if (element.mozRequestFullScreen) {
55230 return element.mozRequestFullScreen;
55231 } else if (element.webkitRequestFullscreen) {
55232 return element.webkitRequestFullscreen;
55237 function getExitFullScreenFn() {
55238 if (document.exitFullscreen) {
55239 return document.exitFullscreen;
55240 } else if (document.msExitFullscreen) {
55241 return document.msExitFullscreen;
55242 } else if (document.mozCancelFullScreen) {
55243 return document.mozCancelFullScreen;
55244 } else if (document.webkitExitFullscreen) {
55245 return document.webkitExitFullscreen;
55250 function isFullScreen() {
55251 return document.fullscreenElement ||
55252 document.mozFullScreenElement ||
55253 document.webkitFullscreenElement ||
55254 document.msFullscreenElement;
55258 function isSupported() {
55259 return !!getFullScreenFn();
55263 function fullScreen() {
55264 event.preventDefault();
55265 if (!isFullScreen()) {
55266 // button.classed('active', true);
55267 getFullScreenFn().apply(element);
55269 // button.classed('active', false);
55270 getExitFullScreenFn().apply(document);
55275 return function() { // selection) {
55276 if (!isSupported())
55279 // button = selection.append('button')
55280 // .attr('title', t('full_screen'))
55281 // .attr('tabindex', -1)
55282 // .on('click', fullScreen)
55285 // button.append('span')
55286 // .attr('class', 'icon full-screen');
55289 .on('f11', fullScreen)
55290 .on(uiCmd('⌘⇧F'), fullScreen);
55297 function uiModal(selection$$1, blocking) {
55298 var keybinding = d3keybinding('modal');
55299 var previous = selection$$1.select('div.modal');
55300 var animate = previous.empty();
55302 previous.transition()
55304 .style('opacity', 0)
55307 var shaded = selection$$1
55309 .attr('class', 'shaded')
55310 .style('opacity', 0);
55312 shaded.close = function() {
55316 .style('opacity',0)
55322 .style('top','0px');
55330 .attr('class', 'modal fillL col6');
55333 shaded.on('click.remove-modal', function() {
55334 if (event.target === this) {
55339 modal.append('button')
55340 .attr('class', 'close')
55341 .on('click', shaded.close)
55342 .call(svgIcon('#icon-close'));
55345 .on('⌫', shaded.close)
55346 .on('⎋', shaded.close);
55354 .attr('class', 'content');
55357 shaded.transition().style('opacity', 1);
55359 shaded.style('opacity', 1);
55366 function uiLoading(context) {
55372 var loading = function(selection) {
55373 modalSelection = uiModal(selection, blocking);
55375 var loadertext = modalSelection.select('.content')
55376 .classed('loading-modal', true)
55378 .attr('class', 'modal-section fillL');
55382 .attr('class', 'loader')
55383 .attr('src', context.imagePath('loader-white.gif'));
55389 modalSelection.select('button.close')
55390 .attr('class', 'hide');
55396 loading.message = function(_) {
55397 if (!arguments.length) return message;
55403 loading.blocking = function(_) {
55404 if (!arguments.length) return blocking;
55410 loading.close = function() {
55411 modalSelection.remove();
55418 function uiGeolocate(context) {
55419 var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
55420 locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
55425 context.enter(modeBrowse$$1(context));
55426 context.container().call(locating);
55427 navigator.geolocation.getCurrentPosition(success, error, geoOptions);
55429 // This timeout ensures that we still call finish() even if
55430 // the user declines to share their location in Firefox
55431 timeoutId = setTimeout(finish, 10000 /* 10sec */ );
55435 function success(position) {
55436 var map = context.map(),
55437 extent = geoExtent$$1([position.coords.longitude, position.coords.latitude])
55438 .padByMeters(position.coords.accuracy);
55440 map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
55450 function finish() {
55451 locating.close(); // unblock ui
55452 if (timeoutId) { clearTimeout(timeoutId); }
55453 timeoutId = undefined;
55457 return function(selection) {
55458 if (!navigator.geolocation) return;
55462 .attr('tabindex', -1)
55463 .attr('title', t('geolocate.title'))
55464 .on('click', click)
55465 .call(svgIcon('#icon-geolocate', 'light'))
55467 .placement((textDirection === 'rtl') ? 'right' : 'left'));
55471 var marked = createCommonjsModule(function (module, exports) {
55473 * marked - a markdown parser
55474 * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
55475 * https://github.com/chjj/marked
55481 * Block-Level Grammar
55486 code: /^( {4}[^\n]+\n*)+/,
55488 hr: /^( *[-*_]){3,} *(?:\n+|$)/,
55489 heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
55491 lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
55492 blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
55493 list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
55494 html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
55495 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
55497 paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
55501 block.bullet = /(?:[*+-]|\d+\.)/;
55502 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
55503 block.item = replace(block.item, 'gm')
55504 (/bull/g, block.bullet)
55507 block.list = replace(block.list)
55508 (/bull/g, block.bullet)
55509 ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
55510 ('def', '\\n+(?=' + block.def.source + ')')
55513 block.blockquote = replace(block.blockquote)
55517 block._tag = '(?!(?:'
55518 + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
55519 + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
55520 + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
55522 block.html = replace(block.html)
55523 ('comment', /<!--[\s\S]*?-->/)
55524 ('closed', /<(tag)[\s\S]+?<\/\1>/)
55525 ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
55526 (/tag/g, block._tag)
55529 block.paragraph = replace(block.paragraph)
55531 ('heading', block.heading)
55532 ('lheading', block.lheading)
55533 ('blockquote', block.blockquote)
55534 ('tag', '<' + block._tag)
55539 * Normal Block Grammar
55542 block.normal = merge({}, block);
55545 * GFM Block Grammar
55548 block.gfm = merge({}, block.normal, {
55549 fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
55551 heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
55554 block.gfm.paragraph = replace(block.paragraph)
55556 + block.gfm.fences.source.replace('\\1', '\\2') + '|'
55557 + block.list.source.replace('\\1', '\\3') + '|')
55561 * GFM + Tables Block Grammar
55564 block.tables = merge({}, block.gfm, {
55565 nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
55566 table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
55573 function Lexer(options) {
55575 this.tokens.links = {};
55576 this.options = options || marked.defaults;
55577 this.rules = block.normal;
55579 if (this.options.gfm) {
55580 if (this.options.tables) {
55581 this.rules = block.tables;
55583 this.rules = block.gfm;
55589 * Expose Block Rules
55592 Lexer.rules = block;
55595 * Static Lex Method
55598 Lexer.lex = function(src, options) {
55599 var lexer = new Lexer(options);
55600 return lexer.lex(src);
55607 Lexer.prototype.lex = function(src) {
55609 .replace(/\r\n|\r/g, '\n')
55610 .replace(/\t/g, ' ')
55611 .replace(/\u00a0/g, ' ')
55612 .replace(/\u2424/g, '\n');
55614 return this.token(src, true);
55621 Lexer.prototype.token = function(src, top, bq) {
55622 var src = src.replace(/^ +$/gm, '')
55635 if (cap = this.rules.newline.exec(src)) {
55636 src = src.substring(cap[0].length);
55637 if (cap[0].length > 1) {
55645 if (cap = this.rules.code.exec(src)) {
55646 src = src.substring(cap[0].length);
55647 cap = cap[0].replace(/^ {4}/gm, '');
55650 text: !this.options.pedantic
55651 ? cap.replace(/\n+$/, '')
55658 if (cap = this.rules.fences.exec(src)) {
55659 src = src.substring(cap[0].length);
55669 if (cap = this.rules.heading.exec(src)) {
55670 src = src.substring(cap[0].length);
55673 depth: cap[1].length,
55679 // table no leading pipe (gfm)
55680 if (top && (cap = this.rules.nptable.exec(src))) {
55681 src = src.substring(cap[0].length);
55685 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
55686 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
55687 cells: cap[3].replace(/\n$/, '').split('\n')
55690 for (i = 0; i < item.align.length; i++) {
55691 if (/^ *-+: *$/.test(item.align[i])) {
55692 item.align[i] = 'right';
55693 } else if (/^ *:-+: *$/.test(item.align[i])) {
55694 item.align[i] = 'center';
55695 } else if (/^ *:-+ *$/.test(item.align[i])) {
55696 item.align[i] = 'left';
55698 item.align[i] = null;
55702 for (i = 0; i < item.cells.length; i++) {
55703 item.cells[i] = item.cells[i].split(/ *\| */);
55706 this.tokens.push(item);
55712 if (cap = this.rules.lheading.exec(src)) {
55713 src = src.substring(cap[0].length);
55716 depth: cap[2] === '=' ? 1 : 2,
55723 if (cap = this.rules.hr.exec(src)) {
55724 src = src.substring(cap[0].length);
55732 if (cap = this.rules.blockquote.exec(src)) {
55733 src = src.substring(cap[0].length);
55736 type: 'blockquote_start'
55739 cap = cap[0].replace(/^ *> ?/gm, '');
55741 // Pass `top` to keep the current
55742 // "toplevel" state. This is exactly
55743 // how markdown.pl works.
55744 this.token(cap, top, true);
55747 type: 'blockquote_end'
55754 if (cap = this.rules.list.exec(src)) {
55755 src = src.substring(cap[0].length);
55759 type: 'list_start',
55760 ordered: bull.length > 1
55763 // Get each top-level item.
55764 cap = cap[0].match(this.rules.item);
55770 for (; i < l; i++) {
55773 // Remove the list item's bullet
55774 // so it is seen as the next token.
55775 space = item.length;
55776 item = item.replace(/^ *([*+-]|\d+\.) +/, '');
55778 // Outdent whatever the
55779 // list item contains. Hacky.
55780 if (~item.indexOf('\n ')) {
55781 space -= item.length;
55782 item = !this.options.pedantic
55783 ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
55784 : item.replace(/^ {1,4}/gm, '');
55787 // Determine whether the next list item belongs here.
55788 // Backpedal if it does not belong in this list.
55789 if (this.options.smartLists && i !== l - 1) {
55790 b = block.bullet.exec(cap[i + 1])[0];
55791 if (bull !== b && !(bull.length > 1 && b.length > 1)) {
55792 src = cap.slice(i + 1).join('\n') + src;
55797 // Determine whether item is loose or not.
55798 // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
55799 // for discount behavior.
55800 loose = next || /\n\n(?!\s*$)/.test(item);
55802 next = item.charAt(item.length - 1) === '\n';
55803 if (!loose) loose = next;
55808 ? 'loose_item_start'
55809 : 'list_item_start'
55813 this.token(item, false, bq);
55816 type: 'list_item_end'
55828 if (cap = this.rules.html.exec(src)) {
55829 src = src.substring(cap[0].length);
55831 type: this.options.sanitize
55834 pre: !this.options.sanitizer
55835 && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
55842 if ((!bq && top) && (cap = this.rules.def.exec(src))) {
55843 src = src.substring(cap[0].length);
55844 this.tokens.links[cap[1].toLowerCase()] = {
55852 if (top && (cap = this.rules.table.exec(src))) {
55853 src = src.substring(cap[0].length);
55857 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
55858 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
55859 cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
55862 for (i = 0; i < item.align.length; i++) {
55863 if (/^ *-+: *$/.test(item.align[i])) {
55864 item.align[i] = 'right';
55865 } else if (/^ *:-+: *$/.test(item.align[i])) {
55866 item.align[i] = 'center';
55867 } else if (/^ *:-+ *$/.test(item.align[i])) {
55868 item.align[i] = 'left';
55870 item.align[i] = null;
55874 for (i = 0; i < item.cells.length; i++) {
55875 item.cells[i] = item.cells[i]
55876 .replace(/^ *\| *| *\| *$/g, '')
55880 this.tokens.push(item);
55885 // top-level paragraph
55886 if (top && (cap = this.rules.paragraph.exec(src))) {
55887 src = src.substring(cap[0].length);
55890 text: cap[1].charAt(cap[1].length - 1) === '\n'
55891 ? cap[1].slice(0, -1)
55898 if (cap = this.rules.text.exec(src)) {
55899 // Top-level should never reach here.
55900 src = src.substring(cap[0].length);
55910 Error('Infinite loop on byte: ' + src.charCodeAt(0));
55914 return this.tokens;
55918 * Inline-Level Grammar
55922 escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
55923 autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
55925 tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
55926 link: /^!?\[(inside)\]\(href\)/,
55927 reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
55928 nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
55929 strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
55930 em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
55931 code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
55932 br: /^ {2,}\n(?!\s*$)/,
55934 text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
55937 inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
55938 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
55940 inline.link = replace(inline.link)
55941 ('inside', inline._inside)
55942 ('href', inline._href)
55945 inline.reflink = replace(inline.reflink)
55946 ('inside', inline._inside)
55950 * Normal Inline Grammar
55953 inline.normal = merge({}, inline);
55956 * Pedantic Inline Grammar
55959 inline.pedantic = merge({}, inline.normal, {
55960 strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
55961 em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
55965 * GFM Inline Grammar
55968 inline.gfm = merge({}, inline.normal, {
55969 escape: replace(inline.escape)('])', '~|])')(),
55970 url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
55971 del: /^~~(?=\S)([\s\S]*?\S)~~/,
55972 text: replace(inline.text)
55974 ('|', '|https?://|')
55979 * GFM + Line Breaks Inline Grammar
55982 inline.breaks = merge({}, inline.gfm, {
55983 br: replace(inline.br)('{2,}', '*')(),
55984 text: replace(inline.gfm.text)('{2,}', '*')()
55988 * Inline Lexer & Compiler
55991 function InlineLexer(links, options) {
55992 this.options = options || marked.defaults;
55993 this.links = links;
55994 this.rules = inline.normal;
55995 this.renderer = this.options.renderer || new Renderer;
55996 this.renderer.options = this.options;
56000 Error('Tokens array requires a `links` property.');
56003 if (this.options.gfm) {
56004 if (this.options.breaks) {
56005 this.rules = inline.breaks;
56007 this.rules = inline.gfm;
56009 } else if (this.options.pedantic) {
56010 this.rules = inline.pedantic;
56015 * Expose Inline Rules
56018 InlineLexer.rules = inline;
56021 * Static Lexing/Compiling Method
56024 InlineLexer.output = function(src, links, options) {
56025 var inline = new InlineLexer(links, options);
56026 return inline.output(src);
56033 InlineLexer.prototype.output = function(src) {
56042 if (cap = this.rules.escape.exec(src)) {
56043 src = src.substring(cap[0].length);
56049 if (cap = this.rules.autolink.exec(src)) {
56050 src = src.substring(cap[0].length);
56051 if (cap[2] === '@') {
56052 text = cap[1].charAt(6) === ':'
56053 ? this.mangle(cap[1].substring(7))
56054 : this.mangle(cap[1]);
56055 href = this.mangle('mailto:') + text;
56057 text = escape(cap[1]);
56060 out += this.renderer.link(href, null, text);
56065 if (!this.inLink && (cap = this.rules.url.exec(src))) {
56066 src = src.substring(cap[0].length);
56067 text = escape(cap[1]);
56069 out += this.renderer.link(href, null, text);
56074 if (cap = this.rules.tag.exec(src)) {
56075 if (!this.inLink && /^<a /i.test(cap[0])) {
56076 this.inLink = true;
56077 } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
56078 this.inLink = false;
56080 src = src.substring(cap[0].length);
56081 out += this.options.sanitize
56082 ? this.options.sanitizer
56083 ? this.options.sanitizer(cap[0])
56090 if (cap = this.rules.link.exec(src)) {
56091 src = src.substring(cap[0].length);
56092 this.inLink = true;
56093 out += this.outputLink(cap, {
56097 this.inLink = false;
56102 if ((cap = this.rules.reflink.exec(src))
56103 || (cap = this.rules.nolink.exec(src))) {
56104 src = src.substring(cap[0].length);
56105 link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
56106 link = this.links[link.toLowerCase()];
56107 if (!link || !link.href) {
56108 out += cap[0].charAt(0);
56109 src = cap[0].substring(1) + src;
56112 this.inLink = true;
56113 out += this.outputLink(cap, link);
56114 this.inLink = false;
56119 if (cap = this.rules.strong.exec(src)) {
56120 src = src.substring(cap[0].length);
56121 out += this.renderer.strong(this.output(cap[2] || cap[1]));
56126 if (cap = this.rules.em.exec(src)) {
56127 src = src.substring(cap[0].length);
56128 out += this.renderer.em(this.output(cap[2] || cap[1]));
56133 if (cap = this.rules.code.exec(src)) {
56134 src = src.substring(cap[0].length);
56135 out += this.renderer.codespan(escape(cap[2], true));
56140 if (cap = this.rules.br.exec(src)) {
56141 src = src.substring(cap[0].length);
56142 out += this.renderer.br();
56147 if (cap = this.rules.del.exec(src)) {
56148 src = src.substring(cap[0].length);
56149 out += this.renderer.del(this.output(cap[1]));
56154 if (cap = this.rules.text.exec(src)) {
56155 src = src.substring(cap[0].length);
56156 out += this.renderer.text(escape(this.smartypants(cap[0])));
56162 Error('Infinite loop on byte: ' + src.charCodeAt(0));
56173 InlineLexer.prototype.outputLink = function(cap, link) {
56174 var href = escape(link.href)
56175 , title = link.title ? escape(link.title) : null;
56177 return cap[0].charAt(0) !== '!'
56178 ? this.renderer.link(href, title, this.output(cap[1]))
56179 : this.renderer.image(href, title, escape(cap[1]));
56183 * Smartypants Transformations
56186 InlineLexer.prototype.smartypants = function(text) {
56187 if (!this.options.smartypants) return text;
56190 .replace(/---/g, '\u2014')
56192 .replace(/--/g, '\u2013')
56194 .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
56195 // closing singles & apostrophes
56196 .replace(/'/g, '\u2019')
56198 .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
56200 .replace(/"/g, '\u201d')
56202 .replace(/\.{3}/g, '\u2026');
56209 InlineLexer.prototype.mangle = function(text) {
56210 if (!this.options.mangle) return text;
56216 for (; i < l; i++) {
56217 ch = text.charCodeAt(i);
56218 if (Math.random() > 0.5) {
56219 ch = 'x' + ch.toString(16);
56221 out += '&#' + ch + ';';
56231 function Renderer(options) {
56232 this.options = options || {};
56235 Renderer.prototype.code = function(code, lang, escaped) {
56236 if (this.options.highlight) {
56237 var out = this.options.highlight(code, lang);
56238 if (out != null && out !== code) {
56245 return '<pre><code>'
56246 + (escaped ? code : escape(code, true))
56247 + '\n</code></pre>';
56250 return '<pre><code class="'
56251 + this.options.langPrefix
56252 + escape(lang, true)
56254 + (escaped ? code : escape(code, true))
56255 + '\n</code></pre>\n';
56258 Renderer.prototype.blockquote = function(quote) {
56259 return '<blockquote>\n' + quote + '</blockquote>\n';
56262 Renderer.prototype.html = function(html) {
56266 Renderer.prototype.heading = function(text, level, raw) {
56270 + this.options.headerPrefix
56271 + raw.toLowerCase().replace(/[^\w]+/g, '-')
56279 Renderer.prototype.hr = function() {
56280 return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
56283 Renderer.prototype.list = function(body, ordered) {
56284 var type = ordered ? 'ol' : 'ul';
56285 return '<' + type + '>\n' + body + '</' + type + '>\n';
56288 Renderer.prototype.listitem = function(text) {
56289 return '<li>' + text + '</li>\n';
56292 Renderer.prototype.paragraph = function(text) {
56293 return '<p>' + text + '</p>\n';
56296 Renderer.prototype.table = function(header, body) {
56307 Renderer.prototype.tablerow = function(content) {
56308 return '<tr>\n' + content + '</tr>\n';
56311 Renderer.prototype.tablecell = function(content, flags) {
56312 var type = flags.header ? 'th' : 'td';
56313 var tag = flags.align
56314 ? '<' + type + ' style="text-align:' + flags.align + '">'
56315 : '<' + type + '>';
56316 return tag + content + '</' + type + '>\n';
56319 // span level renderer
56320 Renderer.prototype.strong = function(text) {
56321 return '<strong>' + text + '</strong>';
56324 Renderer.prototype.em = function(text) {
56325 return '<em>' + text + '</em>';
56328 Renderer.prototype.codespan = function(text) {
56329 return '<code>' + text + '</code>';
56332 Renderer.prototype.br = function() {
56333 return this.options.xhtml ? '<br/>' : '<br>';
56336 Renderer.prototype.del = function(text) {
56337 return '<del>' + text + '</del>';
56340 Renderer.prototype.link = function(href, title, text) {
56341 if (this.options.sanitize) {
56343 var prot = decodeURIComponent(unescape(href))
56344 .replace(/[^\w:]/g, '')
56349 if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
56353 var out = '<a href="' + href + '"';
56355 out += ' title="' + title + '"';
56357 out += '>' + text + '</a>';
56361 Renderer.prototype.image = function(href, title, text) {
56362 var out = '<img src="' + href + '" alt="' + text + '"';
56364 out += ' title="' + title + '"';
56366 out += this.options.xhtml ? '/>' : '>';
56370 Renderer.prototype.text = function(text) {
56375 * Parsing & Compiling
56378 function Parser(options) {
56381 this.options = options || marked.defaults;
56382 this.options.renderer = this.options.renderer || new Renderer;
56383 this.renderer = this.options.renderer;
56384 this.renderer.options = this.options;
56388 * Static Parse Method
56391 Parser.parse = function(src, options, renderer) {
56392 var parser = new Parser(options, renderer);
56393 return parser.parse(src);
56400 Parser.prototype.parse = function(src) {
56401 this.inline = new InlineLexer(src.links, this.options, this.renderer);
56402 this.tokens = src.reverse();
56405 while (this.next()) {
56416 Parser.prototype.next = function() {
56417 return this.token = this.tokens.pop();
56421 * Preview Next Token
56424 Parser.prototype.peek = function() {
56425 return this.tokens[this.tokens.length - 1] || 0;
56429 * Parse Text Tokens
56432 Parser.prototype.parseText = function() {
56433 var body = this.token.text;
56435 while (this.peek().type === 'text') {
56436 body += '\n' + this.next().text;
56439 return this.inline.output(body);
56443 * Parse Current Token
56446 Parser.prototype.tok = function() {
56447 switch (this.token.type) {
56452 return this.renderer.hr();
56455 return this.renderer.heading(
56456 this.inline.output(this.token.text),
56461 return this.renderer.code(this.token.text,
56463 this.token.escaped);
56476 for (i = 0; i < this.token.header.length; i++) {
56477 flags = { header: true, align: this.token.align[i] };
56478 cell += this.renderer.tablecell(
56479 this.inline.output(this.token.header[i]),
56480 { header: true, align: this.token.align[i] }
56483 header += this.renderer.tablerow(cell);
56485 for (i = 0; i < this.token.cells.length; i++) {
56486 row = this.token.cells[i];
56489 for (j = 0; j < row.length; j++) {
56490 cell += this.renderer.tablecell(
56491 this.inline.output(row[j]),
56492 { header: false, align: this.token.align[j] }
56496 body += this.renderer.tablerow(cell);
56498 return this.renderer.table(header, body);
56500 case 'blockquote_start': {
56503 while (this.next().type !== 'blockquote_end') {
56504 body += this.tok();
56507 return this.renderer.blockquote(body);
56509 case 'list_start': {
56511 , ordered = this.token.ordered;
56513 while (this.next().type !== 'list_end') {
56514 body += this.tok();
56517 return this.renderer.list(body, ordered);
56519 case 'list_item_start': {
56522 while (this.next().type !== 'list_item_end') {
56523 body += this.token.type === 'text'
56528 return this.renderer.listitem(body);
56530 case 'loose_item_start': {
56533 while (this.next().type !== 'list_item_end') {
56534 body += this.tok();
56537 return this.renderer.listitem(body);
56540 var html = !this.token.pre && !this.options.pedantic
56541 ? this.inline.output(this.token.text)
56543 return this.renderer.html(html);
56545 case 'paragraph': {
56546 return this.renderer.paragraph(this.inline.output(this.token.text));
56549 return this.renderer.paragraph(this.parseText());
56558 function escape(html, encode) {
56560 .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
56561 .replace(/</g, '<')
56562 .replace(/>/g, '>')
56563 .replace(/"/g, '"')
56564 .replace(/'/g, ''');
56567 function unescape(html) {
56568 // explicitly match decimal, hex, and named HTML entities
56569 return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
56570 n = n.toLowerCase();
56571 if (n === 'colon') return ':';
56572 if (n.charAt(0) === '#') {
56573 return n.charAt(1) === 'x'
56574 ? String.fromCharCode(parseInt(n.substring(2), 16))
56575 : String.fromCharCode(+n.substring(1));
56581 function replace(regex, opt) {
56582 regex = regex.source;
56584 return function self(name, val) {
56585 if (!name) return new RegExp(regex, opt);
56586 val = val.source || val;
56587 val = val.replace(/(^|[^\[])\^/g, '$1');
56588 regex = regex.replace(name, val);
56596 function merge(obj) {
56601 for (; i < arguments.length; i++) {
56602 target = arguments[i];
56603 for (key in target) {
56604 if (Object.prototype.hasOwnProperty.call(target, key)) {
56605 obj[key] = target[key];
56618 function marked(src, opt, callback) {
56619 if (callback || typeof opt === 'function') {
56625 opt = merge({}, marked.defaults, opt || {});
56627 var highlight = opt.highlight
56633 tokens = Lexer.lex(src, opt);
56635 return callback(e);
56638 pending = tokens.length;
56640 var done = function(err) {
56642 opt.highlight = highlight;
56643 return callback(err);
56649 out = Parser.parse(tokens, opt);
56654 opt.highlight = highlight;
56658 : callback(null, out);
56661 if (!highlight || highlight.length < 3) {
56665 delete opt.highlight;
56667 if (!pending) return done();
56669 for (; i < tokens.length; i++) {
56671 if (token.type !== 'code') {
56672 return --pending || done();
56674 return highlight(token.text, token.lang, function(err, code) {
56675 if (err) return done(err);
56676 if (code == null || code === token.text) {
56677 return --pending || done();
56680 token.escaped = true;
56681 --pending || done();
56689 if (opt) opt = merge({}, marked.defaults, opt);
56690 return Parser.parse(Lexer.lex(src, opt), opt);
56692 e.message += '\nPlease report this to https://github.com/chjj/marked.';
56693 if ((opt || marked.defaults).silent) {
56694 return '<p>An error occured:</p><pre>'
56695 + escape(e.message + '', true)
56707 marked.setOptions = function(opt) {
56708 merge(marked.defaults, opt);
56712 marked.defaults = {
56723 langPrefix: 'lang-',
56724 smartypants: false,
56726 renderer: new Renderer,
56734 marked.Parser = Parser;
56735 marked.parser = Parser.parse;
56737 marked.Renderer = Renderer;
56739 marked.Lexer = Lexer;
56740 marked.lexer = Lexer.lex;
56742 marked.InlineLexer = InlineLexer;
56743 marked.inlineLexer = InlineLexer.output;
56745 marked.parse = marked;
56747 if (typeof module !== 'undefined' && typeof exports === 'object') {
56748 module.exports = marked;
56749 } else if (typeof define === 'function' && define.amd) {
56750 define(function() { return marked; });
56752 this.marked = marked;
56755 }).call(function() {
56756 return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
56760 // toggles the visibility of ui elements, using a combination of the
56761 // hide class, which sets display=none, and a d3 transition for opacity.
56762 // this will cause blinking when called repeatedly, so check that the
56763 // value actually changes between calls.
56764 function uiToggle(show, callback) {
56765 return function(selection$$1) {
56767 .style('opacity', show ? 0 : 1)
56768 .classed('hide', false)
56770 .style('opacity', show ? 1 : 0)
56771 .on('end', function() {
56773 .classed('hide', !show)
56774 .style('opacity', null);
56775 if (callback) callback.apply(this);
56780 // Tooltips and svg mask used to highlight certain features
56781 function d3curtain() {
56783 var dispatch$$1 = dispatch(),
56784 surface = select(null),
56785 tooltip = select(null),
56786 darkness = select(null);
56788 function curtain(selection$$1) {
56789 surface = selection$$1
56791 .attr('id', 'curtain')
56792 .style('z-index', 1000)
56793 .style('pointer-events', 'none')
56794 .style('position', 'absolute')
56798 darkness = surface.append('path')
56801 .attr('class', 'curtain-darkness');
56803 select(window).on('resize.curtain', resize);
56805 tooltip = selection$$1.append('div')
56806 .attr('class', 'tooltip')
56807 .style('z-index', 1002);
56811 .attr('class', 'tooltip-arrow');
56815 .attr('class', 'tooltip-inner');
56820 function resize() {
56822 .attr('width', window.innerWidth)
56823 .attr('height', window.innerHeight);
56824 curtain.cut(darkness.datum());
56829 curtain.reveal = function(box, text$$1, tooltipclass, duration) {
56830 if (typeof box === 'string') box = select(box).node();
56831 if (box.getBoundingClientRect) box = box.getBoundingClientRect();
56833 curtain.cut(box, duration);
56836 // pseudo markdown bold text hack
56837 var parts = text$$1.split('**');
56838 var html$$1 = parts[0] ? '<span>' + parts[0] + '</span>' : '';
56839 if (parts[1]) html$$1 += '<span class="bold">' + parts[1] + '</span>';
56841 var selection$$1 = tooltip
56842 .classed('in', true)
56843 .selectAll('.tooltip-inner')
56846 var dimensions = utilGetDimensions(selection$$1, true),
56847 w = window.innerWidth,
56848 h = window.innerHeight,
56851 // trim box dimensions to just the portion that fits in the window..
56852 if (box.top + box.height > h) {
56853 box.height -= (box.top + box.height - h);
56855 if (box.left + box.width > w) {
56856 box.width -= (box.left + box.width - w);
56859 // determine tooltip placement..
56860 if (box.top + box.height < Math.min(100, box.width + box.left)) {
56862 pos = [box.left + box.width / 2 - dimensions[0] / 2, box.top + box.height];
56864 } else if (box.left + box.width + 300 < w) {
56866 pos = [box.left + box.width, box.top + box.height / 2 - dimensions[1] / 2];
56868 } else if (box.left > 300) {
56870 pos = [box.left - 200, box.top + box.height / 2 - dimensions[1] / 2];
56874 pos = [box.left, box.top + box.height];
56878 Math.min(Math.max(10, pos[0]), w - dimensions[0] - 10),
56879 Math.min(Math.max(10, pos[1]), h - dimensions[1] - 10)
56882 if (duration !== 0 || !tooltip.classed(side)) {
56883 tooltip.call(uiToggle(true));
56887 .style('top', pos[1] + 'px')
56888 .style('left', pos[0] + 'px')
56889 .attr('class', 'curtain-tooltip tooltip in ' + side + ' ' + tooltipclass);
56892 tooltip.call(uiToggle(false));
56897 curtain.cut = function(datum, duration) {
56898 darkness.datum(datum)
56901 (duration === 0 ? darkness : darkness.transition().duration(duration || 600))
56902 .attr('d', function(d) {
56903 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
56904 window.innerWidth + ',' + window.innerHeight + 'L' +
56905 window.innerWidth + ',0 Z';
56907 if (!d) return string;
56908 return string + 'M' +
56909 d.left + ',' + d.top + 'L' +
56910 d.left + ',' + (d.top + d.height) + 'L' +
56911 (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
56912 (d.left + d.width) + ',' + (d.top) + 'Z';
56918 curtain.remove = function() {
56924 return utilRebind(curtain, dispatch$$1, 'on');
56927 var dataIntroGraph = {"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]},"n185964961":{"id":"n185964961","loc":[-85.6406588,41.942601]},"n185964962":{"id":"n185964962","loc":[-85.6394548,41.94261]},"n185970607":{"id":"n185970607","loc":[-85.641094,41.94006]},"n185970614":{"id":"n185970614","loc":[-85.641825,41.941316]},"n185970616":{"id":"n185970616","loc":[-85.641838,41.941556]},"n185973650":{"id":"n185973650","loc":[-85.639918,41.940064]},"n185973660":{"id":"n185973660","loc":[-85.640645,41.941339]},"n185973659":{"id":"n185973659","loc":[-85.6406115,41.9400658]},"n185974479":{"id":"n185974479","loc":[-85.639402,41.941344]},"n185974481":{"id":"n185974481","loc":[-85.643071,41.941288]},"n185976259":{"id":"n185976259","loc":[-85.642213,41.940043]},"n185976261":{"id":"n185976261","loc":[-85.643056,41.94001]},"n185964959":{"id":"n185964959","loc":[-85.6431031,41.9425754]},"n185964960":{"id":"n185964960","loc":[-85.6418749,41.9425864]},"n185981481":{"id":"n185981481","loc":[-85.6386827,41.9400828]},"n185981482":{"id":"n185981482","loc":[-85.6393664,41.9400854]},"n2138493844":{"id":"n2138493844","loc":[-85.6427969,41.940522]},"n2138493845":{"id":"n2138493845","loc":[-85.6425891,41.9405228]},"n2138493846":{"id":"n2138493846","loc":[-85.6425868,41.9402875]},"n2138493847":{"id":"n2138493847","loc":[-85.6427969,41.9402858]},"n2138493848":{"id":"n2138493848","loc":[-85.6425708,41.9405234]},"n2138493849":{"id":"n2138493849","loc":[-85.642568,41.9402855]},"n2138493850":{"id":"n2138493850","loc":[-85.6423157,41.9402886]},"n2138493851":{"id":"n2138493851","loc":[-85.6423212,41.9404362]},"n2138493852":{"id":"n2138493852","loc":[-85.6422923,41.9404578]},"n2138493853":{"id":"n2138493853","loc":[-85.6422868,41.9404834]},"n2138493854":{"id":"n2138493854","loc":[-85.6423226,41.9405091]},"n2138493855":{"id":"n2138493855","loc":[-85.6423847,41.9405111]},"n2138493856":{"id":"n2138493856","loc":[-85.6424081,41.9405265]},"n2140155811":{"id":"n2140155811","loc":[-85.6419547,41.9410956]},"n2140155814":{"id":"n2140155814","loc":[-85.6427577,41.9410884]},"n2140155816":{"id":"n2140155816","loc":[-85.6427545,41.9410052]},"n2140155818":{"id":"n2140155818","loc":[-85.6428057,41.9410028]},"n2140155821":{"id":"n2140155821","loc":[-85.6427993,41.9407339]},"n2140155823":{"id":"n2140155823","loc":[-85.6427385,41.9407339]},"n2140155825":{"id":"n2140155825","loc":[-85.6427417,41.9406435]},"n2140155827":{"id":"n2140155827","loc":[-85.6419515,41.9406482]},"n2140155828":{"id":"n2140155828","loc":[-85.6429368,41.9412407]},"n2140155829":{"id":"n2140155829","loc":[-85.6417756,41.9412526]},"n2140155830":{"id":"n2140155830","loc":[-85.641766,41.9405983]},"n2140155831":{"id":"n2140155831","loc":[-85.6419803,41.9405983]},"n2140155832":{"id":"n2140155832","loc":[-85.6419611,41.9401366]},"n2140155833":{"id":"n2140155833","loc":[-85.6429336,41.94012]},"n2140155834":{"id":"n2140155834","loc":[-85.6430697,41.9411732]},"n2140155835":{"id":"n2140155835","loc":[-85.6428411,41.9409974]},"n2140155837":{"id":"n2140155837","loc":[-85.6428388,41.9407211]},"n2140155839":{"id":"n2140155839","loc":[-85.6430624,41.9405521]},"n2140155840":{"id":"n2140155840","loc":[-85.6427323,41.9412396]},"n2140155842":{"id":"n2140155842","loc":[-85.6418147,41.9412457]},"n2140155844":{"id":"n2140155844","loc":[-85.641813,41.9411319]},"n2140155845":{"id":"n2140155845","loc":[-85.6418394,41.9411111]},"n2140155847":{"id":"n2140155847","loc":[-85.6418838,41.9410977]},"n2140155849":{"id":"n2140155849","loc":[-85.6427324,41.9410921]},"n2140155851":{"id":"n2140155851","loc":[-85.6427798,41.9412945]},"n2140155852":{"id":"n2140155852","loc":[-85.6427701,41.9411777]},"n2140155854":{"id":"n2140155854","loc":[-85.6427323,41.9411572]},"n2140155856":{"id":"n2140155856","loc":[-85.6418478,41.9411666]},"n2165942818":{"id":"n2165942818","loc":[-85.6437533,41.9415029]},"n2165942819":{"id":"n2165942819","loc":[-85.6437623,41.9421195]},"n2168510551":{"id":"n2168510551","loc":[-85.6423795,41.9422615]},"n2168510552":{"id":"n2168510552","loc":[-85.6423744,41.9419439]},"n2168510553":{"id":"n2168510553","loc":[-85.642518,41.9419427]},"n2168510554":{"id":"n2168510554","loc":[-85.6425186,41.9419801]},"n2168510555":{"id":"n2168510555","loc":[-85.6428314,41.9419773]},"n2168510556":{"id":"n2168510556","loc":[-85.6428368,41.9423116]},"n2168510557":{"id":"n2168510557","loc":[-85.6424947,41.9423146]},"n2168510558":{"id":"n2168510558","loc":[-85.6424938,41.9422605]},"n2189046007":{"id":"n2189046007","loc":[-85.6410866,41.9424327]},"n2189046009":{"id":"n2189046009","loc":[-85.6410805,41.9420061]},"n2189046011":{"id":"n2189046011","loc":[-85.6412443,41.9420048]},"n2189046012":{"id":"n2189046012","loc":[-85.6412505,41.9424314]},"n2189046014":{"id":"n2189046014","loc":[-85.6413311,41.942968]},"n2189046016":{"id":"n2189046016","loc":[-85.6413281,41.942713]},"n2189046018":{"id":"n2189046018","loc":[-85.641521,41.9427117]},"n2189046021":{"id":"n2189046021","loc":[-85.6415234,41.9429236]},"n2189046022":{"id":"n2189046022","loc":[-85.6415045,41.9429238]},"n2189046025":{"id":"n2189046025","loc":[-85.641505,41.9429668]},"n2189046053":{"id":"n2189046053","loc":[-85.6385988,41.942412]},"n2189046054":{"id":"n2189046054","loc":[-85.6385985,41.9423311]},"n2189046055":{"id":"n2189046055","loc":[-85.6387617,41.9423308]},"n2189046056":{"id":"n2189046056","loc":[-85.6387616,41.9423026]},"n2189046058":{"id":"n2189046058","loc":[-85.6388215,41.9423025]},"n2189046059":{"id":"n2189046059","loc":[-85.6388219,41.9424115]},"n2189046060":{"id":"n2189046060","loc":[-85.6391096,41.9424486]},"n2189046061":{"id":"n2189046061","loc":[-85.6391105,41.9423673]},"n2189046063":{"id":"n2189046063","loc":[-85.6392911,41.9423684]},"n2189046065":{"id":"n2189046065","loc":[-85.6392903,41.9424497]},"n2189046067":{"id":"n2189046067","loc":[-85.6397927,41.9423876]},"n2189046069":{"id":"n2189046069","loc":[-85.6397897,41.9422981]},"n2189046070":{"id":"n2189046070","loc":[-85.6399702,41.9422947]},"n2189046072":{"id":"n2189046072","loc":[-85.6399732,41.9423843]},"n2189046074":{"id":"n2189046074","loc":[-85.6396331,41.9430227]},"n2189046075":{"id":"n2189046075","loc":[-85.6398673,41.9430189]},"n2189046077":{"id":"n2189046077","loc":[-85.6398656,41.9429637]},"n2189046079":{"id":"n2189046079","loc":[-85.6398885,41.9429633]},"n2189046082":{"id":"n2189046082","loc":[-85.6398832,41.942779]},"n2189046083":{"id":"n2189046083","loc":[-85.6398513,41.9427796]},"n2189046085":{"id":"n2189046085","loc":[-85.6398502,41.9427401]},"n2189046087":{"id":"n2189046087","loc":[-85.6397889,41.9427411]},"n2189046089":{"id":"n2189046089","loc":[-85.6397892,41.942753]},"n2189046090":{"id":"n2189046090","loc":[-85.6396983,41.9427544]},"n2189046092":{"id":"n2189046092","loc":[-85.6396993,41.9427882]},"n2189046094":{"id":"n2189046094","loc":[-85.6396746,41.9427886]},"n2189046096":{"id":"n2189046096","loc":[-85.6396758,41.9428296]},"n2189046097":{"id":"n2189046097","loc":[-85.6397007,41.9428292]},"n2189046099":{"id":"n2189046099","loc":[-85.6397018,41.9428686]},"n2189046103":{"id":"n2189046103","loc":[-85.6396289,41.9428697]},"n2189046112":{"id":"n2189046112","loc":[-85.6435683,41.9429457]},"n2189046113":{"id":"n2189046113","loc":[-85.643568,41.9427766]},"n2189046115":{"id":"n2189046115","loc":[-85.6434011,41.9427767]},"n2189046116":{"id":"n2189046116","loc":[-85.6434012,41.9428631]},"n2189046117":{"id":"n2189046117","loc":[-85.643448,41.9428631]},"n2189046118":{"id":"n2189046118","loc":[-85.6434481,41.9429457]},"n2189046119":{"id":"n2189046119","loc":[-85.6428363,41.9429809]},"n2189046120":{"id":"n2189046120","loc":[-85.6429171,41.9429791]},"n2189046121":{"id":"n2189046121","loc":[-85.642914,41.9429041]},"n2189046122":{"id":"n2189046122","loc":[-85.6429385,41.9429035]},"n2189046123":{"id":"n2189046123","loc":[-85.6429348,41.9428126]},"n2189046124":{"id":"n2189046124","loc":[-85.6427746,41.9428163]},"n2189046125":{"id":"n2189046125","loc":[-85.6427783,41.942906]},"n2189046126":{"id":"n2189046126","loc":[-85.6428332,41.9429047]},"n2189046127":{"id":"n2189046127","loc":[-85.6423018,41.9428859]},"n2189046128":{"id":"n2189046128","loc":[-85.6422987,41.9427208]},"n2189046130":{"id":"n2189046130","loc":[-85.6424218,41.9427195]},"n2189046131":{"id":"n2189046131","loc":[-85.6424246,41.9428684]},"n2189046132":{"id":"n2189046132","loc":[-85.6423845,41.9428689]},"n2189046133":{"id":"n2189046133","loc":[-85.6423848,41.942885]},"n2189046134":{"id":"n2189046134","loc":[-85.641533,41.9429392]},"n2189046135":{"id":"n2189046135","loc":[-85.6416096,41.9428768]},"n2189046137":{"id":"n2189046137","loc":[-85.6416763,41.9429221]},"n2189046138":{"id":"n2189046138","loc":[-85.6415997,41.9429845]},"n2189046139":{"id":"n2189046139","loc":[-85.6420598,41.9428016]},"n2189046140":{"id":"n2189046140","loc":[-85.6420593,41.9427415]},"n2189046141":{"id":"n2189046141","loc":[-85.6421957,41.9427409]},"n2189046142":{"id":"n2189046142","loc":[-85.6421963,41.9428182]},"n2189046143":{"id":"n2189046143","loc":[-85.6421281,41.9428185]},"n2189046144":{"id":"n2189046144","loc":[-85.6421279,41.9428013]},"n2189046145":{"id":"n2189046145","loc":[-85.6409429,41.9429345]},"n2189046146":{"id":"n2189046146","loc":[-85.6410354,41.9429334]},"n2189046147":{"id":"n2189046147","loc":[-85.6410325,41.9427972]},"n2189046148":{"id":"n2189046148","loc":[-85.640997,41.9427976]},"n2189046149":{"id":"n2189046149","loc":[-85.6409963,41.9427643]},"n2189046150":{"id":"n2189046150","loc":[-85.6408605,41.9427659]},"n2189046152":{"id":"n2189046152","loc":[-85.6408623,41.9428482]},"n2189046153":{"id":"n2189046153","loc":[-85.640941,41.9428473]},"n2189152992":{"id":"n2189152992","loc":[-85.6437661,41.9422257]},"n2189152993":{"id":"n2189152993","loc":[-85.643768,41.9424067]},"n2189152994":{"id":"n2189152994","loc":[-85.6432176,41.9417705]},"n2189152995":{"id":"n2189152995","loc":[-85.6432097,41.941327]},"n2189152996":{"id":"n2189152996","loc":[-85.6436493,41.9413226]},"n2189152997":{"id":"n2189152997","loc":[-85.6436563,41.9417164]},"n2189152998":{"id":"n2189152998","loc":[-85.6435796,41.9417171]},"n2189152999":{"id":"n2189152999","loc":[-85.6435805,41.9417669]},"n2189153000":{"id":"n2189153000","loc":[-85.6438202,41.9414953]},"n2189153001":{"id":"n2189153001","loc":[-85.6438173,41.9413175]},"n2189153004":{"id":"n2189153004","loc":[-85.6432535,41.9418466]},"n2189153005":{"id":"n2189153005","loc":[-85.6433935,41.9418599]},"n2189153006":{"id":"n2189153006","loc":[-85.6434831,41.9418986]},"n2189153007":{"id":"n2189153007","loc":[-85.6435678,41.9419774]},"n2189153008":{"id":"n2189153008","loc":[-85.6435987,41.9420282]},"n2189153009":{"id":"n2189153009","loc":[-85.643438,41.9419573]},"n2189153010":{"id":"n2189153010","loc":[-85.6435284,41.9424676]},"n2189153011":{"id":"n2189153011","loc":[-85.6436207,41.9423631]},"n2189153012":{"id":"n2189153012","loc":[-85.6434957,41.9422973]},"n2189153013":{"id":"n2189153013","loc":[-85.6434457,41.9422458]},"n2189153014":{"id":"n2189153014","loc":[-85.6433976,41.9421772]},"n2189153015":{"id":"n2189153015","loc":[-85.6433861,41.9420785]},"n2189153016":{"id":"n2189153016","loc":[-85.6433765,41.9420313]},"n2189153017":{"id":"n2189153017","loc":[-85.6432207,41.9420284]},"n2189153018":{"id":"n2189153018","loc":[-85.6432245,41.9422759]},"n2189153019":{"id":"n2189153019","loc":[-85.6432649,41.9423474]},"n2189153020":{"id":"n2189153020","loc":[-85.6433226,41.9424132]},"n2189153021":{"id":"n2189153021","loc":[-85.6434111,41.9424704]},"n2189153022":{"id":"n2189153022","loc":[-85.6434591,41.9424347]},"n2189153025":{"id":"n2189153025","loc":[-85.6437669,41.9423073]},"n2189153026":{"id":"n2189153026","loc":[-85.6436611,41.942293]},"n2189153027":{"id":"n2189153027","loc":[-85.6435784,41.9422473]},"n2189153028":{"id":"n2189153028","loc":[-85.6435245,41.9421443]},"n2189153029":{"id":"n2189153029","loc":[-85.6435149,41.9420613]},"n2189153030":{"id":"n2189153030","loc":[-85.6433528,41.9419269]},"n2189153031":{"id":"n2189153031","loc":[-85.6432535,41.9419191]},"n2189153032":{"id":"n2189153032","loc":[-85.6430868,41.9419198]},"n2189153033":{"id":"n2189153033","loc":[-85.6434894,41.9420033]},"n2189153034":{"id":"n2189153034","loc":[-85.6432974,41.9419225]},"n2189153035":{"id":"n2189153035","loc":[-85.6433055,41.9421632]},"n2189153036":{"id":"n2189153036","loc":[-85.6433538,41.9422849]},"n2189153037":{"id":"n2189153037","loc":[-85.6434718,41.9423887]},"n2189153038":{"id":"n2189153038","loc":[-85.6436134,41.9422667]},"n2189153040":{"id":"n2189153040","loc":[-85.6438759,41.9414017]},"n2189153041":{"id":"n2189153041","loc":[-85.6438181,41.9413687]},"n2189153042":{"id":"n2189153042","loc":[-85.6436821,41.9413044]},"n2189153043":{"id":"n2189153043","loc":[-85.6435899,41.9412862]},"n2189153044":{"id":"n2189153044","loc":[-85.6433169,41.9417268]},"n2189153045":{"id":"n2189153045","loc":[-85.643301,41.9412859]},"n2189153046":{"id":"n2189153046","loc":[-85.6435531,41.9416981]},"n2189153047":{"id":"n2189153047","loc":[-85.6435427,41.9412863]},"n185948706":{"id":"n185948706","loc":[-85.6369439,41.940122]},"n185949348":{"id":"n185949348","loc":[-85.640039,41.931135]},"n185949870":{"id":"n185949870","loc":[-85.643195,41.949261]},"n185954680":{"id":"n185954680","loc":[-85.6337802,41.9401143]},"n185954784":{"id":"n185954784","loc":[-85.6487485,41.942527]},"n185958670":{"id":"n185958670","loc":[-85.637255,41.940104]},"n185958672":{"id":"n185958672","loc":[-85.636996,41.941355]},"n185960207":{"id":"n185960207","loc":[-85.634992,41.940118]},"n185963163":{"id":"n185963163","loc":[-85.638831,41.93398]},"n185963165":{"id":"n185963165","loc":[-85.640073,41.933968]},"n185963167":{"id":"n185963167","loc":[-85.641225,41.933972]},"n185963168":{"id":"n185963168","loc":[-85.642386,41.933952]},"n185964695":{"id":"n185964695","loc":[-85.6443608,41.9425645]},"n185964697":{"id":"n185964697","loc":[-85.644384,41.939941]},"n185964963":{"id":"n185964963","loc":[-85.6382347,41.9426146]},"n185964965":{"id":"n185964965","loc":[-85.637022,41.942622]},"n185964967":{"id":"n185964967","loc":[-85.6363706,41.9426606]},"n185964968":{"id":"n185964968","loc":[-85.6357988,41.9427748]},"n185964969":{"id":"n185964969","loc":[-85.6355409,41.9428465]},"n185964970":{"id":"n185964970","loc":[-85.6348729,41.9430443]},"n185966958":{"id":"n185966958","loc":[-85.641946,41.946413]},"n185966960":{"id":"n185966960","loc":[-85.643148,41.946389]},"n185967774":{"id":"n185967774","loc":[-85.641889,41.943852]},"n185967775":{"id":"n185967775","loc":[-85.641922,41.945121]},"n185967776":{"id":"n185967776","loc":[-85.641927,41.947544]},"n185967777":{"id":"n185967777","loc":[-85.641982,41.947622]},"n185969289":{"id":"n185969289","loc":[-85.63928,41.929221]},"n185969704":{"id":"n185969704","loc":[-85.6388186,41.9350099]},"n185969706":{"id":"n185969706","loc":[-85.6400709,41.9349957]},"n185969708":{"id":"n185969708","loc":[-85.6412214,41.9349827]},"n185969710":{"id":"n185969710","loc":[-85.6423509,41.934974]},"n185970602":{"id":"n185970602","loc":[-85.641293,41.931817]},"n185970604":{"id":"n185970604","loc":[-85.641258,41.932705]},"n185970605":{"id":"n185970605","loc":[-85.641148,41.936984]},"n185970606":{"id":"n185970606","loc":[-85.641112,41.938169]},"n185970906":{"id":"n185970906","loc":[-85.639454,41.943871]},"n185970908":{"id":"n185970908","loc":[-85.6394635,41.9450504]},"n185970909":{"id":"n185970909","loc":[-85.6394914,41.9451911]},"n185971368":{"id":"n185971368","loc":[-85.635769,41.940122]},"n185971978":{"id":"n185971978","loc":[-85.640003,41.936988]},"n185971980":{"id":"n185971980","loc":[-85.642299,41.936988]},"n185973633":{"id":"n185973633","loc":[-85.639023,41.92861]},"n185973635":{"id":"n185973635","loc":[-85.639153,41.928969]},"n185973637":{"id":"n185973637","loc":[-85.639213,41.929088]},"n185973639":{"id":"n185973639","loc":[-85.63935,41.929396]},"n185973641":{"id":"n185973641","loc":[-85.640143,41.931462]},"n185973644":{"id":"n185973644","loc":[-85.64019,41.931788]},"n185973646":{"id":"n185973646","loc":[-85.6401365,41.9327199]},"n185973648":{"id":"n185973648","loc":[-85.639983,41.938174]},"n185974477":{"id":"n185974477","loc":[-85.638206,41.941331]},"n185975928":{"id":"n185975928","loc":[-85.640683,41.94513]},"n185975930":{"id":"n185975930","loc":[-85.643102,41.945103]},"n185976255":{"id":"n185976255","loc":[-85.642424,41.931817]},"n185976257":{"id":"n185976257","loc":[-85.64242,41.932699]},"n185976258":{"id":"n185976258","loc":[-85.6422621,41.9381489]},"n185977452":{"id":"n185977452","loc":[-85.6457497,41.9398834]},"n185978772":{"id":"n185978772","loc":[-85.646656,41.939869]},"n185981472":{"id":"n185981472","loc":[-85.6388962,41.9321266]},"n185981474":{"id":"n185981474","loc":[-85.6388769,41.9327334]},"n185981476":{"id":"n185981476","loc":[-85.638829,41.934116]},"n185981478":{"id":"n185981478","loc":[-85.63876,41.937002]},"n185981480":{"id":"n185981480","loc":[-85.638682,41.93819]},"n185981999":{"id":"n185981999","loc":[-85.638194,41.9400866]},"n185982001":{"id":"n185982001","loc":[-85.646302,41.93988]},"n185982877":{"id":"n185982877","loc":[-85.640676,41.943867]},"n185982879":{"id":"n185982879","loc":[-85.640734,41.945887]},"n185985823":{"id":"n185985823","loc":[-85.643106,41.943841]},"n185985824":{"id":"n185985824","loc":[-85.643145,41.947641]},"n185985825":{"id":"n185985825","loc":[-85.643219,41.950829]},"n1475301385":{"id":"n1475301385","loc":[-85.6360612,41.9427042]},"n1475301397":{"id":"n1475301397","loc":[-85.6366651,41.9426328]},"n2139795811":{"id":"n2139795811","loc":[-85.6469154,41.9425427]},"n2139795830":{"id":"n2139795830","loc":[-85.6443194,41.9399444]},"n2139795834":{"id":"n2139795834","loc":[-85.6453506,41.9399002]},"n2139795837":{"id":"n2139795837","loc":[-85.645806,41.9398831]},"n2139858932":{"id":"n2139858932","loc":[-85.6351721,41.9429557]},"n2140019000":{"id":"n2140019000","loc":[-85.6359935,41.9427224]},"n2165942817":{"id":"n2165942817","loc":[-85.6442017,41.9414993]},"n2165942820":{"id":"n2165942820","loc":[-85.6442107,41.9421159]},"n2189152990":{"id":"n2189152990","loc":[-85.6442328,41.942404]},"n2189152991":{"id":"n2189152991","loc":[-85.6442309,41.9422229]},"n2189153002":{"id":"n2189153002","loc":[-85.6441329,41.9413147]},"n2189153003":{"id":"n2189153003","loc":[-85.6441357,41.9414925]},"n2189153023":{"id":"n2189153023","loc":[-85.6443453,41.9423074]},"n2189153024":{"id":"n2189153024","loc":[-85.6442318,41.9423045]},"n2189153039":{"id":"n2189153039","loc":[-85.6441343,41.9414025]},"w208643102":{"id":"w208643102","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153034","n2189153035","n2189153036","n2189153037","n2189153038"]},"w17966942":{"id":"w17966942","tags":{"highway":"residential","name":"Millard St"},"nodes":["n185954680","n185960207","n185971368","n185948706","n185958670","n185981999","n185981481","n185981482","n185973650","n185973659","n185970607","n185976259","n185976261","n2139795830","n185964697","n2139795834","n185977452","n2139795837","n185982001","n185978772"]},"w208643105":{"id":"w208643105","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153046","n2189153047"]},"w208631637":{"id":"w208631637","tags":{"area":"yes","building":"yes"},"nodes":["n2189046014","n2189046016","n2189046018","n2189046021","n2189046022","n2189046025","n2189046014"]},"w208643096":{"id":"w208643096","tags":{"amenity":"parking","area":"yes","fee":"no"},"nodes":["n2189152990","n2189153024","n2189152991","n2189152992","n2189153025","n2189152993","n2189152990"]},"w208631656":{"id":"w208631656","tags":{"area":"yes","building":"yes"},"nodes":["n2189046134","n2189046135","n2189046137","n2189046138","n2189046134"]},"w204003417":{"id":"w204003417","tags":{"area":"yes","building":"school"},"nodes":["n2140155811","n2140155814","n2140155816","n2140155818","n2140155821","n2140155823","n2140155825","n2140155827","n2140155811"]},"w208631654":{"id":"w208631654","tags":{"area":"yes","building":"yes"},"nodes":["n2189046127","n2189046128","n2189046130","n2189046131","n2189046132","n2189046133","n2189046127"]},"w17966327":{"id":"w17966327","tags":{"highway":"residential","name":"S Douglas Ave"},"nodes":["n185976261","n2140155839","n2140155834","n185974481","n2189153032","n185964959"]},"w41785752":{"id":"w41785752","tags":{"highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60","access":"yes"},"nodes":["n185954784","n2139795811","n185964695","n185964959","n185964960","n185964961","n185964962","n185964963","n185964965","n1475301397","n185964967","n1475301385","n2140019000","n185964968","n185964969","n2139858932","n185964970"]},"w203841842":{"id":"w203841842","tags":{"area":"yes","leisure":"playground"},"nodes":["n2138493848","n2138493849","n2138493850","n2138493851","n2138493852","n2138493853","n2138493854","n2138493855","n2138493856","n2138493848"]},"w208643103":{"id":"w208643103","tags":{"highway":"service"},"nodes":["n2189153039","n2189153040","n2189153041","n2189153042","n2189153043","n2189153047","n2189153045","n185974481"]},"w208643098":{"id":"w208643098","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153000","n2189153041","n2189153001","n2189153002","n2189153039","n2189153003","n2189153000"]},"w208631646":{"id":"w208631646","tags":{"area":"yes","building":"yes"},"nodes":["n2189046067","n2189046069","n2189046070","n2189046072","n2189046067"]},"w208631653":{"id":"w208631653","tags":{"area":"yes","building":"yes"},"nodes":["n2189046119","n2189046120","n2189046121","n2189046122","n2189046123","n2189046124","n2189046125","n2189046126","n2189046119"]},"w17966041":{"id":"w17966041","tags":{"highway":"residential","name":"S Lincoln Ave"},"nodes":["n185973659","n185973660","n185964961"]},"w208631645":{"id":"w208631645","tags":{"area":"yes","building":"yes"},"nodes":["n2189046060","n2189046061","n2189046063","n2189046065","n2189046060"]},"w206803397":{"id":"w206803397","tags":{"area":"yes","building":"yes"},"nodes":["n2168510551","n2168510552","n2168510553","n2168510554","n2168510555","n2168510556","n2168510557","n2168510558","n2168510551"]},"w17965792":{"id":"w17965792","tags":{"highway":"residential","name":"N Hooker Ave"},"nodes":["n185964962","n185970906","n185970908","n185970909"]},"w208631651":{"id":"w208631651","tags":{"area":"yes","building":"yes"},"nodes":["n2189046112","n2189046113","n2189046115","n2189046116","n2189046117","n2189046118","n2189046112"]},"w208631643":{"id":"w208631643","tags":{"area":"yes","building":"yes"},"nodes":["n2189046053","n2189046054","n2189046055","n2189046056","n2189046058","n2189046059","n2189046053"]},"w17966878":{"id":"w17966878","tags":{"highway":"residential","name":"S Hooker Ave"},"nodes":["n185981472","n185981474","n185963163","n185981476","n185969704","n185981478","n185981480","n185981481"]},"w17966102":{"id":"w17966102","tags":{"highway":"residential","name":"South St"},"nodes":["n185958672","n185974477","n185974479","n185973660","n185970614"]},"w208631660":{"id":"w208631660","tags":{"area":"yes","building":"yes"},"nodes":["n2189046145","n2189046146","n2189046147","n2189046148","n2189046149","n2189046150","n2189046152","n2189046153","n2189046145"]},"w208643101":{"id":"w208643101","tags":{"highway":"service"},"nodes":["n2189153023","n2189153024","n2189153025","n2189153026","n2189153038","n2189153027","n2189153028","n2189153029","n2189153033","n2189153009","n2189153030","n2189153034","n2189153031","n2189153032"]},"w204000205":{"id":"w204000205","tags":{"highway":"residential","name":"South St","oneway":"yes"},"nodes":["n185974481","n2140155851","n185970614"]},"w203841841":{"id":"w203841841","tags":{"area":"yes","leisure":"pitch","pitch":"basketball"},"nodes":["n2138493844","n2138493845","n2138493846","n2138493847","n2138493844"]},"w17965444":{"id":"w17965444","tags":{"highway":"residential","name":"N Grant Ave"},"nodes":["n185964960","n185967774","n185967775","n185966958","n185967776","n185967777"]},"w208631648":{"id":"w208631648","tags":{"area":"yes","building":"yes"},"nodes":["n2189046074","n2189046075","n2189046077","n2189046079","n2189046082","n2189046083","n2189046085","n2189046087","n2189046089","n2189046090","n2189046092","n2189046094","n2189046096","n2189046097","n2189046099","n2189046103","n2189046074"]},"w208643100":{"id":"w208643100","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153010","n2189153011","n2189153012","n2189153013","n2189153014","n2189153015","n2189153016","n2189153017","n2189153018","n2189153019","n2189153020","n2189153021","n2189153022","n2189153010"]},"w17965749":{"id":"w17965749","tags":{"highway":"residential","name":"S Grant Ave"},"nodes":["n185970614","n185970616","n185964960"]},"w206574482":{"id":"w206574482","tags":{"amenity":"library","area":"yes","building":"yes","name":"Three Rivers Public Library"},"nodes":["n2165942817","n2165942818","n2165942819","n2165942820","n2165942817"]},"w208643097":{"id":"w208643097","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189152994","n2189152995","n2189152996","n2189152997","n2189152998","n2189152999","n2189152994"]},"w17966879":{"id":"w17966879","tags":{"highway":"residential","name":"S Hooker Ave"},"nodes":["n185981482","n185974479","n185964962"]},"w17966325":{"id":"w17966325","tags":{"highway":"residential","name":"S Douglas Ave"},"nodes":["n185976255","n185976257","n185963168","n185969710","n185971980","n185976258","n185954700","n185976259"]},"w17967390":{"id":"w17967390","tags":{"highway":"residential","name":"N Douglas Ave"},"nodes":["n185964959","n185985823","n185975930","n185966960","n185985824","n185949870","n185985825"]},"w208631635":{"id":"w208631635","tags":{"area":"yes","building":"yes"},"nodes":["n2189046007","n2189046009","n2189046011","n2189046012","n2189046007"]},"w208643099":{"id":"w208643099","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153031","n2189153004","n2189153005","n2189153006","n2189153007","n2189153008","n2189153029","n2189153033","n2189153009","n2189153030","n2189153031"]},"w208631658":{"id":"w208631658","tags":{"area":"yes","building":"yes"},"nodes":["n2189046139","n2189046140","n2189046141","n2189046142","n2189046143","n2189046144","n2189046139"]},"w208643104":{"id":"w208643104","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153044","n2189153045"]},"w17966039":{"id":"w17966039","tags":{"highway":"residential","name":"S Lincoln Ave"},"nodes":["n185973633","n185973635","n185973637","n185969289","n185973639","n185949348","n185973641","n185973644","n185973646","n185963165","n185969706","n185971978","n185973648","n185973650"]},"w204003420":{"id":"w204003420","tags":{"amenity":"parking","area":"yes"},"nodes":["n2140155840","n2140155842","n2140155844","n2140155845","n2140155847","n2140155849","n2140155854","n2140155840"]},"w204003419":{"id":"w204003419","tags":{"highway":"service"},"nodes":["n2140155834","n2140155835","n2140155837","n2140155839"]},"w204003418":{"id":"w204003418","tags":{"amenity":"school","area":"yes","name":"Andrews Elementary School"},"nodes":["n2140155828","n2140155829","n2140155830","n2140155831","n2140155832","n2140155833","n2140155828"]},"w17965747":{"id":"w17965747","tags":{"highway":"residential","name":"S Grant Ave"},"nodes":["n185970602","n185970604","n185963167","n185969708","n185970605","n185970606","n185970607"]},"w17967073":{"id":"w17967073","tags":{"highway":"residential","name":"N Lincoln Ave"},"nodes":["n185964961","n185982877","n185975928","n185982879"]},"w204003421":{"id":"w204003421","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2140155851","n2140155852","n2140155854","n2140155856"]},"r1943857":{"id":"r1943857","tags":{"modifier":"Business","name":"US 131 Business (Three Rivers, MI)","network":"US:US","ref":"131","route":"road","type":"route"},"members":[{"id":"w17966509","type":"way","role":"forward"},{"id":"w143497377","type":"way","role":""},{"id":"w134150811","type":"way","role":""},{"id":"w134150800","type":"way","role":""},{"id":"w134150789","type":"way","role":""},{"id":"w134150795","type":"way","role":""},{"id":"w41785752","type":"way","role":""},{"id":"w17965146","type":"way","role":"forward"},{"id":"w17964031","type":"way","role":"forward"}]},"r270277":{"id":"r270277","tags":{"network":"US:MI","ref":"60","route":"road","state_id":"MI","type":"route","url":"http://en.wikipedia.org/wiki/M-60_%28Michigan_highway%29"},"members":[{"id":"w17751087","type":"way","role":"east"},{"id":"w117148312","type":"way","role":"east"},{"id":"w40942155","type":"way","role":"west"},{"id":"w17751017","type":"way","role":""},{"id":"w17751083","type":"way","role":""},{"id":"w17747780","type":"way","role":""},{"id":"w41068082","type":"way","role":""},{"id":"w197025212","type":"way","role":""},{"id":"w17743874","type":"way","role":""},{"id":"w17751044","type":"way","role":""},{"id":"w17752167","type":"way","role":""},{"id":"w17751089","type":"way","role":""},{"id":"w17743879","type":"way","role":""},{"id":"w17751064","type":"way","role":""},{"id":"w197057073","type":"way","role":""},{"id":"w167699963","type":"way","role":""},{"id":"w167699972","type":"way","role":""},{"id":"w17967584","type":"way","role":""},{"id":"w167699964","type":"way","role":""},{"id":"w17967582","type":"way","role":"west"},{"id":"w41260270","type":"way","role":"west"},{"id":"w17965146","type":"way","role":"west"},{"id":"w41785752","type":"way","role":""},{"id":"w134150795","type":"way","role":""},{"id":"w134150789","type":"way","role":""},{"id":"w134150800","type":"way","role":""},{"id":"w134150811","type":"way","role":""},{"id":"w134150836","type":"way","role":""},{"id":"w134150802","type":"way","role":""},{"id":"w41074896","type":"way","role":""},{"id":"w17966773","type":"way","role":""},{"id":"w17967415","type":"way","role":""},{"id":"w41074899","type":"way","role":""},{"id":"w17967581","type":"way","role":""},{"id":"w41074902","type":"way","role":""},{"id":"w41074906","type":"way","role":""},{"id":"w209707997","type":"way","role":""},{"id":"w209707998","type":"way","role":""},{"id":"w17964798","type":"way","role":""},{"id":"w17966034","type":"way","role":""},{"id":"w17967593","type":"way","role":""},{"id":"w41074888","type":"way","role":""},{"id":"w17733772","type":"way","role":""},{"id":"w41074813","type":"way","role":""},{"id":"w17742213","type":"way","role":""},{"id":"w17746863","type":"way","role":""},{"id":"w17745772","type":"way","role":""},{"id":"w17742222","type":"way","role":""},{"id":"w17745922","type":"way","role":""},{"id":"w17742198","type":"way","role":""},{"id":"w17747675","type":"way","role":""},{"id":"w17739927","type":"way","role":""},{"id":"w17745708","type":"way","role":""},{"id":"w41006323","type":"way","role":""},{"id":"w17744233","type":"way","role":""},{"id":"w17739436","type":"way","role":""},{"id":"w17742201","type":"way","role":""},{"id":"w151418616","type":"way","role":""},{"id":"w17750062","type":"way","role":""},{"id":"w17742227","type":"way","role":"east"},{"id":"w41006348","type":"way","role":"east"},{"id":"w41260984","type":"way","role":""},{"id":"w17832427","type":"way","role":""},{"id":"w17838408","type":"way","role":""},{"id":"w17835846","type":"way","role":""},{"id":"w17832923","type":"way","role":""},{"id":"w17839388","type":"way","role":""},{"id":"w17838390","type":"way","role":""},{"id":"w17831272","type":"way","role":""},{"id":"w17828581","type":"way","role":""},{"id":"w38240686","type":"way","role":""},{"id":"w17838405","type":"way","role":"east"},{"id":"w123323711","type":"way","role":"east"},{"id":"w17830167","type":"way","role":"east"},{"id":"w99011909","type":"way","role":"east"},{"id":"w41911361","type":"way","role":"east"},{"id":"w41911355","type":"way","role":"east"},{"id":"w41911356","type":"way","role":"east"},{"id":"w117148326","type":"way","role":"west"},{"id":"w41911352","type":"way","role":"west"},{"id":"w41911353","type":"way","role":"west"},{"id":"w41911354","type":"way","role":"west"},{"id":"w41911360","type":"way","role":"west"},{"id":"w38240676","type":"way","role":"west"},{"id":"w123323710","type":"way","role":"west"},{"id":"w41260271","type":"way","role":"east"},{"id":"w41260273","type":"way","role":"east"},{"id":"w17964031","type":"way","role":"east"},{"id":"w41006344","type":"way","role":"west"},{"id":"w41006351","type":"way","role":"west"}]},"n367813436":{"id":"n367813436","loc":[-85.63605205663384,41.94305506683346],"tags":{"amenity":"fire_station","name":"Three Rivers Fire Department"}},"n185948708":{"id":"n185948708","loc":[-85.6369828,41.9408789]},"n185948710":{"id":"n185948710","loc":[-85.6370184,41.9411346]},"n185954691":{"id":"n185954691","loc":[-85.634476,41.941475]},"n185954692":{"id":"n185954692","loc":[-85.635008,41.941846]},"n185954693":{"id":"n185954693","loc":[-85.635362,41.941962]},"n185954695":{"id":"n185954695","loc":[-85.63578,41.941978]},"n185972903":{"id":"n185972903","loc":[-85.63295,41.9430062]},"n185964971":{"id":"n185964971","loc":[-85.6346811,41.9431023]},"n1819805854":{"id":"n1819805854","loc":[-85.6331275,41.9404837]},"n1819805918":{"id":"n1819805918","loc":[-85.6331168,41.942798]},"n1819805762":{"id":"n1819805762","loc":[-85.6333034,41.9424123]},"n1819805907":{"id":"n1819805907","loc":[-85.6334819,41.9419121]},"n1819805915":{"id":"n1819805915","loc":[-85.6334554,41.9413588]},"n1819848888":{"id":"n1819848888","loc":[-85.6331625,41.942679]},"n1819848930":{"id":"n1819848930","loc":[-85.6338684,41.9431252]},"n1819858505":{"id":"n1819858505","loc":[-85.6346782,41.9429092]},"n1819858507":{"id":"n1819858507","loc":[-85.6339003,41.9414534]},"n1819858508":{"id":"n1819858508","loc":[-85.6345709,41.9427742]},"n1819858509":{"id":"n1819858509","loc":[-85.63419,41.9417322]},"n1819858511":{"id":"n1819858511","loc":[-85.6340666,41.9415652]},"n1819858512":{"id":"n1819858512","loc":[-85.6343295,41.9423027]},"n1819858514":{"id":"n1819858514","loc":[-85.6343241,41.942207]},"n1819858521":{"id":"n1819858521","loc":[-85.633391,41.941231]},"n1819858528":{"id":"n1819858528","loc":[-85.6343027,41.9419716]},"n185954683":{"id":"n185954683","loc":[-85.6335412,41.940147]},"n185954685":{"id":"n185954685","loc":[-85.6334296,41.9403023]},"n185954687":{"id":"n185954687","loc":[-85.6333988,41.9404704]},"n185954689":{"id":"n185954689","loc":[-85.6335511,41.9410225]},"n185954690":{"id":"n185954690","loc":[-85.6336721,41.9411669]},"n1820938802":{"id":"n1820938802","loc":[-85.6330671,41.941845]},"n1821006702":{"id":"n1821006702","loc":[-85.6344047,41.9395496]},"n2130304133":{"id":"n2130304133","loc":[-85.6349025,41.9427659]},"n2130304136":{"id":"n2130304136","loc":[-85.6346027,41.9422017]},"n2130304138":{"id":"n2130304138","loc":[-85.6348577,41.9421517]},"n2130304140":{"id":"n2130304140","loc":[-85.6348419,41.9422694]},"n2130304142":{"id":"n2130304142","loc":[-85.6349071,41.9423135]},"n2130304144":{"id":"n2130304144","loc":[-85.6350495,41.9423312]},"n2130304146":{"id":"n2130304146","loc":[-85.6351009,41.9422812]},"n2130304147":{"id":"n2130304147","loc":[-85.6351227,41.9421532]},"n2130304148":{"id":"n2130304148","loc":[-85.635526,41.9421547]},"n2130304149":{"id":"n2130304149","loc":[-85.6355339,41.9425768]},"n2130304150":{"id":"n2130304150","loc":[-85.6351582,41.9426562]},"n2130304151":{"id":"n2130304151","loc":[-85.6351207,41.9427032]},"n2138493807":{"id":"n2138493807","loc":[-85.6350923,41.9415216]},"n2138493808":{"id":"n2138493808","loc":[-85.6353603,41.9411061]},"n2138493809":{"id":"n2138493809","loc":[-85.6354421,41.9410942]},"n2138493810":{"id":"n2138493810","loc":[-85.6355079,41.9411044]},"n2138493811":{"id":"n2138493811","loc":[-85.6355693,41.9411246]},"n2138493812":{"id":"n2138493812","loc":[-85.6355829,41.9411061]},"n2138493813":{"id":"n2138493813","loc":[-85.6355624,41.9409777]},"n2138493814":{"id":"n2138493814","loc":[-85.6355011,41.9409152]},"n2138493815":{"id":"n2138493815","loc":[-85.635383,41.9409219]},"n2138493816":{"id":"n2138493816","loc":[-85.635299,41.9409658]},"n2138493817":{"id":"n2138493817","loc":[-85.6351695,41.941204]},"n2138493818":{"id":"n2138493818","loc":[-85.6348879,41.9415166]},"n2138493819":{"id":"n2138493819","loc":[-85.634897,41.9415757]},"n2138493820":{"id":"n2138493820","loc":[-85.6349606,41.9416399]},"n2138493821":{"id":"n2138493821","loc":[-85.6350219,41.9416669]},"n2138493822":{"id":"n2138493822","loc":[-85.6351241,41.9416314]},"n2138493823":{"id":"n2138493823","loc":[-85.6350855,41.9415622]},"n2138493824":{"id":"n2138493824","loc":[-85.6350401,41.9413603]},"n2138493825":{"id":"n2138493825","loc":[-85.6352206,41.9410765]},"n2138493826":{"id":"n2138493826","loc":[-85.6343865,41.9415594]},"n2138493827":{"id":"n2138493827","loc":[-85.6343506,41.9415873]},"n2138493828":{"id":"n2138493828","loc":[-85.6344158,41.9417557]},"n2138493829":{"id":"n2138493829","loc":[-85.6344614,41.9417968]},"n2138493830":{"id":"n2138493830","loc":[-85.6345005,41.9418186]},"n2138493831":{"id":"n2138493831","loc":[-85.6345965,41.9418162]},"n2138493832":{"id":"n2138493832","loc":[-85.6347317,41.9417242]},"n2138493833":{"id":"n2138493833","loc":[-85.6346722,41.941775]},"n2139858909":{"id":"n2139858909","loc":[-85.633403,41.9391006]},"n2139858910":{"id":"n2139858910","loc":[-85.6332973,41.9393967]},"n2139858911":{"id":"n2139858911","loc":[-85.633205,41.9396742]},"n2139858912":{"id":"n2139858912","loc":[-85.6332203,41.9397772]},"n2139858913":{"id":"n2139858913","loc":[-85.6333453,41.939936]},"n2139858914":{"id":"n2139858914","loc":[-85.6333761,41.9400018]},"n2139858915":{"id":"n2139858915","loc":[-85.63328,41.9402249]},"n2139858916":{"id":"n2139858916","loc":[-85.6332357,41.9403523]},"n2139858917":{"id":"n2139858917","loc":[-85.6332838,41.9405831]},"n2139858918":{"id":"n2139858918","loc":[-85.6333643,41.9408744]},"n2139858919":{"id":"n2139858919","loc":[-85.6334394,41.9410519]},"n2139858920":{"id":"n2139858920","loc":[-85.6335815,41.9411717]},"n2139858921":{"id":"n2139858921","loc":[-85.6337478,41.9412734]},"n2139858922":{"id":"n2139858922","loc":[-85.6343174,41.9415268]},"n2139858923":{"id":"n2139858923","loc":[-85.6343886,41.9417397]},"n2139858924":{"id":"n2139858924","loc":[-85.6344407,41.9418015]},"n2139858925":{"id":"n2139858925","loc":[-85.6345139,41.9418366]},"n2139858926":{"id":"n2139858926","loc":[-85.6344846,41.942005]},"n2139858927":{"id":"n2139858927","loc":[-85.6345775,41.9422218]},"n2139858928":{"id":"n2139858928","loc":[-85.6348771,41.9427814]},"n2139858929":{"id":"n2139858929","loc":[-85.6349487,41.9427995]},"n2139858930":{"id":"n2139858930","loc":[-85.6350415,41.9427874]},"n2139858931":{"id":"n2139858931","loc":[-85.6351246,41.9428589]},"n2139858978":{"id":"n2139858978","loc":[-85.6349658,41.9431481]},"n2139858979":{"id":"n2139858979","loc":[-85.6350081,41.9431287]},"n2139858980":{"id":"n2139858980","loc":[-85.6349967,41.9430997]},"n2139858981":{"id":"n2139858981","loc":[-85.6352158,41.9430352]},"n2139858982":{"id":"n2139858982","loc":[-85.6348174,41.94267]},"n2139858983":{"id":"n2139858983","loc":[-85.6346142,41.9425989]},"n2139858984":{"id":"n2139858984","loc":[-85.6344938,41.9423809]},"n2139858985":{"id":"n2139858985","loc":[-85.6344856,41.9422997]},"n2139870380":{"id":"n2139870380","loc":[-85.6346707,41.9417955]},"n2139870381":{"id":"n2139870381","loc":[-85.6345949,41.9418311]},"n2139870382":{"id":"n2139870382","loc":[-85.6343322,41.9418659]},"n2139870383":{"id":"n2139870383","loc":[-85.6342072,41.941885]},"n2139870384":{"id":"n2139870384","loc":[-85.6341325,41.9418919]},"n2139870385":{"id":"n2139870385","loc":[-85.6341314,41.9422028]},"n2139870386":{"id":"n2139870386","loc":[-85.6340472,41.9423271]},"n2139870387":{"id":"n2139870387","loc":[-85.6342185,41.9427933]},"n2139870388":{"id":"n2139870388","loc":[-85.6340605,41.9423924]},"n2139870389":{"id":"n2139870389","loc":[-85.6339889,41.9424069]},"n2139870390":{"id":"n2139870390","loc":[-85.633971,41.942356]},"n2139870391":{"id":"n2139870391","loc":[-85.63361,41.9424235]},"n2139870392":{"id":"n2139870392","loc":[-85.6337137,41.9426819]},"n2139870393":{"id":"n2139870393","loc":[-85.6336977,41.9428632]},"n2139870394":{"id":"n2139870394","loc":[-85.6338823,41.9428647]},"n2139870395":{"id":"n2139870395","loc":[-85.6339412,41.9430069]},"n2139870396":{"id":"n2139870396","loc":[-85.6338873,41.9430353]},"n2139870397":{"id":"n2139870397","loc":[-85.6337676,41.942815]},"n2139870398":{"id":"n2139870398","loc":[-85.6336822,41.9423505]},"n2139870399":{"id":"n2139870399","loc":[-85.634037,41.9422725]},"n2139870400":{"id":"n2139870400","loc":[-85.6340294,41.9422518]},"n2139870401":{"id":"n2139870401","loc":[-85.6336726,41.9423312]},"n2139870402":{"id":"n2139870402","loc":[-85.6342188,41.9425715]},"n2139870403":{"id":"n2139870403","loc":[-85.6342524,41.942565]},"n2139870404":{"id":"n2139870404","loc":[-85.6341438,41.942299]},"n2139870405":{"id":"n2139870405","loc":[-85.6341149,41.9423061]},"n2139870407":{"id":"n2139870407","loc":[-85.6340846,41.9431458]},"n2139870408":{"id":"n2139870408","loc":[-85.6339436,41.9429032]},"n2139870409":{"id":"n2139870409","loc":[-85.6343143,41.9428207]},"n2139870410":{"id":"n2139870410","loc":[-85.6343507,41.94277]},"n2139870411":{"id":"n2139870411","loc":[-85.6341527,41.942254]},"n2139870412":{"id":"n2139870412","loc":[-85.6340925,41.9422199]},"n2139870413":{"id":"n2139870413","loc":[-85.6335435,41.9423433]},"n2139870414":{"id":"n2139870414","loc":[-85.6335023,41.9423975]},"n2139870415":{"id":"n2139870415","loc":[-85.6335086,41.9424552]},"n2139870416":{"id":"n2139870416","loc":[-85.6336296,41.942665]},"n2139870417":{"id":"n2139870417","loc":[-85.6341396,41.9428596]},"n2139870418":{"id":"n2139870418","loc":[-85.6339701,41.9424487]},"n2139870419":{"id":"n2139870419","loc":[-85.6335514,41.9425294]},"n2139870420":{"id":"n2139870420","loc":[-85.6337406,41.9424929]},"n2139870421":{"id":"n2139870421","loc":[-85.6338939,41.9428687]},"n2139870422":{"id":"n2139870422","loc":[-85.6341323,41.9419538]},"n2139870423":{"id":"n2139870423","loc":[-85.6340321,41.9420376]},"n2139870424":{"id":"n2139870424","loc":[-85.6337648,41.942238]},"n2139870425":{"id":"n2139870425","loc":[-85.6337604,41.9422685]},"n2139870426":{"id":"n2139870426","loc":[-85.6337682,41.9422928]},"n2139870427":{"id":"n2139870427","loc":[-85.6338086,41.9423862]},"n2139870428":{"id":"n2139870428","loc":[-85.6349465,41.9416631]},"n2139870429":{"id":"n2139870429","loc":[-85.6351097,41.9416973]},"n2139870430":{"id":"n2139870430","loc":[-85.6353371,41.9416798]},"n2139870431":{"id":"n2139870431","loc":[-85.6349627,41.9422506]},"n2139870432":{"id":"n2139870432","loc":[-85.634979,41.9421815]},"n2139870433":{"id":"n2139870433","loc":[-85.634885,41.9421679]},"n2139870434":{"id":"n2139870434","loc":[-85.6348689,41.9422377]},"n2139870435":{"id":"n2139870435","loc":[-85.6349779,41.9419486]},"n2139870436":{"id":"n2139870436","loc":[-85.6349505,41.9418933]},"n2139870437":{"id":"n2139870437","loc":[-85.6347327,41.9419505]},"n2139870438":{"id":"n2139870438","loc":[-85.6347614,41.9420087]},"n2139870439":{"id":"n2139870439","loc":[-85.6351889,41.9416912]},"n2139870440":{"id":"n2139870440","loc":[-85.6351092,41.9418426]},"n2139870441":{"id":"n2139870441","loc":[-85.635086,41.9419659]},"n2139870442":{"id":"n2139870442","loc":[-85.6350584,41.9421466]},"n2139870443":{"id":"n2139870443","loc":[-85.6350993,41.9421606]},"n2139870444":{"id":"n2139870444","loc":[-85.6350993,41.9422132]},"n2139870445":{"id":"n2139870445","loc":[-85.6350794,41.9422855]},"n2139870446":{"id":"n2139870446","loc":[-85.6350474,41.9423159]},"n2139870447":{"id":"n2139870447","loc":[-85.6349251,41.9422998]},"n2139870448":{"id":"n2139870448","loc":[-85.634911,41.9422755]},"n2139870449":{"id":"n2139870449","loc":[-85.6349157,41.9422553]},"n2139870450":{"id":"n2139870450","loc":[-85.6347213,41.9419324]},"n2139870451":{"id":"n2139870451","loc":[-85.6349535,41.9418771]},"n2139870452":{"id":"n2139870452","loc":[-85.6350135,41.9419421]},"n2139870453":{"id":"n2139870453","loc":[-85.6348584,41.9418997]},"n2139870454":{"id":"n2139870454","loc":[-85.6348113,41.9418101]},"n2139870455":{"id":"n2139870455","loc":[-85.6347306,41.9417449]},"n2139870456":{"id":"n2139870456","loc":[-85.6349123,41.941776]},"n2139870457":{"id":"n2139870457","loc":[-85.6349423,41.9421448]},"n2139870458":{"id":"n2139870458","loc":[-85.6349436,41.9420652]},"n2139870459":{"id":"n2139870459","loc":[-85.6349136,41.9419963]},"n2139870460":{"id":"n2139870460","loc":[-85.6349814,41.9419789]},"n2139989328":{"id":"n2139989328","loc":[-85.6334188,41.9421725]},"n2139989330":{"id":"n2139989330","loc":[-85.6335087,41.9416308]},"n2139989335":{"id":"n2139989335","loc":[-85.6336856,41.9429371]},"n2139989337":{"id":"n2139989337","loc":[-85.6333713,41.9427217]},"n2139989339":{"id":"n2139989339","loc":[-85.6332912,41.9425383]},"n2139989341":{"id":"n2139989341","loc":[-85.6339369,41.9409198]},"n2139989344":{"id":"n2139989344","loc":[-85.634097,41.9409469]},"n2139989346":{"id":"n2139989346","loc":[-85.634137,41.9412852]},"n2139989348":{"id":"n2139989348","loc":[-85.6344536,41.9414151]},"n2139989350":{"id":"n2139989350","loc":[-85.6350794,41.9412392]},"n2139989351":{"id":"n2139989351","loc":[-85.6352541,41.9409387]},"n2139989353":{"id":"n2139989353","loc":[-85.6357198,41.9408007]},"n2139989355":{"id":"n2139989355","loc":[-85.6357235,41.9427088]},"n2139989357":{"id":"n2139989357","loc":[-85.6337119,41.9421256]},"n2139989359":{"id":"n2139989359","loc":[-85.6336913,41.9420655]},"n2139989360":{"id":"n2139989360","loc":[-85.633582,41.9420867]},"n2139989362":{"id":"n2139989362","loc":[-85.6336058,41.9421491]},"n2139989364":{"id":"n2139989364","loc":[-85.6339685,41.9410995]},"n2139989366":{"id":"n2139989366","loc":[-85.6339067,41.9411383]},"n2139989368":{"id":"n2139989368","loc":[-85.6339685,41.9411972]},"n2139989370":{"id":"n2139989370","loc":[-85.6340398,41.9411619]},"n2139870379":{"id":"n2139870379","loc":[-85.6348391,41.9416651]},"n2140006363":{"id":"n2140006363","loc":[-85.6353144,41.9430345]},"n2140006364":{"id":"n2140006364","loc":[-85.6349191,41.9431422]},"n2140018997":{"id":"n2140018997","loc":[-85.63645945147184,41.942986488012565],"tags":{"amenity":"townhall","name":"Three Rivers City Hall"}},"n2140018998":{"id":"n2140018998","loc":[-85.6370319,41.9427919]},"n2140018999":{"id":"n2140018999","loc":[-85.6360687,41.9427808]},"n2199856288":{"id":"n2199856288","loc":[-85.6344968,41.9407307]},"n2199856289":{"id":"n2199856289","loc":[-85.634492,41.9406036]},"n2199856290":{"id":"n2199856290","loc":[-85.634891,41.9406001]},"n2199856291":{"id":"n2199856291","loc":[-85.6348894,41.9405288]},"n2199856292":{"id":"n2199856292","loc":[-85.6349166,41.94053]},"n2199856293":{"id":"n2199856293","loc":[-85.6349166,41.9404956]},"n2199856294":{"id":"n2199856294","loc":[-85.6350219,41.9404956]},"n2199856295":{"id":"n2199856295","loc":[-85.6350251,41.94053]},"n2199856296":{"id":"n2199856296","loc":[-85.6350538,41.9405288]},"n2199856297":{"id":"n2199856297","loc":[-85.6350602,41.94079]},"n2199856298":{"id":"n2199856298","loc":[-85.6351703,41.9407912]},"n2199856299":{"id":"n2199856299","loc":[-85.6351688,41.9409171]},"n2199856300":{"id":"n2199856300","loc":[-85.6347889,41.9409135]},"n2199856301":{"id":"n2199856301","loc":[-85.6347921,41.94079]},"n2199856302":{"id":"n2199856302","loc":[-85.6348942,41.9407888]},"n2199856303":{"id":"n2199856303","loc":[-85.6348926,41.9407283]},"n185951869":{"id":"n185951869","loc":[-85.6387639,41.957288]},"n185958643":{"id":"n185958643","loc":[-85.636746,41.929221]},"n185958645":{"id":"n185958645","loc":[-85.636791,41.929363]},"n185958647":{"id":"n185958647","loc":[-85.6375975,41.9314987]},"n185958649":{"id":"n185958649","loc":[-85.637669,41.931667]},"n185958651":{"id":"n185958651","loc":[-85.637728,41.931901]},"n185958653":{"id":"n185958653","loc":[-85.637724,41.932187]},"n185958656":{"id":"n185958656","loc":[-85.637732,41.932761]},"n185958658":{"id":"n185958658","loc":[-85.637688,41.93398]},"n185958660":{"id":"n185958660","loc":[-85.637685,41.934223]},"n185958662":{"id":"n185958662","loc":[-85.6376468,41.9350232]},"n185958664":{"id":"n185958664","loc":[-85.637564,41.937028]},"n185958666":{"id":"n185958666","loc":[-85.637458,41.938197]},"n185958668":{"id":"n185958668","loc":[-85.637424,41.938692]},"n185964972":{"id":"n185964972","loc":[-85.6341901,41.9432732]},"n185971361":{"id":"n185971361","loc":[-85.635762,41.938208]},"n185971364":{"id":"n185971364","loc":[-85.635732,41.9384]},"n185971366":{"id":"n185971366","loc":[-85.635736,41.938697]},"n185972775":{"id":"n185972775","loc":[-85.635638,42.070357]},"n185972777":{"id":"n185972777","loc":[-85.635724,42.069929]},"n185972779":{"id":"n185972779","loc":[-85.635804,42.069248]},"n185972781":{"id":"n185972781","loc":[-85.635869,42.068361]},"n185972783":{"id":"n185972783","loc":[-85.635883,42.067582]},"n185972785":{"id":"n185972785","loc":[-85.635875,42.067114]},"n185972787":{"id":"n185972787","loc":[-85.635778,42.065359]},"n185972788":{"id":"n185972788","loc":[-85.635728,42.063416]},"n185972789":{"id":"n185972789","loc":[-85.635665,42.062491]},"n185972790":{"id":"n185972790","loc":[-85.635617,42.061928]},"n185972791":{"id":"n185972791","loc":[-85.635614,42.061898]},"n185972793":{"id":"n185972793","loc":[-85.635379,42.060288]},"n185972795":{"id":"n185972795","loc":[-85.635092,42.05799]},"n185972797":{"id":"n185972797","loc":[-85.634843,42.055781]},"n185972798":{"id":"n185972798","loc":[-85.634817,42.055549]},"n185972800":{"id":"n185972800","loc":[-85.634708,42.053942]},"n185972802":{"id":"n185972802","loc":[-85.634447,42.051809]},"n185972805":{"id":"n185972805","loc":[-85.634241,42.04946]},"n185972807":{"id":"n185972807","loc":[-85.633787,42.045926]},"n185972809":{"id":"n185972809","loc":[-85.633811,42.045645]},"n185972811":{"id":"n185972811","loc":[-85.63373,42.043626]},"n185972813":{"id":"n185972813","loc":[-85.633698,42.042184]},"n185972814":{"id":"n185972814","loc":[-85.63369,42.04181]},"n185972815":{"id":"n185972815","loc":[-85.633681,42.040714]},"n185972816":{"id":"n185972816","loc":[-85.633571,42.036322]},"n185972817":{"id":"n185972817","loc":[-85.633537,42.034044]},"n185972819":{"id":"n185972819","loc":[-85.633481,42.030785]},"n185972821":{"id":"n185972821","loc":[-85.633452,42.027538]},"n185972824":{"id":"n185972824","loc":[-85.633438,42.027427]},"n185972826":{"id":"n185972826","loc":[-85.633342,42.022656]},"n185972830":{"id":"n185972830","loc":[-85.63327,42.020724]},"n185972832":{"id":"n185972832","loc":[-85.633198,42.019106]},"n185972834":{"id":"n185972834","loc":[-85.633249,42.018363]},"n185972835":{"id":"n185972835","loc":[-85.633139,42.012944]},"n185972836":{"id":"n185972836","loc":[-85.63309,42.008284]},"n185972839":{"id":"n185972839","loc":[-85.63298,42.00005]},"n185972845":{"id":"n185972845","loc":[-85.6325369,41.9764959]},"n185972847":{"id":"n185972847","loc":[-85.6327549,41.9750005]},"n185972849":{"id":"n185972849","loc":[-85.6329374,41.9742527]},"n185972851":{"id":"n185972851","loc":[-85.6331387,41.9736039]},"n185972862":{"id":"n185972862","loc":[-85.6383589,41.9585023]},"n185972868":{"id":"n185972868","loc":[-85.6393633,41.9551716]},"n185972878":{"id":"n185972878","loc":[-85.639377,41.95335]},"n185972882":{"id":"n185972882","loc":[-85.6389179,41.9516944]},"n185972885":{"id":"n185972885","loc":[-85.6387444,41.9512105]},"n185972891":{"id":"n185972891","loc":[-85.636421,41.946392]},"n185972895":{"id":"n185972895","loc":[-85.635965,41.945809]},"n185972897":{"id":"n185972897","loc":[-85.635683,41.945449]},"n185972899":{"id":"n185972899","loc":[-85.635281,41.9450252]},"n185972905":{"id":"n185972905","loc":[-85.6324428,41.9425743]},"n185985217":{"id":"n185985217","loc":[-85.638243,41.943674]},"n185985219":{"id":"n185985219","loc":[-85.638228,41.943747]},"n185985221":{"id":"n185985221","loc":[-85.638163,41.943797]},"n185985222":{"id":"n185985222","loc":[-85.638089,41.943832]},"n185985223":{"id":"n185985223","loc":[-85.637969,41.943841]},"n185985225":{"id":"n185985225","loc":[-85.637841,41.943833]},"n185985227":{"id":"n185985227","loc":[-85.637601,41.943789]},"n185985229":{"id":"n185985229","loc":[-85.637449,41.943754]},"n185985231":{"id":"n185985231","loc":[-85.637342,41.943734]},"n185985233":{"id":"n185985233","loc":[-85.637218,41.943703]},"n185985235":{"id":"n185985235","loc":[-85.637151,41.943663]},"n185985238":{"id":"n185985238","loc":[-85.637118,41.943615]},"n185985240":{"id":"n185985240","loc":[-85.637073,41.943494]},"n185990434":{"id":"n185990434","loc":[-85.6329028,41.9984292],"tags":{"railway":"level_crossing"}},"n1475284023":{"id":"n1475284023","loc":[-85.6336163,41.9435806],"tags":{"railway":"level_crossing"}},"n1475293222":{"id":"n1475293222","loc":[-85.6394045,41.953658],"tags":{"railway":"level_crossing"}},"n1475293226":{"id":"n1475293226","loc":[-85.6364975,41.9638663],"tags":{"railway":"level_crossing"}},"n1475293234":{"id":"n1475293234","loc":[-85.6390449,41.9565145]},"n1475293240":{"id":"n1475293240","loc":[-85.636943,41.9473114]},"n1475293252":{"id":"n1475293252","loc":[-85.6392115,41.9559003]},"n1475293254":{"id":"n1475293254","loc":[-85.6348931,41.9685127],"tags":{"railway":"level_crossing"}},"n1475293260":{"id":"n1475293260","loc":[-85.6375999,41.9485401]},"n1475293261":{"id":"n1475293261","loc":[-85.6391256,41.9523817],"tags":{"railway":"level_crossing"}},"n1475293264":{"id":"n1475293264","loc":[-85.6394155,41.9546493],"tags":{"railway":"level_crossing"}},"n1819805614":{"id":"n1819805614","loc":[-85.6345652,41.9363097]},"n1819805618":{"id":"n1819805618","loc":[-85.6295334,41.9426862]},"n1819805622":{"id":"n1819805622","loc":[-85.6308208,41.9430773]},"n1819805626":{"id":"n1819805626","loc":[-85.6274734,41.9406592]},"n1819805629":{"id":"n1819805629","loc":[-85.6296943,41.9430533]},"n1819805632":{"id":"n1819805632","loc":[-85.6340931,41.9354477]},"n1819805636":{"id":"n1819805636","loc":[-85.6304131,41.9436598]},"n1819805639":{"id":"n1819805639","loc":[-85.6304882,41.9426623]},"n1819805641":{"id":"n1819805641","loc":[-85.6336103,41.9367487]},"n1819805643":{"id":"n1819805643","loc":[-85.6300376,41.9418084]},"n1819805645":{"id":"n1819805645","loc":[-85.6365286,41.9336679]},"n1819805647":{"id":"n1819805647","loc":[-85.632016,41.9429221]},"n1819805666":{"id":"n1819805666","loc":[-85.6314753,41.9442663]},"n1819805669":{"id":"n1819805669","loc":[-85.6268619,41.9402203]},"n1819805673":{"id":"n1819805673","loc":[-85.6296728,41.9412099]},"n1819805676":{"id":"n1819805676","loc":[-85.6354557,41.932766]},"n1819805680":{"id":"n1819805680","loc":[-85.632752,41.9431012]},"n1819805683":{"id":"n1819805683","loc":[-85.631147,41.9432014]},"n1819805687":{"id":"n1819805687","loc":[-85.635284,41.9343942]},"n1819805690":{"id":"n1819805690","loc":[-85.6249736,41.9405794]},"n1819805694":{"id":"n1819805694","loc":[-85.6294153,41.9417925]},"n1819805698":{"id":"n1819805698","loc":[-85.6323486,41.9426986]},"n1819805702":{"id":"n1819805702","loc":[-85.6340287,41.9373871]},"n1819805707":{"id":"n1819805707","loc":[-85.6353698,41.9316326]},"n1819805711":{"id":"n1819805711","loc":[-85.6284176,41.940356]},"n1819805715":{"id":"n1819805715","loc":[-85.6291471,41.9412897]},"n1819805718":{"id":"n1819805718","loc":[-85.6311105,41.943979]},"n1819805722":{"id":"n1819805722","loc":[-85.6320868,41.9400128]},"n1819805724":{"id":"n1819805724","loc":[-85.635166,41.9324627]},"n1819805727":{"id":"n1819805727","loc":[-85.6344686,41.9350567]},"n1819805728":{"id":"n1819805728","loc":[-85.6357132,41.9332369]},"n1819805731":{"id":"n1819805731","loc":[-85.629984,41.9434444]},"n1819805760":{"id":"n1819805760","loc":[-85.6330996,41.9378784]},"n1819805766":{"id":"n1819805766","loc":[-85.625274,41.9411141]},"n1819805770":{"id":"n1819805770","loc":[-85.6326321,41.9412173]},"n1819805774":{"id":"n1819805774","loc":[-85.6347047,41.9312096]},"n1819805777":{"id":"n1819805777","loc":[-85.6363569,41.9339552]},"n1819805780":{"id":"n1819805780","loc":[-85.6327392,41.941926]},"n1819805783":{"id":"n1819805783","loc":[-85.6357239,41.9338435]},"n1819805786":{"id":"n1819805786","loc":[-85.6356595,41.9346576]},"n1819805789":{"id":"n1819805789","loc":[-85.6316469,41.9436598]},"n1819805792":{"id":"n1819805792","loc":[-85.6350587,41.9354557]},"n1819805795":{"id":"n1819805795","loc":[-85.6360028,41.9322791]},"n1819805798":{"id":"n1819805798","loc":[-85.63125,41.9443062]},"n1819805802":{"id":"n1819805802","loc":[-85.6263362,41.9408109]},"n1819805805":{"id":"n1819805805","loc":[-85.6315075,41.9438753]},"n1819805808":{"id":"n1819805808","loc":[-85.6340008,41.9316051]},"n1819805810":{"id":"n1819805810","loc":[-85.6345545,41.9320557]},"n1819805812":{"id":"n1819805812","loc":[-85.6250809,41.9408587]},"n1819805814":{"id":"n1819805814","loc":[-85.6257783,41.9400926]},"n1819805834":{"id":"n1819805834","loc":[-85.6326408,41.9424363]},"n1819805838":{"id":"n1819805838","loc":[-85.6365607,41.9334365]},"n1819805842":{"id":"n1819805842","loc":[-85.6288253,41.9410343]},"n1819805846":{"id":"n1819805846","loc":[-85.6279133,41.9402921]},"n1819805849":{"id":"n1819805849","loc":[-85.6289433,41.9405156]},"n1819805852":{"id":"n1819805852","loc":[-85.6313787,41.9439152]},"n1819805858":{"id":"n1819805858","loc":[-85.6300805,41.9420398]},"n1819805861":{"id":"n1819805861","loc":[-85.6321941,41.9396297]},"n1819805864":{"id":"n1819805864","loc":[-85.6329129,41.9393903]},"n1819805868":{"id":"n1819805868","loc":[-85.632001,41.9434922]},"n1819805870":{"id":"n1819805870","loc":[-85.6314903,41.9431535]},"n1819805873":{"id":"n1819805873","loc":[-85.6251667,41.9401166]},"n1819805876":{"id":"n1819805876","loc":[-85.63287,41.939941]},"n1819805878":{"id":"n1819805878","loc":[-85.6307886,41.9437317]},"n1819805880":{"id":"n1819805880","loc":[-85.6321727,41.940348]},"n1819805883":{"id":"n1819805883","loc":[-85.6265872,41.940113]},"n1819805885":{"id":"n1819805885","loc":[-85.6268404,41.9406672]},"n1819805887":{"id":"n1819805887","loc":[-85.6325267,41.9389035]},"n1819805889":{"id":"n1819805889","loc":[-85.6364964,41.933189]},"n1819805911":{"id":"n1819805911","loc":[-85.6248663,41.9401804]},"n1819805922":{"id":"n1819805922","loc":[-85.633267,41.9387199]},"n1819805925":{"id":"n1819805925","loc":[-85.6293402,41.9408428]},"n1819848849":{"id":"n1819848849","loc":[-85.6464957,41.9695178]},"n1819848850":{"id":"n1819848850","loc":[-85.6497642,41.9611355]},"n1819848851":{"id":"n1819848851","loc":[-85.6480943,41.9624818]},"n1819848854":{"id":"n1819848854","loc":[-85.6500362,41.9657367]},"n1819848855":{"id":"n1819848855","loc":[-85.6493673,41.9783496]},"n1819848856":{"id":"n1819848856","loc":[-85.6457409,41.9548007]},"n1819848857":{"id":"n1819848857","loc":[-85.651313,41.9760426]},"n1819848858":{"id":"n1819848858","loc":[-85.6495819,41.9784772]},"n1819848859":{"id":"n1819848859","loc":[-85.6495105,41.9833722]},"n1819848860":{"id":"n1819848860","loc":[-85.6405053,41.9492792]},"n1819848863":{"id":"n1819848863","loc":[-85.6502293,41.9786826]},"n1819848865":{"id":"n1819848865","loc":[-85.6406877,41.9495106]},"n1819848870":{"id":"n1819848870","loc":[-85.6493136,41.9704611]},"n1819848871":{"id":"n1819848871","loc":[-85.6372249,41.9441284]},"n1819848873":{"id":"n1819848873","loc":[-85.6512379,41.9659441]},"n1819848875":{"id":"n1819848875","loc":[-85.6508087,41.9650187]},"n1819848877":{"id":"n1819848877","loc":[-85.6487166,41.9605352]},"n1819848878":{"id":"n1819848878","loc":[-85.6506478,41.9760665]},"n1819848879":{"id":"n1819848879","loc":[-85.651431,41.9758512]},"n1819848886":{"id":"n1819848886","loc":[-85.6477617,41.9563945]},"n1819848889":{"id":"n1819848889","loc":[-85.6497895,41.9832286]},"n1819848892":{"id":"n1819848892","loc":[-85.6504868,41.9791931]},"n1819848893":{"id":"n1819848893","loc":[-85.6498002,41.9615085]},"n1819848894":{"id":"n1819848894","loc":[-85.6404302,41.9502846]},"n1819848901":{"id":"n1819848901","loc":[-85.6354412,41.9439886]},"n1819848903":{"id":"n1819848903","loc":[-85.6472145,41.9698528]},"n1819848904":{"id":"n1819848904","loc":[-85.6401979,41.9486233]},"n1819848905":{"id":"n1819848905","loc":[-85.6475042,41.963503]},"n1819848909":{"id":"n1819848909","loc":[-85.6343405,41.94358]},"n1819848914":{"id":"n1819848914","loc":[-85.6503474,41.9737773]},"n1819848915":{"id":"n1819848915","loc":[-85.6389533,41.9470992]},"n1819848916":{"id":"n1819848916","loc":[-85.6483625,41.9577907]},"n1819848917":{"id":"n1819848917","loc":[-85.6484768,41.9617419]},"n1819848918":{"id":"n1819848918","loc":[-85.644078,41.9545693]},"n1819848919":{"id":"n1819848919","loc":[-85.6437169,41.9543041]},"n1819848920":{"id":"n1819848920","loc":[-85.6478331,41.9627949]},"n1819848922":{"id":"n1819848922","loc":[-85.6499144,41.9785889]},"n1819848924":{"id":"n1819848924","loc":[-85.647633,41.9720066]},"n1819848926":{"id":"n1819848926","loc":[-85.6487987,41.978868]},"n1819848927":{"id":"n1819848927","loc":[-85.6495105,41.9730355]},"n1819848928":{"id":"n1819848928","loc":[-85.648223,41.9829654]},"n1819848929":{"id":"n1819848929","loc":[-85.6514846,41.9659122]},"n1819848931":{"id":"n1819848931","loc":[-85.6498753,41.9731871]},"n1819848932":{"id":"n1819848932","loc":[-85.640906,41.9508575]},"n1819848933":{"id":"n1819848933","loc":[-85.649775,41.9799767]},"n1819848934":{"id":"n1819848934","loc":[-85.6507014,41.9739927]},"n1819848937":{"id":"n1819848937","loc":[-85.6479763,41.9840899]},"n1819848938":{"id":"n1819848938","loc":[-85.6501113,41.9600884]},"n1819848939":{"id":"n1819848939","loc":[-85.6389962,41.9478253]},"n1819848941":{"id":"n1819848941","loc":[-85.637469,41.9445791]},"n1819848942":{"id":"n1819848942","loc":[-85.6494569,41.9601682]},"n1819848943":{"id":"n1819848943","loc":[-85.6368803,41.9439351]},"n1819848945":{"id":"n1819848945","loc":[-85.6474398,41.9724213]},"n1819848946":{"id":"n1819848946","loc":[-85.6382629,41.9463666]},"n1819848948":{"id":"n1819848948","loc":[-85.6489633,41.9830771]},"n1819848952":{"id":"n1819848952","loc":[-85.6488882,41.9600326]},"n1819848953":{"id":"n1819848953","loc":[-85.6488094,41.9774324]},"n1819848954":{"id":"n1819848954","loc":[-85.6491135,41.9600485]},"n1819848955":{"id":"n1819848955","loc":[-85.6501435,41.9734583]},"n1819848956":{"id":"n1819848956","loc":[-85.6495534,41.960958]},"n1819848958":{"id":"n1819848958","loc":[-85.6474683,41.9561491]},"n1819848959":{"id":"n1819848959","loc":[-85.6401083,41.9485451]},"n1819848960":{"id":"n1819848960","loc":[-85.6481764,41.9678686]},"n1819848961":{"id":"n1819848961","loc":[-85.6484017,41.967382]},"n1819848962":{"id":"n1819848962","loc":[-85.6501328,41.959897]},"n1819848964":{"id":"n1819848964","loc":[-85.6403695,41.9504586]},"n1819848966":{"id":"n1819848966","loc":[-85.6398975,41.9491499]},"n1819848967":{"id":"n1819848967","loc":[-85.6412455,41.9510187]},"n1819848968":{"id":"n1819848968","loc":[-85.6482622,41.9619493]},"n1819848969":{"id":"n1819848969","loc":[-85.6405841,41.9501474]},"n1819848970":{"id":"n1819848970","loc":[-85.6478583,41.9703394]},"n1819848971":{"id":"n1819848971","loc":[-85.6493388,41.9832845]},"n1819848972":{"id":"n1819848972","loc":[-85.6485664,41.9829415]},"n1819848974":{"id":"n1819848974","loc":[-85.6491457,41.9779887]},"n1819848975":{"id":"n1819848975","loc":[-85.6468889,41.9697033]},"n1819848976":{"id":"n1819848976","loc":[-85.6452726,41.9546072]},"n1819848977":{"id":"n1819848977","loc":[-85.6448435,41.9546072]},"n1819848979":{"id":"n1819848979","loc":[-85.6485342,41.9763138]},"n1819848980":{"id":"n1819848980","loc":[-85.6495282,41.9664087]},"n1819848986":{"id":"n1819848986","loc":[-85.6486307,41.9603278]},"n1819848987":{"id":"n1819848987","loc":[-85.6492278,41.9791871]},"n1819848990":{"id":"n1819848990","loc":[-85.6501934,41.9800724]},"n1819848992":{"id":"n1819848992","loc":[-85.6482445,41.9819685]},"n1819848993":{"id":"n1819848993","loc":[-85.6481871,41.9704451]},"n1819848994":{"id":"n1819848994","loc":[-85.6371364,41.9457602]},"n1819848996":{"id":"n1819848996","loc":[-85.6500362,41.9801023]},"n1819849000":{"id":"n1819849000","loc":[-85.639007,41.9485914]},"n1819849001":{"id":"n1819849001","loc":[-85.6488882,41.9669253]},"n1819849002":{"id":"n1819849002","loc":[-85.6484698,41.9565062]},"n1819849004":{"id":"n1819849004","loc":[-85.6510769,41.9761064]},"n1819849005":{"id":"n1819849005","loc":[-85.6503581,41.9799029]},"n1819849006":{"id":"n1819849006","loc":[-85.6489381,41.9703893]},"n1819849008":{"id":"n1819849008","loc":[-85.6497457,41.9833588]},"n1819849011":{"id":"n1819849011","loc":[-85.6497358,41.9717593]},"n1819849012":{"id":"n1819849012","loc":[-85.6494676,41.9796796]},"n1819849019":{"id":"n1819849019","loc":[-85.6486093,41.9771034]},"n1819849021":{"id":"n1819849021","loc":[-85.6504546,41.9796556]},"n1819849022":{"id":"n1819849022","loc":[-85.6371294,41.9454154]},"n1819849023":{"id":"n1819849023","loc":[-85.6503436,41.9759249]},"n1819849025":{"id":"n1819849025","loc":[-85.6462382,41.9693822]},"n1819849026":{"id":"n1819849026","loc":[-85.6497573,41.983093]},"n1819849028":{"id":"n1819849028","loc":[-85.6497465,41.9602799]},"n1819849029":{"id":"n1819849029","loc":[-85.6374728,41.9460698]},"n1819849030":{"id":"n1819849030","loc":[-85.6486592,41.9566039]},"n1819849031":{"id":"n1819849031","loc":[-85.6515989,41.9654993]},"n1819849032":{"id":"n1819849032","loc":[-85.6387028,41.9482658]},"n1819849033":{"id":"n1819849033","loc":[-85.6464742,41.9688398]},"n1819849034":{"id":"n1819849034","loc":[-85.6495212,41.9589236]},"n1819849035":{"id":"n1819849035","loc":[-85.6490599,41.9790096]},"n1819849036":{"id":"n1819849036","loc":[-85.6489918,41.9800724]},"n1819849038":{"id":"n1819849038","loc":[-85.6499182,41.9659042]},"n1819849040":{"id":"n1819849040","loc":[-85.639758,41.9490143]},"n1819849041":{"id":"n1819849041","loc":[-85.6514846,41.9755241]},"n1819849042":{"id":"n1819849042","loc":[-85.6436633,41.9540647]},"n1819849045":{"id":"n1819849045","loc":[-85.6475541,41.9726387]},"n1819849046":{"id":"n1819849046","loc":[-85.6488308,41.9718331]},"n1819849047":{"id":"n1819849047","loc":[-85.6377694,41.9460953]},"n1819849048":{"id":"n1819849048","loc":[-85.6490706,41.9804452]},"n1819849049":{"id":"n1819849049","loc":[-85.6485449,41.9766248]},"n1819849051":{"id":"n1819849051","loc":[-85.6483625,41.9790256]},"n1819849052":{"id":"n1819849052","loc":[-85.6490706,41.9585167]},"n1819849053":{"id":"n1819849053","loc":[-85.6425008,41.9522874]},"n1819849054":{"id":"n1819849054","loc":[-85.6475793,41.9632158]},"n1819849055":{"id":"n1819849055","loc":[-85.6408631,41.9499399]},"n1819849056":{"id":"n1819849056","loc":[-85.6483373,41.9814681]},"n1819849057":{"id":"n1819849057","loc":[-85.6313548,41.9442876]},"n1819849058":{"id":"n1819849058","loc":[-85.6432663,41.9529796]},"n1819849059":{"id":"n1819849059","loc":[-85.6487128,41.9582873]},"n1819849060":{"id":"n1819849060","loc":[-85.6482338,41.9817612]},"n1819849062":{"id":"n1819849062","loc":[-85.6485664,41.9788661]},"n1819849063":{"id":"n1819849063","loc":[-85.6373081,41.9448824]},"n1819849064":{"id":"n1819849064","loc":[-85.6472215,41.9557582]},"n1819849065":{"id":"n1819849065","loc":[-85.6348984,41.9440414]},"n1819849066":{"id":"n1819849066","loc":[-85.6501972,41.9647315]},"n1819849067":{"id":"n1819849067","loc":[-85.6489741,41.9808281]},"n1819849068":{"id":"n1819849068","loc":[-85.6420111,41.9515034]},"n1819849069":{"id":"n1819849069","loc":[-85.6397972,41.9488882]},"n1819849070":{"id":"n1819849070","loc":[-85.6499718,41.9593465]},"n1819849071":{"id":"n1819849071","loc":[-85.6486844,41.9811311]},"n1819849072":{"id":"n1819849072","loc":[-85.6390392,41.9474663]},"n1819849074":{"id":"n1819849074","loc":[-85.6495642,41.9616362]},"n1819849075":{"id":"n1819849075","loc":[-85.6483518,41.9791931]},"n1819849076":{"id":"n1819849076","loc":[-85.6478974,41.9833104]},"n1819849077":{"id":"n1819849077","loc":[-85.640155,41.948719]},"n1819849078":{"id":"n1819849078","loc":[-85.6399366,41.9487845]},"n1819849079":{"id":"n1819849079","loc":[-85.6492959,41.9825348]},"n1819849080":{"id":"n1819849080","loc":[-85.6505083,41.9648352]},"n1819849081":{"id":"n1819849081","loc":[-85.6492959,41.9645241]},"n1819849082":{"id":"n1819849082","loc":[-85.6402049,41.9491835]},"n1819849083":{"id":"n1819849083","loc":[-85.6495175,41.9826963]},"n1819849084":{"id":"n1819849084","loc":[-85.6480836,41.9728361]},"n1819849085":{"id":"n1819849085","loc":[-85.6374349,41.9443425]},"n1819849086":{"id":"n1819849086","loc":[-85.6478331,41.9681238]},"n1819849089":{"id":"n1819849089","loc":[-85.639368,41.9486169]},"n1819849092":{"id":"n1819849092","loc":[-85.6503581,41.9788022]},"n1819849093":{"id":"n1819849093","loc":[-85.64862,41.9568014]},"n1819849094":{"id":"n1819849094","loc":[-85.6496999,41.9828877]},"n1819849095":{"id":"n1819849095","loc":[-85.647472,41.972198]},"n1819849096":{"id":"n1819849096","loc":[-85.6485771,41.9644523]},"n1819849097":{"id":"n1819849097","loc":[-85.6388353,41.9480488]},"n1819849099":{"id":"n1819849099","loc":[-85.6472752,41.9683312]},"n1819849104":{"id":"n1819849104","loc":[-85.6479548,41.9836035]},"n1819849105":{"id":"n1819849105","loc":[-85.6462489,41.9691668]},"n1819849107":{"id":"n1819849107","loc":[-85.6511912,41.9746328]},"n1819849108":{"id":"n1819849108","loc":[-85.6498646,41.9714881]},"n1819849111":{"id":"n1819849111","loc":[-85.6488239,41.961684]},"n1819849112":{"id":"n1819849112","loc":[-85.6469356,41.9553812]},"n1819849114":{"id":"n1819849114","loc":[-85.6479548,41.9640853]},"n1819849119":{"id":"n1819849119","loc":[-85.6491565,41.961692]},"n1819849121":{"id":"n1819849121","loc":[-85.651667,41.9656728]},"n1819849124":{"id":"n1819849124","loc":[-85.6388423,41.9484414]},"n1819849126":{"id":"n1819849126","loc":[-85.6371686,41.9450978]},"n1819849127":{"id":"n1819849127","loc":[-85.6502615,41.9656728]},"n1819849129":{"id":"n1819849129","loc":[-85.6498501,41.9613031]},"n1819849131":{"id":"n1819849131","loc":[-85.6513881,41.9653298]},"n1819849133":{"id":"n1819849133","loc":[-85.639883,41.9485291]},"n1819849139":{"id":"n1819849139","loc":[-85.6508693,41.9658264]},"n1819849140":{"id":"n1819849140","loc":[-85.6486806,41.9761642]},"n1819849141":{"id":"n1819849141","loc":[-85.6483159,41.9717613]},"n1819849144":{"id":"n1819849144","loc":[-85.6443714,41.9546232]},"n1819849146":{"id":"n1819849146","loc":[-85.641775,41.9513359]},"n1819849147":{"id":"n1819849147","loc":[-85.6495604,41.9757335]},"n1819849148":{"id":"n1819849148","loc":[-85.6465671,41.9551678]},"n1819849150":{"id":"n1819849150","loc":[-85.6485127,41.9794084]},"n1819849151":{"id":"n1819849151","loc":[-85.6499144,41.9757096]},"n1819849152":{"id":"n1819849152","loc":[-85.6433736,41.9531072]},"n1819849154":{"id":"n1819849154","loc":[-85.6489741,41.9607426]},"n1819849155":{"id":"n1819849155","loc":[-85.640627,41.9507697]},"n1819849156":{"id":"n1819849156","loc":[-85.6509659,41.9743058]},"n1819849157":{"id":"n1819849157","loc":[-85.6486844,41.9704431]},"n1819849158":{"id":"n1819849158","loc":[-85.6498538,41.9711132]},"n1819849159":{"id":"n1819849159","loc":[-85.6358937,41.943719]},"n1819849160":{"id":"n1819849160","loc":[-85.6497358,41.9707702]},"n1819849161":{"id":"n1819849161","loc":[-85.6480476,41.9564842]},"n1819849162":{"id":"n1819849162","loc":[-85.6482982,41.9574556]},"n1819849163":{"id":"n1819849163","loc":[-85.6501757,41.9757794]},"n1819849164":{"id":"n1819849164","loc":[-85.6372973,41.9459916]},"n1819849165":{"id":"n1819849165","loc":[-85.6513773,41.9750775]},"n1819849166":{"id":"n1819849166","loc":[-85.6436418,41.9537455]},"n1819849167":{"id":"n1819849167","loc":[-85.6483625,41.9571524]},"n1819849169":{"id":"n1819849169","loc":[-85.647751,41.9727962]},"n1819849170":{"id":"n1819849170","loc":[-85.6504546,41.9656808]},"n1819849171":{"id":"n1819849171","loc":[-85.6479977,41.971839]},"n1819849172":{"id":"n1819849172","loc":[-85.6482767,41.9642449]},"n1819849174":{"id":"n1819849174","loc":[-85.6414317,41.9512086]},"n1819849176":{"id":"n1819849176","loc":[-85.6469034,41.9685287]},"n1819849179":{"id":"n1819849179","loc":[-85.6408631,41.9497564]},"n1819849182":{"id":"n1819849182","loc":[-85.6476721,41.96384]},"n1819849183":{"id":"n1819849183","loc":[-85.6479725,41.983111]},"n1819849184":{"id":"n1819849184","loc":[-85.640788,41.9500516]},"n1819849185":{"id":"n1819849185","loc":[-85.6427798,41.9528778]},"n1819849186":{"id":"n1819849186","loc":[-85.6435308,41.9534124]},"n1819849187":{"id":"n1819849187","loc":[-85.6483733,41.9821998]},"n1819849189":{"id":"n1819849189","loc":[-85.6351752,41.9440796]},"n1819849191":{"id":"n1819849191","loc":[-85.6487021,41.9601463]},"n1819849192":{"id":"n1819849192","loc":[-85.6363811,41.9437605]},"n1819849193":{"id":"n1819849193","loc":[-85.6490883,41.9759728]},"n1819849194":{"id":"n1819849194","loc":[-85.6423292,41.9520081]},"n1819849195":{"id":"n1819849195","loc":[-85.6500003,41.960242]},"n1819849196":{"id":"n1819849196","loc":[-85.6385778,41.9466443]},"n1819849197":{"id":"n1819849197","loc":[-85.6494032,41.9718789]},"n1819849198":{"id":"n1819849198","loc":[-85.6404339,41.9506501]},"n1819849199":{"id":"n1819849199","loc":[-85.6426226,41.9527083]},"n1819849200":{"id":"n1819849200","loc":[-85.6439101,41.9545035]},"n1819849201":{"id":"n1819849201","loc":[-85.6516563,41.9657845]},"n1819849202":{"id":"n1819849202","loc":[-85.6473395,41.9699585]},"n1819858501":{"id":"n1819858501","loc":[-85.6361263,41.9437126]},"n1819858503":{"id":"n1819858503","loc":[-85.6350068,41.944034]},"n1819858513":{"id":"n1819858513","loc":[-85.6371402,41.9453282]},"n1819858518":{"id":"n1819858518","loc":[-85.6348713,41.9432923]},"n1819858523":{"id":"n1819858523","loc":[-85.6357047,41.943799]},"n1819858526":{"id":"n1819858526","loc":[-85.6349947,41.9435756]},"n1819858531":{"id":"n1819858531","loc":[-85.6350376,41.943827]},"n1820937508":{"id":"n1820937508","loc":[-85.1026013,42.0881722]},"n1820937509":{"id":"n1820937509","loc":[-85.0558088,42.102493]},"n1820937511":{"id":"n1820937511","loc":[-85.3030116,41.9724451]},"n1820937513":{"id":"n1820937513","loc":[-85.0353221,42.1027398]},"n1820937514":{"id":"n1820937514","loc":[-85.0835468,42.1015469]},"n1820937515":{"id":"n1820937515","loc":[-85.2421298,42.0106305]},"n1820937517":{"id":"n1820937517","loc":[-85.0090632,42.0910452]},"n1820937518":{"id":"n1820937518","loc":[-85.086626,42.0948838]},"n1820937520":{"id":"n1820937520","loc":[-85.2552039,42.0015448]},"n1820937521":{"id":"n1820937521","loc":[-85.3739614,41.9969917]},"n1820937522":{"id":"n1820937522","loc":[-85.4831166,41.993898]},"n1820937523":{"id":"n1820937523","loc":[-85.0341084,42.0977657]},"n1820937524":{"id":"n1820937524","loc":[-85.3272802,41.9710333]},"n1820937525":{"id":"n1820937525","loc":[-85.2125568,42.0414521]},"n1820937526":{"id":"n1820937526","loc":[-85.3798022,41.9992458]},"n1820937527":{"id":"n1820937527","loc":[-85.2652021,41.999768]},"n1820937528":{"id":"n1820937528","loc":[-85.3852739,42.0004896]},"n1820937529":{"id":"n1820937529","loc":[-85.3911919,42.0030513]},"n1820937530":{"id":"n1820937530","loc":[-85.5440349,41.9717109]},"n1820937531":{"id":"n1820937531","loc":[-85.2790155,41.9911764]},"n1820937532":{"id":"n1820937532","loc":[-85.4723277,41.9950518]},"n1820937533":{"id":"n1820937533","loc":[-85.5690546,41.9653931]},"n1820937535":{"id":"n1820937535","loc":[-85.5674882,41.9649623]},"n1820937536":{"id":"n1820937536","loc":[-85.6362815,41.9189165]},"n1820937537":{"id":"n1820937537","loc":[-85.5659003,41.963638]},"n1820937539":{"id":"n1820937539","loc":[-85.6391353,41.9122262]},"n1820937540":{"id":"n1820937540","loc":[-85.4834385,41.9894803]},"n1820937541":{"id":"n1820937541","loc":[-85.6399078,41.9160744]},"n1820937542":{"id":"n1820937542","loc":[-85.632874,41.941031]},"n1820937543":{"id":"n1820937543","loc":[-85.1307591,42.0726961]},"n1820937544":{"id":"n1820937544","loc":[-85.6444397,41.9128378]},"n1820937545":{"id":"n1820937545","loc":[-85.6197204,41.9420365]},"n1820937546":{"id":"n1820937546","loc":[-85.1164857,42.0864631]},"n1820937547":{"id":"n1820937547","loc":[-85.6476111,41.9142222]},"n1820937548":{"id":"n1820937548","loc":[-85.2915747,41.9774223]},"n1820937549":{"id":"n1820937549","loc":[-85.6430192,41.9102461]},"n1820937550":{"id":"n1820937550","loc":[-85.1597495,42.0639017]},"n1820937551":{"id":"n1820937551","loc":[-85.5504079,41.9701793]},"n1820937553":{"id":"n1820937553","loc":[-85.2781317,41.9948951]},"n1820937555":{"id":"n1820937555","loc":[-85.3724594,41.997518]},"n1820937556":{"id":"n1820937556","loc":[-85.5629434,41.9665155]},"n1820937557":{"id":"n1820937557","loc":[-85.3791971,41.9990808]},"n1820937558":{"id":"n1820937558","loc":[-85.001891,42.0878843]},"n1820937560":{"id":"n1820937560","loc":[-85.3140838,41.9709056]},"n1820937561":{"id":"n1820937561","loc":[-85.2468032,42.0146987]},"n1820937563":{"id":"n1820937563","loc":[-85.0877378,42.097255]},"n1820937564":{"id":"n1820937564","loc":[-85.2442498,42.0150654]},"n1820937566":{"id":"n1820937566","loc":[-85.3108973,41.9701478]},"n1820937568":{"id":"n1820937568","loc":[-85.0344584,42.1016572]},"n1820937569":{"id":"n1820937569","loc":[-85.2331025,42.0297387]},"n1820937570":{"id":"n1820937570","loc":[-85.5058446,41.9746996]},"n1820937571":{"id":"n1820937571","loc":[-85.5622739,41.9676427]},"n1820937572":{"id":"n1820937572","loc":[-85.2792687,41.9890337]},"n1820937574":{"id":"n1820937574","loc":[-84.9909302,42.08695]},"n1820937575":{"id":"n1820937575","loc":[-85.6218233,41.9418609]},"n1820937576":{"id":"n1820937576","loc":[-85.3577437,41.9931062]},"n1820937577":{"id":"n1820937577","loc":[-85.639028,41.9165853]},"n1820937578":{"id":"n1820937578","loc":[-84.9956576,42.0865348]},"n1820937579":{"id":"n1820937579","loc":[-85.4828376,41.990198]},"n1820937580":{"id":"n1820937580","loc":[-85.3244478,41.9720543]},"n1820937582":{"id":"n1820937582","loc":[-85.0517479,42.1035159]},"n1820937583":{"id":"n1820937583","loc":[-85.225646,42.0338025]},"n1820937584":{"id":"n1820937584","loc":[-84.9941019,42.0862163]},"n1820937586":{"id":"n1820937586","loc":[-85.1051762,42.0879452]},"n1820937587":{"id":"n1820937587","loc":[-85.1245203,42.0753162]},"n1820937588":{"id":"n1820937588","loc":[-85.3250808,41.9719506]},"n1820937589":{"id":"n1820937589","loc":[-85.2720109,41.997933]},"n1820937590":{"id":"n1820937590","loc":[-85.2556653,42.0027248]},"n1820937591":{"id":"n1820937591","loc":[-85.0872483,42.0943544]},"n1820937592":{"id":"n1820937592","loc":[-85.2778353,41.9955023]},"n1820937593":{"id":"n1820937593","loc":[-85.2984733,41.9735538]},"n1820937594":{"id":"n1820937594","loc":[-85.101578,42.0889552]},"n1820937595":{"id":"n1820937595","loc":[-85.3888745,42.0016959]},"n1820937596":{"id":"n1820937596","loc":[-84.9903508,42.0870654]},"n1820937597":{"id":"n1820937597","loc":[-85.6405558,41.9146261]},"n1820937598":{"id":"n1820937598","loc":[-85.6460704,41.9141311]},"n1820937599":{"id":"n1820937599","loc":[-85.0377468,42.1037428]},"n1820937600":{"id":"n1820937600","loc":[-85.2298345,42.0312899]},"n1820937601":{"id":"n1820937601","loc":[-85.1080958,42.0861964]},"n1820937602":{"id":"n1820937602","loc":[-85.6325307,41.9402329]},"n1820937603":{"id":"n1820937603","loc":[-85.1165984,42.0832184]},"n1820937604":{"id":"n1820937604","loc":[-85.6354446,41.9190602]},"n1820937605":{"id":"n1820937605","loc":[-85.1114592,42.0862959]},"n1820937606":{"id":"n1820937606","loc":[-85.0858763,42.1001646]},"n1820937607":{"id":"n1820937607","loc":[-85.0472083,42.1015151]},"n1820937608":{"id":"n1820937608","loc":[-85.0802477,42.1027609]},"n1820937610":{"id":"n1820937610","loc":[-85.0924585,42.0928564]},"n1820937611":{"id":"n1820937611","loc":[-85.0329617,42.09827]},"n1820937612":{"id":"n1820937612","loc":[-85.2814617,41.993465]},"n1820937613":{"id":"n1820937613","loc":[-85.3097708,41.9700282]},"n1820937614":{"id":"n1820937614","loc":[-85.2809427,41.993695]},"n1820937615":{"id":"n1820937615","loc":[-85.0583233,42.1026494]},"n1820937617":{"id":"n1820937617","loc":[-85.2801592,41.9840021]},"n1820937619":{"id":"n1820937619","loc":[-85.1064154,42.0863449]},"n1820937620":{"id":"n1820937620","loc":[-85.0423173,42.1014662]},"n1820937621":{"id":"n1820937621","loc":[-85.2168913,42.0398107]},"n1820937622":{"id":"n1820937622","loc":[-85.2798481,41.9833401]},"n1820937623":{"id":"n1820937623","loc":[-85.0575468,42.1028672]},"n1820937625":{"id":"n1820937625","loc":[-85.0130369,42.0893067]},"n1820937626":{"id":"n1820937626","loc":[-85.0346985,42.1018256]},"n1820937627":{"id":"n1820937627","loc":[-85.2231569,42.0372768]},"n1820937628":{"id":"n1820937628","loc":[-85.2956195,41.9732268]},"n1820937629":{"id":"n1820937629","loc":[-85.1052312,42.086893]},"n1820937630":{"id":"n1820937630","loc":[-85.4813356,41.9958436]},"n1820937631":{"id":"n1820937631","loc":[-85.0961599,42.0914672]},"n1820937632":{"id":"n1820937632","loc":[-85.308419,41.9704749]},"n1820937633":{"id":"n1820937633","loc":[-85.295952,41.9715119]},"n1820937634":{"id":"n1820937634","loc":[-85.3310933,41.9703923]},"n1820937635":{"id":"n1820937635","loc":[-85.2940745,41.9739686]},"n1820937636":{"id":"n1820937636","loc":[-85.3803343,42.000484]},"n1820937637":{"id":"n1820937637","loc":[-85.1174231,42.0845533]},"n1820937638":{"id":"n1820937638","loc":[-85.0095836,42.089839]},"n1820937639":{"id":"n1820937639","loc":[-85.3179354,41.9705866]},"n1820937640":{"id":"n1820937640","loc":[-85.257708,42.0001189]},"n1820937641":{"id":"n1820937641","loc":[-85.2563522,42.0002771]},"n1820937642":{"id":"n1820937642","loc":[-85.3181929,41.970419]},"n1820937643":{"id":"n1820937643","loc":[-85.2911884,41.9757154]},"n1820937644":{"id":"n1820937644","loc":[-85.2714423,41.9975862]},"n1820937645":{"id":"n1820937645","loc":[-85.0193669,42.089888]},"n1820937646":{"id":"n1820937646","loc":[-85.3889818,42.0039921]},"n1820937647":{"id":"n1820937647","loc":[-85.3408093,41.9853965]},"n1820937648":{"id":"n1820937648","loc":[-85.1258091,42.0748332]},"n1820937649":{"id":"n1820937649","loc":[-85.5722561,41.962782]},"n1820937650":{"id":"n1820937650","loc":[-85.3266902,41.9721819]},"n1820937651":{"id":"n1820937651","loc":[-85.1473255,42.065192]},"n1820937652":{"id":"n1820937652","loc":[-85.1462526,42.0655106]},"n1820937653":{"id":"n1820937653","loc":[-85.4641051,42.0013929]},"n1820937654":{"id":"n1820937654","loc":[-85.5620379,41.9700677]},"n1820937655":{"id":"n1820937655","loc":[-85.3226025,41.971121]},"n1820937656":{"id":"n1820937656","loc":[-85.0200965,42.0899516]},"n1820937657":{"id":"n1820937657","loc":[-85.0624714,42.1044711]},"n1820937658":{"id":"n1820937658","loc":[-85.5649562,41.9637178]},"n1820937659":{"id":"n1820937659","loc":[-85.2360315,42.0253315]},"n1820937660":{"id":"n1820937660","loc":[-85.3881449,41.9994475]},"n1820937661":{"id":"n1820937661","loc":[-85.5032911,41.976263]},"n1820937662":{"id":"n1820937662","loc":[-85.481297,41.9871414]},"n1820937663":{"id":"n1820937663","loc":[-85.1167056,42.0841898]},"n1820937664":{"id":"n1820937664","loc":[-85.2891714,41.9787223]},"n1820937665":{"id":"n1820937665","loc":[-85.4393429,42.0058736]},"n1820937666":{"id":"n1820937666","loc":[-85.0077007,42.0895762]},"n1820937667":{"id":"n1820937667","loc":[-85.2736202,41.9979171]},"n1820937668":{"id":"n1820937668","loc":[-84.9935332,42.0859296]},"n1820937669":{"id":"n1820937669","loc":[-85.0622769,42.1046713]},"n1820937670":{"id":"n1820937670","loc":[-85.2309031,42.0311249]},"n1820937671":{"id":"n1820937671","loc":[-85.0343726,42.10069]},"n1820937672":{"id":"n1820937672","loc":[-85.0596551,42.1048612]},"n1820937673":{"id":"n1820937673","loc":[-85.1338597,42.0707449]},"n1820937674":{"id":"n1820937674","loc":[-85.3117663,41.9689194]},"n1820937675":{"id":"n1820937675","loc":[-85.0705649,42.1057499]},"n1820937676":{"id":"n1820937676","loc":[-85.2441425,42.0180944]},"n1820937677":{"id":"n1820937677","loc":[-85.1171174,42.0862692]},"n1820937678":{"id":"n1820937678","loc":[-85.0346824,42.1005519]},"n1820937680":{"id":"n1820937680","loc":[-85.2389927,42.0229245]},"n1820937681":{"id":"n1820937681","loc":[-85.0834892,42.1018642]},"n1820937682":{"id":"n1820937682","loc":[-85.0619443,42.1049459]},"n1820937683":{"id":"n1820937683","loc":[-85.2845366,41.9811868]},"n1820937684":{"id":"n1820937684","loc":[-85.210411,42.0394123]},"n1820937685":{"id":"n1820937685","loc":[-85.4377383,42.0055942]},"n1820937686":{"id":"n1820937686","loc":[-85.2882058,41.9789138]},"n1820937687":{"id":"n1820937687","loc":[-85.2741191,41.9955808]},"n1820937688":{"id":"n1820937688","loc":[-85.3442211,41.9903575]},"n1820937689":{"id":"n1820937689","loc":[-85.2641413,41.9995237]},"n1820937690":{"id":"n1820937690","loc":[-85.2804489,41.9829174]},"n1820937691":{"id":"n1820937691","loc":[-85.5593342,41.9729074]},"n1820937692":{"id":"n1820937692","loc":[-85.3590912,41.9932601]},"n1820937694":{"id":"n1820937694","loc":[-85.4826445,41.9957479]},"n1820937695":{"id":"n1820937695","loc":[-85.4539127,42.0063041]},"n1820937696":{"id":"n1820937696","loc":[-85.2456767,42.0153683]},"n1820937697":{"id":"n1820937697","loc":[-85.5794015,41.9489631]},"n1820937698":{"id":"n1820937698","loc":[-85.4108686,42.0078507]},"n1820937699":{"id":"n1820937699","loc":[-85.0616386,42.1051529]},"n1820937700":{"id":"n1820937700","loc":[-85.4977979,41.978241]},"n1820937701":{"id":"n1820937701","loc":[-85.2488417,42.0086319]},"n1820937702":{"id":"n1820937702","loc":[-85.5588836,41.9728116]},"n1820937703":{"id":"n1820937703","loc":[-85.4557366,42.0051241]},"n1820937705":{"id":"n1820937705","loc":[-85.0723151,42.1056094]},"n1820937706":{"id":"n1820937706","loc":[-85.0057909,42.0887323]},"n1820937707":{"id":"n1820937707","loc":[-85.0756786,42.105677]},"n1820937708":{"id":"n1820937708","loc":[-85.0901504,42.0940001]},"n1820937709":{"id":"n1820937709","loc":[-85.0979999,42.0910213]},"n1820937710":{"id":"n1820937710","loc":[-85.2376301,42.0239686]},"n1820937711":{"id":"n1820937711","loc":[-85.2780671,41.9902299]},"n1820937712":{"id":"n1820937712","loc":[-85.251481,42.0113188]},"n1820937713":{"id":"n1820937713","loc":[-85.3114767,41.9690311]},"n1820937714":{"id":"n1820937714","loc":[-85.2649621,41.9975662]},"n1820937715":{"id":"n1820937715","loc":[-85.283807,41.9813383]},"n1820937716":{"id":"n1820937716","loc":[-85.5515451,41.9703867]},"n1820937717":{"id":"n1820937717","loc":[-85.1176605,42.0850896]},"n1820937718":{"id":"n1820937718","loc":[-85.1069317,42.0862441]},"n1820937719":{"id":"n1820937719","loc":[-85.2739314,41.9976938]},"n1820937720":{"id":"n1820937720","loc":[-85.5550212,41.9702112]},"n1820937721":{"id":"n1820937721","loc":[-85.3076679,41.9719904]},"n1820937722":{"id":"n1820937722","loc":[-85.592319,41.9440316]},"n1820937723":{"id":"n1820937723","loc":[-85.3139979,41.9704031]},"n1820937724":{"id":"n1820937724","loc":[-85.0421134,42.1013149]},"n1820937725":{"id":"n1820937725","loc":[-85.2508373,42.0102741]},"n1820937726":{"id":"n1820937726","loc":[-85.0830922,42.1038821]},"n1820937727":{"id":"n1820937727","loc":[-85.6342473,41.9360031]},"n1820937730":{"id":"n1820937730","loc":[-85.0500192,42.1024942]},"n1820937731":{"id":"n1820937731","loc":[-85.3498644,41.9926221]},"n1820937732":{"id":"n1820937732","loc":[-85.0234117,42.0918903]},"n1820937733":{"id":"n1820937733","loc":[-85.0464425,42.1009408]},"n1820937734":{"id":"n1820937734","loc":[-85.033938,42.099886]},"n1820937736":{"id":"n1820937736","loc":[-85.0152752,42.0886009]},"n1820937737":{"id":"n1820937737","loc":[-85.0441894,42.1012671]},"n1820937738":{"id":"n1820937738","loc":[-85.4668731,41.9979804]},"n1820937739":{"id":"n1820937739","loc":[-85.4407377,42.006033]},"n1820937740":{"id":"n1820937740","loc":[-85.2262253,42.0344878]},"n1820937741":{"id":"n1820937741","loc":[-85.2550001,42.0033706]},"n1820937742":{"id":"n1820937742","loc":[-85.3071422,41.9722617]},"n1820937743":{"id":"n1820937743","loc":[-85.6147852,41.942228]},"n1820937744":{"id":"n1820937744","loc":[-85.0183853,42.0901825]},"n1820937745":{"id":"n1820937745","loc":[-85.6323161,41.9228489]},"n1820937746":{"id":"n1820937746","loc":[-85.0095568,42.0901376]},"n1820937747":{"id":"n1820937747","loc":[-85.2524037,42.0113826]},"n1820937748":{"id":"n1820937748","loc":[-85.3186864,41.9708578]},"n1820937749":{"id":"n1820937749","loc":[-85.2805669,41.9870883]},"n1820937750":{"id":"n1820937750","loc":[-85.0585768,42.1038144]},"n1820937751":{"id":"n1820937751","loc":[-85.2970786,41.9715358]},"n1820937752":{"id":"n1820937752","loc":[-85.1315758,42.0723445]},"n1820937753":{"id":"n1820937753","loc":[-85.2448291,42.0175444]},"n1820937754":{"id":"n1820937754","loc":[-85.2446468,42.0174248]},"n1820937755":{"id":"n1820937755","loc":[-85.229165,42.032129]},"n1820937756":{"id":"n1820937756","loc":[-85.5612654,41.9724926]},"n1820937757":{"id":"n1820937757","loc":[-85.2331776,42.030854]},"n1820937758":{"id":"n1820937758","loc":[-85.2271909,42.0334519]},"n1820937759":{"id":"n1820937759","loc":[-85.1032396,42.0879214]},"n1820937760":{"id":"n1820937760","loc":[-85.0638447,42.1044154]},"n1820937761":{"id":"n1820937761","loc":[-85.1260706,42.0745556]},"n1820937762":{"id":"n1820937762","loc":[-85.3454485,41.99132]},"n1820937763":{"id":"n1820937763","loc":[-85.2639321,41.9980088]},"n1820937764":{"id":"n1820937764","loc":[-85.0837681,42.1013746]},"n1820937765":{"id":"n1820937765","loc":[-85.2808137,41.9869368]},"n1820937766":{"id":"n1820937766","loc":[-85.6338997,41.9309373]},"n1820937767":{"id":"n1820937767","loc":[-85.2267403,42.0332766]},"n1820937768":{"id":"n1820937768","loc":[-85.0605831,42.1052074]},"n1820937769":{"id":"n1820937769","loc":[-85.0259021,42.0930037]},"n1820937770":{"id":"n1820937770","loc":[-85.232963,42.0313162]},"n1820937771":{"id":"n1820937771","loc":[-85.2404947,42.0125381]},"n1820937772":{"id":"n1820937772","loc":[-85.0910892,42.0935742]},"n1820937773":{"id":"n1820937773","loc":[-85.2554829,42.0019435]},"n1820937774":{"id":"n1820937774","loc":[-85.2799339,41.9867773]},"n1820937775":{"id":"n1820937775","loc":[-85.1075432,42.0852767]},"n1820937776":{"id":"n1820937776","loc":[-85.1176927,42.0854001]},"n1820937777":{"id":"n1820937777","loc":[-85.1067064,42.0863357]},"n1820937778":{"id":"n1820937778","loc":[-85.2517492,42.0106333]},"n1820937779":{"id":"n1820937779","loc":[-85.0987174,42.0909031]},"n1820937780":{"id":"n1820937780","loc":[-85.1160083,42.0863994]},"n1820937781":{"id":"n1820937781","loc":[-85.1268645,42.0739703]},"n1820937782":{"id":"n1820937782","loc":[-85.0454702,42.1002852]},"n1820937783":{"id":"n1820937783","loc":[-85.1334145,42.0705418]},"n1820937784":{"id":"n1820937784","loc":[-85.5866542,41.947431]},"n1820937786":{"id":"n1820937786","loc":[-85.2359886,42.0250366]},"n1820937787":{"id":"n1820937787","loc":[-85.3138048,41.9698527]},"n1820937788":{"id":"n1820937788","loc":[-85.1274291,42.0733081]},"n1820937790":{"id":"n1820937790","loc":[-85.6292905,41.9411267]},"n1820937791":{"id":"n1820937791","loc":[-85.5958809,41.9417333]},"n1820937792":{"id":"n1820937792","loc":[-85.1271019,42.0737581]},"n1820937793":{"id":"n1820937793","loc":[-85.2312679,42.0314437]},"n1820937794":{"id":"n1820937794","loc":[-85.1081387,42.0863516]},"n1820937795":{"id":"n1820937795","loc":[-85.2424473,42.0212109]},"n1820937796":{"id":"n1820937796","loc":[-85.2710654,41.9975236]},"n1820937797":{"id":"n1820937797","loc":[-85.4798408,41.9863223]},"n1820937798":{"id":"n1820937798","loc":[-85.035939,42.104296]},"n1820937799":{"id":"n1820937799","loc":[-85.2178139,42.0395398]},"n1820937800":{"id":"n1820937800","loc":[-85.0630709,42.1042614]},"n1820937801":{"id":"n1820937801","loc":[-85.0440124,42.1014861]},"n1820937802":{"id":"n1820937802","loc":[-85.1321874,42.0720458]},"n1820937804":{"id":"n1820937804","loc":[-85.079427,42.1029121]},"n1820937805":{"id":"n1820937805","loc":[-85.2962632,41.9738968]},"n1820937806":{"id":"n1820937806","loc":[-85.6334748,41.9274627]},"n1820937807":{"id":"n1820937807","loc":[-85.1057341,42.0872804]},"n1820937808":{"id":"n1820937808","loc":[-85.4960169,41.9778263]},"n1820937809":{"id":"n1820937809","loc":[-85.2821226,41.9910273]},"n1820937810":{"id":"n1820937810","loc":[-85.0013868,42.0885054]},"n1820937811":{"id":"n1820937811","loc":[-85.2952547,41.9729795]},"n1820937812":{"id":"n1820937812","loc":[-85.1298375,42.0667842]},"n1820937813":{"id":"n1820937813","loc":[-85.1339201,42.0710025]},"n1820937814":{"id":"n1820937814","loc":[-85.0374356,42.103691]},"n1820937815":{"id":"n1820937815","loc":[-85.0061115,42.0880607]},"n1820937817":{"id":"n1820937817","loc":[-85.2398402,42.0226934]},"n1820937818":{"id":"n1820937818","loc":[-85.123501,42.076236]},"n1820937819":{"id":"n1820937819","loc":[-85.1209489,42.0791294]},"n1820937820":{"id":"n1820937820","loc":[-85.0818624,42.1025778]},"n1820937821":{"id":"n1820937821","loc":[-85.4428835,42.0054749]},"n1820937822":{"id":"n1820937822","loc":[-85.4710359,41.9961147]},"n1820937823":{"id":"n1820937823","loc":[-85.4253354,42.006198]},"n1820937824":{"id":"n1820937824","loc":[-85.5486483,41.9709451]},"n1820937825":{"id":"n1820937825","loc":[-85.2303238,42.0310452]},"n1820937826":{"id":"n1820937826","loc":[-85.6450405,41.9136361]},"n1820937828":{"id":"n1820937828","loc":[-85.2606853,41.9964073]},"n1820937830":{"id":"n1820937830","loc":[-85.097383,42.0911447]},"n1820937831":{"id":"n1820937831","loc":[-85.0498207,42.102136]},"n1820937832":{"id":"n1820937832","loc":[-85.1232435,42.0763793]},"n1820937833":{"id":"n1820937833","loc":[-85.394093,42.0055921]},"n1820937834":{"id":"n1820937834","loc":[-85.3566665,41.9928295]},"n1820937835":{"id":"n1820937835","loc":[-85.3543276,41.9920002]},"n1820937837":{"id":"n1820937837","loc":[-85.084668,42.1034932]},"n1820937838":{"id":"n1820937838","loc":[-85.4400296,42.0060649]},"n1820937839":{"id":"n1820937839","loc":[-85.2362246,42.025714]},"n1820937840":{"id":"n1820937840","loc":[-85.0409225,42.1012791]},"n1820937841":{"id":"n1820937841","loc":[-85.2442283,42.019832]},"n1820937842":{"id":"n1820937842","loc":[-85.1123001,42.084824]},"n1820937843":{"id":"n1820937843","loc":[-85.1603074,42.0638061]},"n1820937844":{"id":"n1820937844","loc":[-85.1359744,42.0650646]},"n1820937845":{"id":"n1820937845","loc":[-85.1757569,42.053849]},"n1820937846":{"id":"n1820937846","loc":[-85.5200925,41.9716686]},"n1820937848":{"id":"n1820937848","loc":[-85.5525322,41.9701315]},"n1820937849":{"id":"n1820937849","loc":[-85.0406489,42.10149]},"n1820937850":{"id":"n1820937850","loc":[-85.0142547,42.088825]},"n1820937851":{"id":"n1820937851","loc":[-85.343749,41.9881884]},"n1820937852":{"id":"n1820937852","loc":[-85.074996,42.1060205]},"n1820937853":{"id":"n1820937853","loc":[-85.2436275,42.0136864]},"n1820937854":{"id":"n1820937854","loc":[-85.2641453,41.9980897]},"n1820937856":{"id":"n1820937856","loc":[-85.2802343,41.9870086]},"n1820937857":{"id":"n1820937857","loc":[-85.0099256,42.0909946]},"n1820937858":{"id":"n1820937858","loc":[-85.493957,41.9786079]},"n1820937859":{"id":"n1820937859","loc":[-85.0739405,42.1059795]},"n1820937860":{"id":"n1820937860","loc":[-85.2331605,42.0301423]},"n1820937862":{"id":"n1820937862","loc":[-85.2035231,42.0438425]},"n1820937863":{"id":"n1820937863","loc":[-85.0884928,42.0986971]},"n1820937864":{"id":"n1820937864","loc":[-85.131597,42.0690142]},"n1820937865":{"id":"n1820937865","loc":[-85.3937454,42.0052677]},"n1820937866":{"id":"n1820937866","loc":[-85.2212729,42.0378561]},"n1820937867":{"id":"n1820937867","loc":[-85.0886068,42.0982421]},"n1820937868":{"id":"n1820937868","loc":[-85.0875004,42.0968064]},"n1820937869":{"id":"n1820937869","loc":[-85.0771323,42.1042642]},"n1820937870":{"id":"n1820937870","loc":[-85.0164554,42.0894887]},"n1820937871":{"id":"n1820937871","loc":[-85.6069102,41.9415577]},"n1820937872":{"id":"n1820937872","loc":[-85.3273875,41.9704908]},"n1820937873":{"id":"n1820937873","loc":[-85.3890891,41.9997983]},"n1820937875":{"id":"n1820937875","loc":[-85.5091276,41.9723705]},"n1820937876":{"id":"n1820937876","loc":[-85.0770626,42.1047696]},"n1820937877":{"id":"n1820937877","loc":[-85.612575,41.9419567]},"n1820937878":{"id":"n1820937878","loc":[-85.3868146,42.0036094]},"n1820937879":{"id":"n1820937879","loc":[-85.2722738,41.9981204]},"n1820937880":{"id":"n1820937880","loc":[-85.3064878,41.9723733]},"n1820937882":{"id":"n1820937882","loc":[-85.1270845,42.0727678]},"n1820937884":{"id":"n1820937884","loc":[-85.3316512,41.97923]},"n1820937885":{"id":"n1820937885","loc":[-85.3932519,42.0042472]},"n1820937886":{"id":"n1820937886","loc":[-85.2457411,42.0175444]},"n1820937887":{"id":"n1820937887","loc":[-85.1397509,42.0648415]},"n1820937891":{"id":"n1820937891","loc":[-85.3196735,41.9719665]},"n1820937892":{"id":"n1820937892","loc":[-85.3372473,41.9845033]},"n1820937894":{"id":"n1820937894","loc":[-85.3254778,41.9719745]},"n1820937897":{"id":"n1820937897","loc":[-85.3185148,41.9691268]},"n1820937899":{"id":"n1820937899","loc":[-85.5419106,41.9714556]},"n1820937901":{"id":"n1820937901","loc":[-85.3293509,41.9748368]},"n1820937903":{"id":"n1820937903","loc":[-85.0798078,42.1028365]},"n1820937905":{"id":"n1820937905","loc":[-85.3954191,42.0056025]},"n1820937909":{"id":"n1820937909","loc":[-85.3417534,41.9857155]},"n1820937913":{"id":"n1820937913","loc":[-84.9927822,42.0857107]},"n1820937915":{"id":"n1820937915","loc":[-85.5444212,41.9712801]},"n1820937917":{"id":"n1820937917","loc":[-85.259088,41.9981682]},"n1820937921":{"id":"n1820937921","loc":[-85.2784576,41.9876358]},"n1820937922":{"id":"n1820937922","loc":[-84.9971918,42.087753]},"n1820937924":{"id":"n1820937924","loc":[-85.5310688,41.966899]},"n1820937928":{"id":"n1820937928","loc":[-85.3766436,41.9979326]},"n1820937930":{"id":"n1820937930","loc":[-85.5494852,41.9704346]},"n1820937933":{"id":"n1820937933","loc":[-85.5548281,41.9695412]},"n1820937935":{"id":"n1820937935","loc":[-85.0768588,42.105088]},"n1820937937":{"id":"n1820937937","loc":[-85.2646885,41.9978054]},"n1820937939":{"id":"n1820937939","loc":[-85.2441532,42.0176082]},"n1820937941":{"id":"n1820937941","loc":[-85.105553,42.0877928]},"n1820937943":{"id":"n1820937943","loc":[-85.0879457,42.0958909]},"n1820937944":{"id":"n1820937944","loc":[-85.3187015,41.9704402]},"n1820937945":{"id":"n1820937945","loc":[-85.5624456,41.970626]},"n1820937946":{"id":"n1820937946","loc":[-85.0580176,42.1028644]},"n1820937948":{"id":"n1820937948","loc":[-85.3016061,41.9726286]},"n1820937949":{"id":"n1820937949","loc":[-85.4310388,42.0069418]},"n1820937950":{"id":"n1820937950","loc":[-85.2945144,41.9740723]},"n1820937951":{"id":"n1820937951","loc":[-85.1170222,42.082657]},"n1820937952":{"id":"n1820937952","loc":[-85.0864503,42.0947632]},"n1820937953":{"id":"n1820937953","loc":[-85.4285926,42.0059533]},"n1820937970":{"id":"n1820937970","loc":[-85.3629965,41.9938023]},"n1820937972":{"id":"n1820937972","loc":[-85.2438099,42.0199755]},"n1820937974":{"id":"n1820937974","loc":[-85.1327654,42.0699285]},"n1820937977":{"id":"n1820937977","loc":[-85.1515956,42.0611935]},"n1820937978":{"id":"n1820937978","loc":[-85.0107369,42.0896638]},"n1820937979":{"id":"n1820937979","loc":[-85.1152626,42.0862083]},"n1820937980":{"id":"n1820937980","loc":[-85.4531831,42.0062881]},"n1820937981":{"id":"n1820937981","loc":[-85.0341473,42.0985924]},"n1820937982":{"id":"n1820937982","loc":[-85.0877485,42.0960171]},"n1820937983":{"id":"n1820937983","loc":[-85.2756373,41.9951742]},"n1820937984":{"id":"n1820937984","loc":[-85.2965421,41.9714401]},"n1820937985":{"id":"n1820937985","loc":[-85.2409775,42.0226934]},"n1820937986":{"id":"n1820937986","loc":[-85.0170723,42.0900579]},"n1820937987":{"id":"n1820937987","loc":[-85.1034663,42.0880555]},"n1820937988":{"id":"n1820937988","loc":[-85.0585071,42.1031577]},"n1820937990":{"id":"n1820937990","loc":[-85.0819174,42.1032373]},"n1820937992":{"id":"n1820937992","loc":[-85.0546608,42.1030542]},"n1820937993":{"id":"n1820937993","loc":[-85.0100811,42.0906125]},"n1820937995":{"id":"n1820937995","loc":[-85.6304278,41.9432655]},"n1820937997":{"id":"n1820937997","loc":[-85.0255628,42.092778]},"n1820938011":{"id":"n1820938011","loc":[-85.2316756,42.0317146]},"n1820938012":{"id":"n1820938012","loc":[-85.4067917,42.008042]},"n1820938013":{"id":"n1820938013","loc":[-85.390398,42.0028759]},"n1820938014":{"id":"n1820938014","loc":[-85.0161604,42.0886527]},"n1820938015":{"id":"n1820938015","loc":[-85.125337,42.0744589]},"n1820938016":{"id":"n1820938016","loc":[-85.2151317,42.0404801]},"n1820938017":{"id":"n1820938017","loc":[-85.3165085,41.9706025]},"n1820938018":{"id":"n1820938018","loc":[-85.5641193,41.9640688]},"n1820938019":{"id":"n1820938019","loc":[-85.147583,42.0642203]},"n1820938022":{"id":"n1820938022","loc":[-85.2803781,41.9947886]},"n1820938024":{"id":"n1820938024","loc":[-85.2692469,41.9982053]},"n1820938026":{"id":"n1820938026","loc":[-85.4321975,42.0067505]},"n1820938028":{"id":"n1820938028","loc":[-85.572535,41.9633405]},"n1820938030":{"id":"n1820938030","loc":[-85.3237505,41.9716475]},"n1820938032":{"id":"n1820938032","loc":[-85.6487698,41.9141583]},"n1820938033":{"id":"n1820938033","loc":[-85.0526371,42.1038315]},"n1820938034":{"id":"n1820938034","loc":[-85.088069,42.0978731]},"n1820938035":{"id":"n1820938035","loc":[-85.2516312,42.0102267]},"n1820938039":{"id":"n1820938039","loc":[-85.2731374,41.9982958]},"n1820938040":{"id":"n1820938040","loc":[-85.5453224,41.9713439]},"n1820938041":{"id":"n1820938041","loc":[-85.4480548,42.0049647]},"n1820938043":{"id":"n1820938043","loc":[-85.2504081,42.010322]},"n1820938045":{"id":"n1820938045","loc":[-85.2663447,41.99919]},"n1820938046":{"id":"n1820938046","loc":[-85.0507287,42.102907]},"n1820938047":{"id":"n1820938047","loc":[-85.0408246,42.1024743]},"n1820938048":{"id":"n1820938048","loc":[-85.2796335,41.9866099]},"n1820938050":{"id":"n1820938050","loc":[-85.452475,42.0061127]},"n1820938051":{"id":"n1820938051","loc":[-85.2410569,42.0128147]},"n1820938052":{"id":"n1820938052","loc":[-85.0413302,42.1011477]},"n1820938053":{"id":"n1820938053","loc":[-85.6327409,41.9197627]},"n1820938056":{"id":"n1820938056","loc":[-85.1072039,42.0857994]},"n1820938057":{"id":"n1820938057","loc":[-85.2001114,42.0448145]},"n1820938058":{"id":"n1820938058","loc":[-85.2655347,41.9978186]},"n1820938059":{"id":"n1820938059","loc":[-85.2330918,42.0304874]},"n1820938060":{"id":"n1820938060","loc":[-85.2601113,41.9966545]},"n1820938061":{"id":"n1820938061","loc":[-85.5397863,41.9708494]},"n1820938062":{"id":"n1820938062","loc":[-85.2702085,41.9977217]},"n1820938063":{"id":"n1820938063","loc":[-85.2219982,42.03699]},"n1820938064":{"id":"n1820938064","loc":[-85.0668957,42.105121]},"n1820938065":{"id":"n1820938065","loc":[-85.2328665,42.0270769]},"n1820938066":{"id":"n1820938066","loc":[-85.3189654,41.9694778]},"n1820938067":{"id":"n1820938067","loc":[-85.3814115,42.0022915]},"n1820938068":{"id":"n1820938068","loc":[-85.2759108,41.9956008]},"n1820938069":{"id":"n1820938069","loc":[-85.0391938,42.1034853]},"n1820938070":{"id":"n1820938070","loc":[-85.2850623,41.9810353]},"n1820938071":{"id":"n1820938071","loc":[-85.538074,41.970855]},"n1820938073":{"id":"n1820938073","loc":[-85.1319661,42.0670932]},"n1820938074":{"id":"n1820938074","loc":[-85.2816763,41.9913678]},"n1820938075":{"id":"n1820938075","loc":[-85.3182144,41.9700282]},"n1820938076":{"id":"n1820938076","loc":[-85.5909028,41.9458989]},"n1820938077":{"id":"n1820938077","loc":[-85.4057617,42.0074361]},"n1820938078":{"id":"n1820938078","loc":[-85.2620438,41.9967729]},"n1820938079":{"id":"n1820938079","loc":[-85.1122143,42.0851107]},"n1820938080":{"id":"n1820938080","loc":[-85.2443785,42.0174567]},"n1820938081":{"id":"n1820938081","loc":[-85.0319733,42.0953853]},"n1820938082":{"id":"n1820938082","loc":[-85.0878276,42.09443]},"n1820938083":{"id":"n1820938083","loc":[-85.0271789,42.0935809]},"n1820938084":{"id":"n1820938084","loc":[-85.0326399,42.0974222]},"n1820938085":{"id":"n1820938085","loc":[-85.3989167,42.0065592]},"n1820938086":{"id":"n1820938086","loc":[-85.3263361,41.9721261]},"n1820938087":{"id":"n1820938087","loc":[-85.2547855,42.0037134]},"n1820938088":{"id":"n1820938088","loc":[-85.4373259,42.005746]},"n1820938089":{"id":"n1820938089","loc":[-85.3094275,41.9699245]},"n1820938090":{"id":"n1820938090","loc":[-85.2783246,41.9872793]},"n1820938092":{"id":"n1820938092","loc":[-85.0815633,42.1025169]},"n1820938093":{"id":"n1820938093","loc":[-85.1788511,42.0522134]},"n1820938095":{"id":"n1820938095","loc":[-85.2830345,41.9816733]},"n1820938096":{"id":"n1820938096","loc":[-85.0744984,42.1059835]},"n1820938097":{"id":"n1820938097","loc":[-85.2788396,41.9879333]},"n1820938098":{"id":"n1820938098","loc":[-85.3640093,41.9946531]},"n1820938099":{"id":"n1820938099","loc":[-85.291167,41.9787463]},"n1820938100":{"id":"n1820938100","loc":[-85.0772436,42.1038156]},"n1820938101":{"id":"n1820938101","loc":[-85.00563,42.0887482]},"n1820938102":{"id":"n1820938102","loc":[-85.0326881,42.0961245]},"n1820938104":{"id":"n1820938104","loc":[-85.0530448,42.1038634]},"n1820938105":{"id":"n1820938105","loc":[-85.2625266,41.9970639]},"n1820938106":{"id":"n1820938106","loc":[-85.2827556,41.9823512]},"n1820938107":{"id":"n1820938107","loc":[-85.2784319,41.9910752]},"n1820938108":{"id":"n1820938108","loc":[-85.0882099,42.094393]},"n1820938109":{"id":"n1820938109","loc":[-85.5718484,41.9645371]},"n1820938110":{"id":"n1820938110","loc":[-85.2559764,42.0099317]},"n1820938111":{"id":"n1820938111","loc":[-85.2969284,41.973179]},"n1820938113":{"id":"n1820938113","loc":[-85.3875055,42.0019726]},"n1820938114":{"id":"n1820938114","loc":[-85.4250779,42.0068199]},"n1820938115":{"id":"n1820938115","loc":[-85.0645367,42.104889]},"n1820938116":{"id":"n1820938116","loc":[-85.1636762,42.0623724]},"n1820938117":{"id":"n1820938117","loc":[-85.0757322,42.1055935]},"n1820938118":{"id":"n1820938118","loc":[-85.3695197,41.9981559]},"n1820938120":{"id":"n1820938120","loc":[-85.1297516,42.0671027]},"n1820938121":{"id":"n1820938121","loc":[-85.1057448,42.0875551]},"n1820938122":{"id":"n1820938122","loc":[-85.2805175,41.9943182]},"n1820938123":{"id":"n1820938123","loc":[-85.2545173,42.0040722]},"n1820938124":{"id":"n1820938124","loc":[-84.9966607,42.0871319]},"n1820938125":{"id":"n1820938125","loc":[-85.0099899,42.0904612]},"n1820938126":{"id":"n1820938126","loc":[-85.2489919,42.0091102]},"n1820938127":{"id":"n1820938127","loc":[-85.0342706,42.0979476]},"n1820938128":{"id":"n1820938128","loc":[-85.1080891,42.0855884]},"n1820938129":{"id":"n1820938129","loc":[-85.0128183,42.0905356]},"n1820938130":{"id":"n1820938130","loc":[-85.631608,41.9434251]},"n1820938131":{"id":"n1820938131","loc":[-85.2551975,42.0008524]},"n1820938132":{"id":"n1820938132","loc":[-85.6421823,41.9096233]},"n1820938133":{"id":"n1820938133","loc":[-85.0125059,42.0906284]},"n1820938134":{"id":"n1820938134","loc":[-85.5499358,41.9701793]},"n1820938135":{"id":"n1820938135","loc":[-85.5472107,41.9712323]},"n1820938136":{"id":"n1820938136","loc":[-85.2760758,41.9958691]},"n1820938137":{"id":"n1820938137","loc":[-85.276678,41.9960433]},"n1820938138":{"id":"n1820938138","loc":[-85.0570319,42.1024731]},"n1820938140":{"id":"n1820938140","loc":[-85.2394325,42.0227492]},"n1820938142":{"id":"n1820938142","loc":[-85.5666341,41.9638829]},"n1820938144":{"id":"n1820938144","loc":[-85.258101,41.9996353]},"n1820938147":{"id":"n1820938147","loc":[-85.2129645,42.0413565]},"n1820938149":{"id":"n1820938149","loc":[-84.9962369,42.0868373]},"n1820938151":{"id":"n1820938151","loc":[-85.2570386,42.0084968]},"n1820938153":{"id":"n1820938153","loc":[-85.3971142,42.0050285]},"n1820938155":{"id":"n1820938155","loc":[-85.1072093,42.0855566]},"n1820938157":{"id":"n1820938157","loc":[-85.2840323,41.9920959]},"n1820938159":{"id":"n1820938159","loc":[-85.1187924,42.0816458]},"n1820938161":{"id":"n1820938161","loc":[-85.2681324,41.9985788]},"n1820938163":{"id":"n1820938163","loc":[-85.0887034,42.0984969]},"n1820938165":{"id":"n1820938165","loc":[-85.4133405,42.0073141]},"n1820938166":{"id":"n1820938166","loc":[-85.0097445,42.0902888]},"n1820938167":{"id":"n1820938167","loc":[-85.0828133,42.1037388]},"n1820938168":{"id":"n1820938168","loc":[-85.0549599,42.1030833]},"n1820938169":{"id":"n1820938169","loc":[-85.4571528,42.0010421]},"n1820938178":{"id":"n1820938178","loc":[-85.2706644,41.9975941]},"n1820938180":{"id":"n1820938180","loc":[-85.2258606,42.0335794]},"n1820938182":{"id":"n1820938182","loc":[-85.2832276,41.9814659]},"n1820938184":{"id":"n1820938184","loc":[-85.1082299,42.0860928]},"n1820938185":{"id":"n1820938185","loc":[-85.3839392,42.0022381]},"n1820938186":{"id":"n1820938186","loc":[-85.2772131,41.995905]},"n1820938187":{"id":"n1820938187","loc":[-85.1044895,42.0879214]},"n1820938188":{"id":"n1820938188","loc":[-85.2135267,42.0407087]},"n1820938189":{"id":"n1820938189","loc":[-85.2543993,42.0044628]},"n1820938190":{"id":"n1820938190","loc":[-85.1501793,42.0617351]},"n1820938191":{"id":"n1820938191","loc":[-85.3350587,41.9820469]},"n1820938192":{"id":"n1820938192","loc":[-85.1350731,42.0655735]},"n1820938193":{"id":"n1820938193","loc":[-85.0404008,42.1028843]},"n1820938194":{"id":"n1820938194","loc":[-85.6323161,41.943042]},"n1820938195":{"id":"n1820938195","loc":[-85.1259593,42.0742837]},"n1820938196":{"id":"n1820938196","loc":[-85.4562988,42.0033758]},"n1820938197":{"id":"n1820938197","loc":[-85.256824,42.0056826]},"n1820938198":{"id":"n1820938198","loc":[-85.2742103,41.9963862]},"n1820938199":{"id":"n1820938199","loc":[-85.0380888,42.1037877]},"n1820938200":{"id":"n1820938200","loc":[-85.47404,41.9944721]},"n1820938201":{"id":"n1820938201","loc":[-85.103021,42.087948]},"n1820938202":{"id":"n1820938202","loc":[-85.4030151,42.0065113]},"n1820938203":{"id":"n1820938203","loc":[-85.2113981,42.040735]},"n1820938204":{"id":"n1820938204","loc":[-85.2603433,41.9965137]},"n1820938206":{"id":"n1820938206","loc":[-85.1669378,42.0607634]},"n1820938207":{"id":"n1820938207","loc":[-85.0642027,42.1046076]},"n1820938208":{"id":"n1820938208","loc":[-85.2812428,41.9915696]},"n1820938209":{"id":"n1820938209","loc":[-85.0839559,42.1038343]},"n1820938210":{"id":"n1820938210","loc":[-85.1239946,42.0769368]},"n1820938211":{"id":"n1820938211","loc":[-85.2311177,42.0283042]},"n1820938212":{"id":"n1820938212","loc":[-85.2791614,41.9882682]},"n1820938213":{"id":"n1820938213","loc":[-85.2674941,41.9987582]},"n1820938214":{"id":"n1820938214","loc":[-85.352787,41.9919579]},"n1820938215":{"id":"n1820938215","loc":[-85.0874146,42.0952182]},"n1820938216":{"id":"n1820938216","loc":[-85.0069711,42.0877092]},"n1820938217":{"id":"n1820938217","loc":[-85.2059049,42.0404004]},"n1820938218":{"id":"n1820938218","loc":[-85.2403552,42.0227332]},"n1820938219":{"id":"n1820938219","loc":[-85.2492923,42.0098915]},"n1820938220":{"id":"n1820938220","loc":[-85.269778,41.9979541]},"n1820938221":{"id":"n1820938221","loc":[-85.2097673,42.0389024]},"n1820938222":{"id":"n1820938222","loc":[-85.0845942,42.1032015]},"n1820938223":{"id":"n1820938223","loc":[-84.993206,42.0858142]},"n1820938224":{"id":"n1820938224","loc":[-85.2108187,42.0402729]},"n1820938225":{"id":"n1820938225","loc":[-84.9893959,42.0873043]},"n1820938226":{"id":"n1820938226","loc":[-85.2952332,41.9719984]},"n1820938227":{"id":"n1820938227","loc":[-85.4100961,42.0081536]},"n1820938228":{"id":"n1820938228","loc":[-85.3299088,41.9785696]},"n1820938229":{"id":"n1820938229","loc":[-85.2258176,42.0340097]},"n1820938230":{"id":"n1820938230","loc":[-85.3146739,41.9711449]},"n1820938231":{"id":"n1820938231","loc":[-85.5447645,41.9712801]},"n1820938232":{"id":"n1820938232","loc":[-85.5510087,41.9705941]},"n1820938233":{"id":"n1820938233","loc":[-85.5122389,41.9703445]},"n1820938234":{"id":"n1820938234","loc":[-85.2792687,41.9865381]},"n1820938235":{"id":"n1820938235","loc":[-85.1475229,42.0630151]},"n1820938237":{"id":"n1820938237","loc":[-85.0332889,42.0996034]},"n1820938238":{"id":"n1820938238","loc":[-85.2588882,41.9986877]},"n1820938239":{"id":"n1820938239","loc":[-85.0656458,42.1050892]},"n1820938240":{"id":"n1820938240","loc":[-84.9913915,42.086098]},"n1820938241":{"id":"n1820938241","loc":[-85.4752416,41.9944402]},"n1820938242":{"id":"n1820938242","loc":[-85.1214304,42.0791147]},"n1820938243":{"id":"n1820938243","loc":[-85.0075183,42.0886925]},"n1820938244":{"id":"n1820938244","loc":[-85.1052888,42.0872087]},"n1820938245":{"id":"n1820938245","loc":[-85.3104252,41.9703393]},"n1820938246":{"id":"n1820938246","loc":[-85.232109,42.0318158]},"n1820938247":{"id":"n1820938247","loc":[-85.0756075,42.1059528]},"n1820938248":{"id":"n1820938248","loc":[-85.0075612,42.0890866]},"n1820938249":{"id":"n1820938249","loc":[-85.1013312,42.0897474]},"n1820938250":{"id":"n1820938250","loc":[-85.1168076,42.0828919]},"n1820938251":{"id":"n1820938251","loc":[-85.2951367,41.9723334]},"n1820938252":{"id":"n1820938252","loc":[-85.0879363,42.0976053]},"n1820938253":{"id":"n1820938253","loc":[-85.0354763,42.1021838]},"n1820938254":{"id":"n1820938254","loc":[-85.2379627,42.0236339]},"n1820938255":{"id":"n1820938255","loc":[-85.1308245,42.0685364]},"n1820938256":{"id":"n1820938256","loc":[-85.0914446,42.0934774]},"n1820938257":{"id":"n1820938257","loc":[-85.2436812,42.014069]},"n1820938258":{"id":"n1820938258","loc":[-85.0682529,42.1056106]},"n1820938259":{"id":"n1820938259","loc":[-85.290652,41.9766805]},"n1820938260":{"id":"n1820938260","loc":[-85.0133494,42.0897434]},"n1820938261":{"id":"n1820938261","loc":[-85.2753047,41.9949429]},"n1820938262":{"id":"n1820938262","loc":[-85.0314691,42.0950788]},"n1820938263":{"id":"n1820938263","loc":[-85.3444786,41.9908359]},"n1820938264":{"id":"n1820938264","loc":[-85.0443115,42.1009061]},"n1820938265":{"id":"n1820938265","loc":[-85.0634853,42.1043159]},"n1820938267":{"id":"n1820938267","loc":[-85.3978223,42.0053952]},"n1820938268":{"id":"n1820938268","loc":[-85.0228659,42.0911885]},"n1820938269":{"id":"n1820938269","loc":[-85.0220237,42.0906272]},"n1820938270":{"id":"n1820938270","loc":[-85.1061525,42.0863369]},"n1820938271":{"id":"n1820938271","loc":[-85.2382309,42.0233708]},"n1820938272":{"id":"n1820938272","loc":[-85.310672,41.9702755]},"n1820938273":{"id":"n1820938273","loc":[-85.1448192,42.0652613]},"n1820938274":{"id":"n1820938274","loc":[-85.6036057,41.9403766]},"n1820938275":{"id":"n1820938275","loc":[-85.0778941,42.1032413]},"n1820938276":{"id":"n1820938276","loc":[-85.1279374,42.0723974]},"n1820938277":{"id":"n1820938277","loc":[-85.2806635,41.9847836]},"n1820938278":{"id":"n1820938278","loc":[-85.2653201,41.9976352]},"n1820938279":{"id":"n1820938279","loc":[-85.0351665,42.1001805]},"n1820938280":{"id":"n1820938280","loc":[-85.0718269,42.1056253]},"n1820938281":{"id":"n1820938281","loc":[-85.2574248,42.0075322]},"n1820938282":{"id":"n1820938282","loc":[-85.126666,42.0740778]},"n1820938283":{"id":"n1820938283","loc":[-85.077705,42.1034733]},"n1820938284":{"id":"n1820938284","loc":[-85.3535552,41.9919045]},"n1820938286":{"id":"n1820938286","loc":[-85.2810711,41.9866657]},"n1820938287":{"id":"n1820938287","loc":[-85.4567494,42.0019885]},"n1820938288":{"id":"n1820938288","loc":[-85.2642419,41.9992936]},"n1820938289":{"id":"n1820938289","loc":[-85.2643344,41.9980925]},"n1820938290":{"id":"n1820938290","loc":[-85.3270335,41.9776125]},"n1820938291":{"id":"n1820938291","loc":[-85.1200584,42.0795077]},"n1820938292":{"id":"n1820938292","loc":[-85.2290792,42.0340256]},"n1820938293":{"id":"n1820938293","loc":[-85.6015887,41.9401372]},"n1820938294":{"id":"n1820938294","loc":[-85.5370869,41.970488]},"n1820938295":{"id":"n1820938295","loc":[-85.3108866,41.9698048]},"n1820938297":{"id":"n1820938297","loc":[-85.1556511,42.0628184]},"n1820938298":{"id":"n1820938298","loc":[-85.0027922,42.0875221]},"n1820938300":{"id":"n1820938300","loc":[-85.3873338,42.0040614]},"n1820938301":{"id":"n1820938301","loc":[-85.0350753,42.1004034]},"n1820938302":{"id":"n1820938302","loc":[-85.6239476,41.9411906]},"n1820938304":{"id":"n1820938304","loc":[-85.0118246,42.0897964]},"n1820938306":{"id":"n1820938306","loc":[-85.4796877,41.995275]},"n1820938307":{"id":"n1820938307","loc":[-85.5388636,41.9707856]},"n1820938309":{"id":"n1820938309","loc":[-85.2971902,41.9727773]},"n1820938310":{"id":"n1820938310","loc":[-85.5426831,41.9715513]},"n1820938311":{"id":"n1820938311","loc":[-85.2798373,41.9836671]},"n1820938312":{"id":"n1820938312","loc":[-85.2432198,42.0104017]},"n1820938313":{"id":"n1820938313","loc":[-85.2650412,41.9987554]},"n1820938317":{"id":"n1820938317","loc":[-85.0015423,42.0882386]},"n1820938318":{"id":"n1820938318","loc":[-85.1409783,42.064879]},"n1820938319":{"id":"n1820938319","loc":[-85.1691908,42.058995]},"n1820938320":{"id":"n1820938320","loc":[-85.1059165,42.0864882]},"n1820938321":{"id":"n1820938321","loc":[-85.3664941,41.9965771]},"n1820938323":{"id":"n1820938323","loc":[-85.3143198,41.9710971]},"n1820938324":{"id":"n1820938324","loc":[-85.0016067,42.0880675]},"n1820938325":{"id":"n1820938325","loc":[-85.0148139,42.0887164]},"n1820938326":{"id":"n1820938326","loc":[-85.0324682,42.0959056]},"n1820938327":{"id":"n1820938327","loc":[-85.0898661,42.0939921]},"n1820938328":{"id":"n1820938328","loc":[-85.2556427,42.0004936]},"n1820938329":{"id":"n1820938329","loc":[-85.6287112,41.9407437]},"n1820938330":{"id":"n1820938330","loc":[-84.9913392,42.0866701]},"n1820938331":{"id":"n1820938331","loc":[-85.2685777,41.9984632]},"n1820938332":{"id":"n1820938332","loc":[-85.0078884,42.0901614]},"n1820938333":{"id":"n1820938333","loc":[-84.999642,42.0878616]},"n1820938334":{"id":"n1820938334","loc":[-85.0188909,42.0899186]},"n1820938335":{"id":"n1820938335","loc":[-85.2830238,41.9819843]},"n1820938336":{"id":"n1820938336","loc":[-85.2491421,42.0096204]},"n1820938337":{"id":"n1820938337","loc":[-85.0585701,42.1034295]},"n1820938338":{"id":"n1820938338","loc":[-85.0651965,42.1051636]},"n1820938339":{"id":"n1820938339","loc":[-85.0583944,42.104292]},"n1820938340":{"id":"n1820938340","loc":[-85.119876,42.0801567]},"n1820938341":{"id":"n1820938341","loc":[-85.0943937,42.0931323]},"n1820938342":{"id":"n1820938342","loc":[-85.1504583,42.0613209]},"n1820938343":{"id":"n1820938343","loc":[-85.0425426,42.1019836]},"n1820938345":{"id":"n1820938345","loc":[-84.9991391,42.0878206]},"n1820938346":{"id":"n1820938346","loc":[-85.2563841,42.0094614]},"n1820938347":{"id":"n1820938347","loc":[-85.0515387,42.103297]},"n1820938348":{"id":"n1820938348","loc":[-85.0857261,42.1003636]},"n1820938349":{"id":"n1820938349","loc":[-85.078971,42.1029241]},"n1820938350":{"id":"n1820938350","loc":[-85.5699558,41.958931]},"n1820938351":{"id":"n1820938351","loc":[-85.3181285,41.9696533]},"n1820938352":{"id":"n1820938352","loc":[-85.5998506,41.9402329]},"n1820938353":{"id":"n1820938353","loc":[-85.2567277,42.000317]},"n1820938354":{"id":"n1820938354","loc":[-85.3082795,41.9708338]},"n1820938355":{"id":"n1820938355","loc":[-85.3127856,41.9692784]},"n1820938356":{"id":"n1820938356","loc":[-85.0340775,42.1010721]},"n1820938357":{"id":"n1820938357","loc":[-85.3158111,41.9706583]},"n1820938359":{"id":"n1820938359","loc":[-85.2312035,42.0280412]},"n1820938360":{"id":"n1820938360","loc":[-85.2448613,42.018477]},"n1820938361":{"id":"n1820938361","loc":[-85.29077,41.9759068]},"n1820938364":{"id":"n1820938364","loc":[-85.3677387,41.9976615]},"n1820938365":{"id":"n1820938365","loc":[-85.0785204,42.1030355]},"n1820938366":{"id":"n1820938366","loc":[-85.2262039,42.0333722]},"n1820938367":{"id":"n1820938367","loc":[-85.1226011,42.0780902]},"n1820938368":{"id":"n1820938368","loc":[-85.3229673,41.971129]},"n1820938369":{"id":"n1820938369","loc":[-85.385334,42.0000056]},"n1820938370":{"id":"n1820938370","loc":[-85.000098,42.0879094]},"n1820938372":{"id":"n1820938372","loc":[-85.3852481,42.0025091]},"n1820938373":{"id":"n1820938373","loc":[-85.3770513,41.9982515]},"n1820938374":{"id":"n1820938374","loc":[-85.6278314,41.9405362]},"n1820938375":{"id":"n1820938375","loc":[-85.6355133,41.9344068]},"n1820938376":{"id":"n1820938376","loc":[-85.635642,41.9324753]},"n1820938377":{"id":"n1820938377","loc":[-85.3154463,41.970778]},"n1820938378":{"id":"n1820938378","loc":[-85.0920334,42.093411]},"n1820938379":{"id":"n1820938379","loc":[-85.3269155,41.9722297]},"n1820938381":{"id":"n1820938381","loc":[-85.1134334,42.0849184]},"n1820938382":{"id":"n1820938382","loc":[-85.005968,42.088585]},"n1820938384":{"id":"n1820938384","loc":[-85.1245203,42.0757183]},"n1820938385":{"id":"n1820938385","loc":[-85.020704,42.0905396]},"n1820938386":{"id":"n1820938386","loc":[-85.119585,42.0808984]},"n1820938387":{"id":"n1820938387","loc":[-85.0072447,42.0880117]},"n1820938388":{"id":"n1820938388","loc":[-85.2742908,41.9960273]},"n1820938389":{"id":"n1820938389","loc":[-85.3275807,41.9696852]},"n1820938390":{"id":"n1820938390","loc":[-85.2385635,42.0231556]},"n1820938392":{"id":"n1820938392","loc":[-85.0202856,42.0900778]},"n1820938393":{"id":"n1820938393","loc":[-85.2067847,42.0395398]},"n1820938394":{"id":"n1820938394","loc":[-85.5183544,41.9713495]},"n1820938396":{"id":"n1820938396","loc":[-85.5073037,41.9736787]},"n1820938397":{"id":"n1820938397","loc":[-85.2519638,42.0114225]},"n1820938398":{"id":"n1820938398","loc":[-85.287487,41.9793285]},"n1820938399":{"id":"n1820938399","loc":[-85.2298088,42.0336431]},"n1820938400":{"id":"n1820938400","loc":[-85.229444,42.0339141]},"n1820938401":{"id":"n1820938401","loc":[-85.2421791,42.0220239]},"n1820938402":{"id":"n1820938402","loc":[-85.2976687,41.9737612]},"n1820938403":{"id":"n1820938403","loc":[-85.3622069,41.993473]},"n1820938404":{"id":"n1820938404","loc":[-85.2465458,42.014906]},"n1820938405":{"id":"n1820938405","loc":[-85.5724663,41.9639412]},"n1820938406":{"id":"n1820938406","loc":[-85.3708501,41.9982037]},"n1820938408":{"id":"n1820938408","loc":[-85.2564592,42.0055311]},"n1820938409":{"id":"n1820938409","loc":[-85.1192846,42.0810856]},"n1820938410":{"id":"n1820938410","loc":[-85.5623812,41.971663]},"n1820938411":{"id":"n1820938411","loc":[-85.3221948,41.9719665]},"n1820938412":{"id":"n1820938412","loc":[-85.5168738,41.9710305]},"n1820938413":{"id":"n1820938413","loc":[-85.4546852,42.0061127]},"n1820938414":{"id":"n1820938414","loc":[-85.5896153,41.9463617]},"n1820938415":{"id":"n1820938415","loc":[-85.2978189,41.9722138]},"n1820938416":{"id":"n1820938416","loc":[-85.1021681,42.0883581]},"n1820938417":{"id":"n1820938417","loc":[-85.2797193,41.9912984]},"n1820938419":{"id":"n1820938419","loc":[-85.2362461,42.0248533]},"n1820938420":{"id":"n1820938420","loc":[-85.4833639,41.9846252]},"n1820938422":{"id":"n1820938422","loc":[-85.3281064,41.9689433]},"n1820938424":{"id":"n1820938424","loc":[-85.2416963,42.0130088]},"n1820938425":{"id":"n1820938425","loc":[-85.5718655,41.9564577]},"n1820938426":{"id":"n1820938426","loc":[-85.0512812,42.1030701]},"n1820938427":{"id":"n1820938427","loc":[-85.1273527,42.0723616]},"n1820938428":{"id":"n1820938428","loc":[-85.0215033,42.0904083]},"n1820938429":{"id":"n1820938429","loc":[-85.6169953,41.942228]},"n1820938430":{"id":"n1820938430","loc":[-85.2829165,41.9907243]},"n1820938431":{"id":"n1820938431","loc":[-85.2240796,42.0374203]},"n1820938432":{"id":"n1820938432","loc":[-85.0167598,42.0898442]},"n1820938433":{"id":"n1820938433","loc":[-85.2132649,42.0411334]},"n1820938434":{"id":"n1820938434","loc":[-85.2293839,42.031513]},"n1820938435":{"id":"n1820938435","loc":[-85.1203374,42.0792608]},"n1820938436":{"id":"n1820938436","loc":[-85.109571,42.086268]},"n1820938437":{"id":"n1820938437","loc":[-85.1079026,42.0853842]},"n1820938438":{"id":"n1820938438","loc":[-85.109237,42.0862413]},"n1820938439":{"id":"n1820938439","loc":[-85.2259936,42.0350831]},"n1820938440":{"id":"n1820938440","loc":[-85.3669705,41.99679]},"n1820938441":{"id":"n1820938441","loc":[-85.2418143,42.0223507]},"n1820938442":{"id":"n1820938442","loc":[-85.3101248,41.9702515]},"n1820938443":{"id":"n1820938443","loc":[-85.069315,42.1059688]},"n1820938444":{"id":"n1820938444","loc":[-85.205862,42.0410378]},"n1820938445":{"id":"n1820938445","loc":[-85.0388076,42.1036604]},"n1820938446":{"id":"n1820938446","loc":[-85.2225389,42.0370115]},"n1820938447":{"id":"n1820938447","loc":[-85.3241474,41.9719346]},"n1820938448":{"id":"n1820938448","loc":[-85.3125496,41.9690789]},"n1820938449":{"id":"n1820938449","loc":[-85.1146497,42.0857039]},"n1820938450":{"id":"n1820938450","loc":[-85.1333944,42.0714963]},"n1820938451":{"id":"n1820938451","loc":[-85.5619306,41.9720937]},"n1820938452":{"id":"n1820938452","loc":[-85.2553651,42.0006479]},"n1820938453":{"id":"n1820938453","loc":[-85.3151137,41.9710093]},"n1820938454":{"id":"n1820938454","loc":[-85.2592315,41.9977947]},"n1820938455":{"id":"n1820938455","loc":[-85.2655723,41.9995966]},"n1820938456":{"id":"n1820938456","loc":[-85.4820652,41.9959233]},"n1820938459":{"id":"n1820938459","loc":[-85.450737,42.0055068]},"n1820938460":{"id":"n1820938460","loc":[-85.2428658,42.0205573]},"n1820938461":{"id":"n1820938461","loc":[-85.0835576,42.1021559]},"n1820938462":{"id":"n1820938462","loc":[-85.244636,42.0194733]},"n1820938463":{"id":"n1820938463","loc":[-85.5702562,41.9581332]},"n1820938465":{"id":"n1820938465","loc":[-85.5680031,41.9659515]},"n1820938467":{"id":"n1820938467","loc":[-85.2798752,41.9948353]},"n1820938468":{"id":"n1820938468","loc":[-85.0477407,42.1015537]},"n1820938469":{"id":"n1820938469","loc":[-85.6403842,41.913732]},"n1820938470":{"id":"n1820938470","loc":[-85.0396029,42.103289]},"n1820938471":{"id":"n1820938471","loc":[-85.2824702,41.9907777]},"n1820938472":{"id":"n1820938472","loc":[-85.2969284,41.9735538]},"n1820938474":{"id":"n1820938474","loc":[-85.401041,42.0070853]},"n1820938475":{"id":"n1820938475","loc":[-85.4116625,42.0073883]},"n1820938476":{"id":"n1820938476","loc":[-85.0437764,42.1016214]},"n1820938477":{"id":"n1820938477","loc":[-85.3643269,41.9958436]},"n1820938478":{"id":"n1820938478","loc":[-85.3895182,42.0009465]},"n1820938479":{"id":"n1820938479","loc":[-85.636157,41.9333373]},"n1820938480":{"id":"n1820938480","loc":[-85.2811355,41.9858044]},"n1820938481":{"id":"n1820938481","loc":[-85.0239052,42.092153]},"n1820938482":{"id":"n1820938482","loc":[-85.2558798,42.0053557]},"n1820938483":{"id":"n1820938483","loc":[-85.2544422,42.0047339]},"n1820938484":{"id":"n1820938484","loc":[-85.4864683,41.9843183]},"n1820938485":{"id":"n1820938485","loc":[-85.2554185,42.0031075]},"n1820938486":{"id":"n1820938486","loc":[-85.3082795,41.9712486]},"n1820938487":{"id":"n1820938487","loc":[-85.2433378,42.0133436]},"n1820938488":{"id":"n1820938488","loc":[-85.0216696,42.0904162]},"n1820938489":{"id":"n1820938489","loc":[-85.2546138,42.0050289]},"n1820938490":{"id":"n1820938490","loc":[-85.2717521,41.9977349]},"n1820938491":{"id":"n1820938491","loc":[-85.0100489,42.0908195]},"n1820938492":{"id":"n1820938492","loc":[-85.207879,42.0392211]},"n1820938493":{"id":"n1820938493","loc":[-85.0007363,42.0882836]},"n1820938494":{"id":"n1820938494","loc":[-85.5775303,41.9504097]},"n1820938495":{"id":"n1820938495","loc":[-85.1131584,42.0847683]},"n1820938496":{"id":"n1820938496","loc":[-85.0887825,42.0941633]},"n1820938497":{"id":"n1820938497","loc":[-85.1185926,42.0818938]},"n1820938498":{"id":"n1820938498","loc":[-85.2748487,41.9948712]},"n1820938499":{"id":"n1820938499","loc":[-85.2566952,42.0090788]},"n1820938500":{"id":"n1820938500","loc":[-85.0774757,42.1036234]},"n1820938501":{"id":"n1820938501","loc":[-85.4190869,42.008903]},"n1820938502":{"id":"n1820938502","loc":[-85.1140395,42.0850577]},"n1820938503":{"id":"n1820938503","loc":[-85.1136104,42.0848627]},"n1820938504":{"id":"n1820938504","loc":[-85.5828089,41.9480638]},"n1820938505":{"id":"n1820938505","loc":[-85.625514,41.9405202]},"n1820938506":{"id":"n1820938506","loc":[-85.2063384,42.0398322]},"n1820938507":{"id":"n1820938507","loc":[-85.3395476,41.9851636]},"n1820938508":{"id":"n1820938508","loc":[-85.0328853,42.0963606]},"n1820938510":{"id":"n1820938510","loc":[-85.1170369,42.0843702]},"n1820938511":{"id":"n1820938511","loc":[-85.2784748,41.9868487]},"n1820938512":{"id":"n1820938512","loc":[-85.6310501,41.9435528]},"n1820938514":{"id":"n1820938514","loc":[-85.0334284,42.0981028]},"n1820938515":{"id":"n1820938515","loc":[-84.9912091,42.0868226]},"n1820938516":{"id":"n1820938516","loc":[-85.2806141,41.9940351]},"n1820938517":{"id":"n1820938517","loc":[-85.1233025,42.0776734]},"n1820938518":{"id":"n1820938518","loc":[-85.2047891,42.0429023]},"n1820938519":{"id":"n1820938519","loc":[-85.1475443,42.0648312]},"n1820938520":{"id":"n1820938520","loc":[-85.2644685,41.9990891]},"n1820938521":{"id":"n1820938521","loc":[-85.1056281,42.0872553]},"n1820938522":{"id":"n1820938522","loc":[-85.4813184,41.9930105]},"n1820938523":{"id":"n1820938523","loc":[-85.321551,41.9722936]},"n1820938524":{"id":"n1820938524","loc":[-85.1564664,42.0631211]},"n1820938525":{"id":"n1820938525","loc":[-85.4149885,42.0079144]},"n1820938527":{"id":"n1820938527","loc":[-85.2861888,41.9803653]},"n1820938528":{"id":"n1820938528","loc":[-85.1301379,42.0682178]},"n1820938529":{"id":"n1820938529","loc":[-85.4156537,42.0084247]},"n1820938530":{"id":"n1820938530","loc":[-85.245151,42.0176082]},"n1820938531":{"id":"n1820938531","loc":[-85.457818,42.0001651]},"n1820938532":{"id":"n1820938532","loc":[-85.310951,41.9694538]},"n1820938533":{"id":"n1820938533","loc":[-85.1509089,42.0611298]},"n1820938534":{"id":"n1820938534","loc":[-85.1108249,42.086321]},"n1820938535":{"id":"n1820938535","loc":[-85.1260344,42.0740687]},"n1820938536":{"id":"n1820938536","loc":[-85.4561228,42.0042791]},"n1820938537":{"id":"n1820938537","loc":[-85.2805082,41.9945761]},"n1820938538":{"id":"n1820938538","loc":[-85.273352,41.9981921]},"n1820938539":{"id":"n1820938539","loc":[-85.1084216,42.0864364]},"n1820938540":{"id":"n1820938540","loc":[-85.5009737,41.9773637]},"n1820938541":{"id":"n1820938541","loc":[-85.3960843,42.0051879]},"n1820938542":{"id":"n1820938542","loc":[-85.3425088,41.9865034]},"n1820938545":{"id":"n1820938545","loc":[-84.9937907,42.0860849]},"n1820938546":{"id":"n1820938546","loc":[-85.1084176,42.086065]},"n1820938547":{"id":"n1820938547","loc":[-85.3492851,41.9924786]},"n1820938548":{"id":"n1820938548","loc":[-85.2512235,42.0101147]},"n1820938549":{"id":"n1820938549","loc":[-85.3717298,41.9979326]},"n1820938551":{"id":"n1820938551","loc":[-85.2573712,42.0064081]},"n1820938552":{"id":"n1820938552","loc":[-85.2514596,42.010139]},"n1820938553":{"id":"n1820938553","loc":[-85.416512,42.0088073]},"n1820938554":{"id":"n1820938554","loc":[-85.4365964,42.0061606]},"n1820938555":{"id":"n1820938555","loc":[-85.4552431,42.0057301]},"n1820938556":{"id":"n1820938556","loc":[-85.2916283,41.9778769]},"n1820938557":{"id":"n1820938557","loc":[-85.100709,42.0902968]},"n1820938558":{"id":"n1820938558","loc":[-85.4703064,41.9965771]},"n1820938559":{"id":"n1820938559","loc":[-85.3134722,41.9696134]},"n1820938560":{"id":"n1820938560","loc":[-85.4834213,41.9885768]},"n1820938561":{"id":"n1820938561","loc":[-85.2740641,41.9975236]},"n1820938562":{"id":"n1820938562","loc":[-85.148334,42.0623405]},"n1820938563":{"id":"n1820938563","loc":[-85.2358598,42.0263675]},"n1820938565":{"id":"n1820938565","loc":[-85.2902979,41.9790892]},"n1820938566":{"id":"n1820938566","loc":[-85.2528865,42.0112869]},"n1820938567":{"id":"n1820938567","loc":[-85.2595319,41.9973003]},"n1820938568":{"id":"n1820938568","loc":[-85.071151,42.105689]},"n1820938570":{"id":"n1820938570","loc":[-85.299278,41.9732188]},"n1820938571":{"id":"n1820938571","loc":[-85.0354669,42.1024771]},"n1820938583":{"id":"n1820938583","loc":[-85.3313937,41.972562]},"n1820938585":{"id":"n1820938585","loc":[-85.0756933,42.1058334]},"n1820938587":{"id":"n1820938587","loc":[-85.3130324,41.9694219]},"n1820938590":{"id":"n1820938590","loc":[-85.0934227,42.0931681]},"n1820938592":{"id":"n1820938592","loc":[-85.3517956,41.9922553]},"n1820938593":{"id":"n1820938593","loc":[-85.4023971,42.0065169]},"n1820938594":{"id":"n1820938594","loc":[-85.3506798,41.9925583]},"n1820938595":{"id":"n1820938595","loc":[-85.3673524,41.9971193]},"n1820938596":{"id":"n1820938596","loc":[-85.1073608,42.0853523]},"n1820938597":{"id":"n1820938597","loc":[-85.2976579,41.972477]},"n1820938598":{"id":"n1820938598","loc":[-85.5616517,41.9694295]},"n1820938599":{"id":"n1820938599","loc":[-85.3552074,41.9921915]},"n1820938600":{"id":"n1820938600","loc":[-85.4665126,41.9999953]},"n1820938601":{"id":"n1820938601","loc":[-85.2740695,41.9966226]},"n1820938602":{"id":"n1820938602","loc":[-85.279376,41.9886669]},"n1820938603":{"id":"n1820938603","loc":[-85.0771109,42.1040413]},"n1820938604":{"id":"n1820938604","loc":[-85.2636049,41.9977895]},"n1820938605":{"id":"n1820938605","loc":[-85.3762145,41.9976456]},"n1820938606":{"id":"n1820938606","loc":[-85.2321369,42.0289577]},"n1820938620":{"id":"n1820938620","loc":[-85.4947724,41.9776189]},"n1820938622":{"id":"n1820938622","loc":[-85.1547069,42.0622768]},"n1820938624":{"id":"n1820938624","loc":[-85.0005056,42.0880249]},"n1820938626":{"id":"n1820938626","loc":[-85.0735596,42.1059357]},"n1820938628":{"id":"n1820938628","loc":[-85.4665298,41.99932]},"n1820938629":{"id":"n1820938629","loc":[-85.434515,42.0065273]},"n1820938630":{"id":"n1820938630","loc":[-85.117462,42.0823823]},"n1820938631":{"id":"n1820938631","loc":[-85.0131777,42.0890707]},"n1820938632":{"id":"n1820938632","loc":[-85.0875326,42.0961934]},"n1820938634":{"id":"n1820938634","loc":[-85.6433839,41.9112042]},"n1820938635":{"id":"n1820938635","loc":[-85.1366181,42.064969]},"n1820938636":{"id":"n1820938636","loc":[-85.073109,42.1057925]},"n1820938638":{"id":"n1820938638","loc":[-85.161406,42.0632541]},"n1820938640":{"id":"n1820938640","loc":[-85.6343932,41.9188845]},"n1820938642":{"id":"n1820938642","loc":[-85.2500004,42.010306]},"n1820938644":{"id":"n1820938644","loc":[-85.291918,41.9753166]},"n1820938663":{"id":"n1820938663","loc":[-85.2841611,41.9916812]},"n1820938664":{"id":"n1820938664","loc":[-85.1052955,42.0868134]},"n1820938665":{"id":"n1820938665","loc":[-85.4606118,42.0005534]},"n1820938666":{"id":"n1820938666","loc":[-85.5672736,41.9642922]},"n1820938667":{"id":"n1820938667","loc":[-85.6348481,41.9316932]},"n1820938668":{"id":"n1820938668","loc":[-85.0224904,42.0909576]},"n1820938669":{"id":"n1820938669","loc":[-85.0133856,42.0899755]},"n1820938670":{"id":"n1820938670","loc":[-85.344779,41.991139]},"n1820938671":{"id":"n1820938671","loc":[-85.632874,41.9425313]},"n1820938673":{"id":"n1820938673","loc":[-85.4941501,41.9779698]},"n1820938675":{"id":"n1820938675","loc":[-85.0862559,42.0997519]},"n1820938676":{"id":"n1820938676","loc":[-85.0097874,42.0898032]},"n1820938678":{"id":"n1820938678","loc":[-84.9913553,42.0863675]},"n1820938680":{"id":"n1820938680","loc":[-85.0533666,42.1038315]},"n1820938682":{"id":"n1820938682","loc":[-85.2950294,41.9743914]},"n1820938684":{"id":"n1820938684","loc":[-85.2517385,42.0104499]},"n1820938686":{"id":"n1820938686","loc":[-85.0247971,42.0922514]},"n1820938688":{"id":"n1820938688","loc":[-85.0807037,42.1026017]},"n1820938690":{"id":"n1820938690","loc":[-85.52462,41.9722748]},"n1820938694":{"id":"n1820938694","loc":[-85.2586535,41.9988818]},"n1820938695":{"id":"n1820938695","loc":[-85.0931612,42.092948]},"n1820938697":{"id":"n1820938697","loc":[-85.2470822,42.016564]},"n1820938698":{"id":"n1820938698","loc":[-85.4143018,42.0075158]},"n1820938699":{"id":"n1820938699","loc":[-85.0771484,42.104487]},"n1820938700":{"id":"n1820938700","loc":[-85.0291208,42.0942775]},"n1820938701":{"id":"n1820938701","loc":[-85.6367964,41.9185971]},"n1820938702":{"id":"n1820938702","loc":[-85.085419,42.1010693]},"n1820938703":{"id":"n1820938703","loc":[-85.0583877,42.1040584]},"n1820938705":{"id":"n1820938705","loc":[-85.2573379,42.0003182]},"n1820938706":{"id":"n1820938706","loc":[-85.2655937,41.9981575]},"n1820938707":{"id":"n1820938707","loc":[-85.023181,42.0915758]},"n1820938708":{"id":"n1820938708","loc":[-85.2318687,42.0274674]},"n1820938709":{"id":"n1820938709","loc":[-85.1056389,42.0866184]},"n1820938710":{"id":"n1820938710","loc":[-85.5276265,41.9700978]},"n1820938711":{"id":"n1820938711","loc":[-85.0864128,42.0945761]},"n1820938712":{"id":"n1820938712","loc":[-84.9897071,42.0871888]},"n1820938714":{"id":"n1820938714","loc":[-85.1328845,42.0665611]},"n1820938715":{"id":"n1820938715","loc":[-85.0336537,42.0991377]},"n1820938716":{"id":"n1820938716","loc":[-85.087597,42.0986692]},"n1820938717":{"id":"n1820938717","loc":[-85.1241394,42.0761882]},"n1820938718":{"id":"n1820938718","loc":[-85.1176002,42.0847723]},"n1820938719":{"id":"n1820938719","loc":[-85.2423615,42.0216572]},"n1820938721":{"id":"n1820938721","loc":[-85.2196378,42.0387908]},"n1820938722":{"id":"n1820938722","loc":[-85.0164272,42.0890082]},"n1820938723":{"id":"n1820938723","loc":[-85.5917182,41.9451807]},"n1820938724":{"id":"n1820938724","loc":[-85.2458806,42.0086638]},"n1820938725":{"id":"n1820938725","loc":[-85.1264474,42.0740527]},"n1820938726":{"id":"n1820938726","loc":[-85.1961631,42.04738]},"n1820938727":{"id":"n1820938727","loc":[-85.2784643,41.9943648]},"n1820938728":{"id":"n1820938728","loc":[-85.2905554,41.9763216]},"n1820938729":{"id":"n1820938729","loc":[-85.2913386,41.9771511]},"n1820938730":{"id":"n1820938730","loc":[-85.0112519,42.0895683]},"n1820938732":{"id":"n1820938732","loc":[-85.4290261,42.0064531]},"n1820938733":{"id":"n1820938733","loc":[-85.3867073,42.0031629]},"n1820938734":{"id":"n1820938734","loc":[-85.4943647,41.9836005]},"n1820938735":{"id":"n1820938735","loc":[-85.4900303,41.9860728]},"n1820938736":{"id":"n1820938736","loc":[-85.0866153,42.0944539]},"n1820938737":{"id":"n1820938737","loc":[-85.0869532,42.0990911]},"n1820938738":{"id":"n1820938738","loc":[-85.6321659,41.9208851]},"n1820938739":{"id":"n1820938739","loc":[-85.5930485,41.9433453]},"n1820938740":{"id":"n1820938740","loc":[-85.0406851,42.102733]},"n1820938741":{"id":"n1820938741","loc":[-85.1051131,42.0869846]},"n1820938742":{"id":"n1820938742","loc":[-85.1377554,42.0648893]},"n1820938743":{"id":"n1820938743","loc":[-85.2795694,41.994604]},"n1820938745":{"id":"n1820938745","loc":[-85.4948153,41.9826594]},"n1820938746":{"id":"n1820938746","loc":[-85.4488916,42.0050923]},"n1820938747":{"id":"n1820938747","loc":[-85.1052526,42.0866144]},"n1820938748":{"id":"n1820938748","loc":[-85.1468749,42.0653991]},"n1820938749":{"id":"n1820938749","loc":[-85.0856886,42.1006104]},"n1820938750":{"id":"n1820938750","loc":[-85.2144022,42.0404004]},"n1820938751":{"id":"n1820938751","loc":[-85.277771,41.9907458]},"n1820938752":{"id":"n1820938752","loc":[-85.1474542,42.0636149]},"n1820938753":{"id":"n1820938753","loc":[-85.0820515,42.1028075]},"n1820938754":{"id":"n1820938754","loc":[-85.1122948,42.08525]},"n1820938756":{"id":"n1820938756","loc":[-85.0173352,42.0901933]},"n1820938757":{"id":"n1820938757","loc":[-85.2259721,42.0354018]},"n1820938758":{"id":"n1820938758","loc":[-85.0872389,42.0987795]},"n1820938759":{"id":"n1820938759","loc":[-85.2291436,42.031874]},"n1820938760":{"id":"n1820938760","loc":[-85.3802485,42.0016002]},"n1820938761":{"id":"n1820938761","loc":[-85.3945822,42.0057938]},"n1820938762":{"id":"n1820938762","loc":[-85.5273237,41.9713017]},"n1820938763":{"id":"n1820938763","loc":[-85.2868862,41.9798629]},"n1820938764":{"id":"n1820938764","loc":[-85.2516677,42.0107899]},"n1820938766":{"id":"n1820938766","loc":[-85.3183002,41.9693103]},"n1820938768":{"id":"n1820938768","loc":[-85.2159042,42.0401932]},"n1820938770":{"id":"n1820938770","loc":[-85.0094481,42.0911141]},"n1820938771":{"id":"n1820938771","loc":[-85.0244538,42.0922155]},"n1820938772":{"id":"n1820938772","loc":[-85.231697,42.028862]},"n1820938773":{"id":"n1820938773","loc":[-85.2102394,42.0390617]},"n1820938774":{"id":"n1820938774","loc":[-85.2463419,42.0151212]},"n1820938775":{"id":"n1820938775","loc":[-85.0726195,42.1056424]},"n1820938776":{"id":"n1820938776","loc":[-85.0060431,42.0883262]},"n1820938778":{"id":"n1820938778","loc":[-85.425889,42.0056982]},"n1820938779":{"id":"n1820938779","loc":[-85.1183042,42.0820638]},"n1820938780":{"id":"n1820938780","loc":[-85.441596,42.0058257]},"n1820938781":{"id":"n1820938781","loc":[-85.1124879,42.0847086]},"n1820938782":{"id":"n1820938782","loc":[-85.2452733,42.0153894]},"n1820938783":{"id":"n1820938783","loc":[-85.2741191,41.9969244]},"n1820938784":{"id":"n1820938784","loc":[-85.2829487,41.9822236]},"n1820938785":{"id":"n1820938785","loc":[-85.3202743,41.972142]},"n1820938786":{"id":"n1820938786","loc":[-85.2345402,42.0266465]},"n1820938787":{"id":"n1820938787","loc":[-85.3037626,41.9724611]},"n1820938789":{"id":"n1820938789","loc":[-85.2474792,42.0161973]},"n1820938790":{"id":"n1820938790","loc":[-85.2951045,41.9727323]},"n1820938791":{"id":"n1820938791","loc":[-85.322345,41.9712726]},"n1820938792":{"id":"n1820938792","loc":[-85.2402372,42.0110394]},"n1820938793":{"id":"n1820938793","loc":[-85.5135693,41.9698659]},"n1820938794":{"id":"n1820938794","loc":[-85.4695339,41.9967366]},"n1820938796":{"id":"n1820938796","loc":[-85.0418492,42.1011131]},"n1820938797":{"id":"n1820938797","loc":[-85.3334107,41.9806337]},"n1820938798":{"id":"n1820938798","loc":[-85.5625314,41.9711685]},"n1820938799":{"id":"n1820938799","loc":[-85.3755707,41.9973585]},"n1820938800":{"id":"n1820938800","loc":[-85.5227532,41.9722429]},"n1820938801":{"id":"n1820938801","loc":[-85.4267687,42.0052836]},"n1820938803":{"id":"n1820938803","loc":[-85.0284704,42.0940837]},"n1820938804":{"id":"n1820938804","loc":[-85.015585,42.0885305]},"n1820938805":{"id":"n1820938805","loc":[-85.0765905,42.1053865]},"n1820938806":{"id":"n1820938806","loc":[-85.2614953,41.9964551]},"n1820938808":{"id":"n1820938808","loc":[-85.0307355,42.0947313]},"n1820938810":{"id":"n1820938810","loc":[-85.3894753,42.0003565]},"n1820938812":{"id":"n1820938812","loc":[-85.0868848,42.095006]},"n1820938813":{"id":"n1820938813","loc":[-85.3854198,42.0009465]},"n1820938814":{"id":"n1820938814","loc":[-85.2659692,41.9993534]},"n1820938815":{"id":"n1820938815","loc":[-85.1234259,42.0765266]},"n1820938816":{"id":"n1820938816","loc":[-85.1426906,42.0648893]},"n1820938818":{"id":"n1820938818","loc":[-85.1014533,42.0893067]},"n1820938819":{"id":"n1820938819","loc":[-85.0883064,42.098067]},"n1820938820":{"id":"n1820938820","loc":[-85.0503156,42.102704]},"n1820938821":{"id":"n1820938821","loc":[-85.1179649,42.0821884]},"n1820938822":{"id":"n1820938822","loc":[-85.3484697,41.9921596]},"n1820938823":{"id":"n1820938823","loc":[-85.3732962,41.9970874]},"n1820938824":{"id":"n1820938824","loc":[-85.2784104,41.9898312]},"n1820938825":{"id":"n1820938825","loc":[-85.4441709,42.0052198]},"n1820938826":{"id":"n1820938826","loc":[-85.3925438,42.0038326]},"n1820938829":{"id":"n1820938829","loc":[-85.5717582,41.9621861]},"n1820938830":{"id":"n1820938830","loc":[-85.0866314,42.0995051]},"n1820938831":{"id":"n1820938831","loc":[-85.576672,41.9522769]},"n1820938832":{"id":"n1820938832","loc":[-85.1587238,42.0636205]},"n1820938833":{"id":"n1820938833","loc":[-85.3804245,41.9999155]},"n1820938834":{"id":"n1820938834","loc":[-85.280083,41.9948843]},"n1820938836":{"id":"n1820938836","loc":[-85.561892,41.9686693]},"n1820938837":{"id":"n1820938837","loc":[-85.0158975,42.0885253]},"n1820938838":{"id":"n1820938838","loc":[-85.4248204,42.007633]},"n1820938839":{"id":"n1820938839","loc":[-85.0352738,42.1039657]},"n1820938840":{"id":"n1820938840","loc":[-85.211956,42.0411812]},"n1820938841":{"id":"n1820938841","loc":[-85.4816575,41.9908997]},"n1820938842":{"id":"n1820938842","loc":[-85.3807635,42.0020308]},"n1820938843":{"id":"n1820938843","loc":[-85.0100865,42.0898521]},"n1820938844":{"id":"n1820938844","loc":[-85.0103936,42.0897434]},"n1820938848":{"id":"n1820938848","loc":[-85.2430052,42.0131363]},"n1820938849":{"id":"n1820938849","loc":[-85.112559,42.0853723]},"n1820938851":{"id":"n1820938851","loc":[-85.3641553,41.9952535]},"n1820938852":{"id":"n1820938852","loc":[-85.2087373,42.0390777]},"n1820938853":{"id":"n1820938853","loc":[-85.2473933,42.0148263]},"n1820938854":{"id":"n1820938854","loc":[-85.0213464,42.090509]},"n1820938855":{"id":"n1820938855","loc":[-85.0673208,42.1052353]},"n1820938856":{"id":"n1820938856","loc":[-85.1003053,42.0905528]},"n1820938857":{"id":"n1820938857","loc":[-85.2617367,41.9965389]},"n1820938858":{"id":"n1820938858","loc":[-85.280363,41.9916015]},"n1820938859":{"id":"n1820938859","loc":[-85.0038866,42.0873469]},"n1820938860":{"id":"n1820938860","loc":[-85.2476401,42.0151451]},"n1820938861":{"id":"n1820938861","loc":[-85.193717,42.0499294]},"n1820938862":{"id":"n1820938862","loc":[-85.3478689,41.9917609]},"n1820938863":{"id":"n1820938863","loc":[-85.5638017,41.9648881]},"n1820938864":{"id":"n1820938864","loc":[-85.4356308,42.0064476]},"n1820938865":{"id":"n1820938865","loc":[-85.0561722,42.1023509]},"n1820938867":{"id":"n1820938867","loc":[-85.2256031,42.0356034]},"n1820938868":{"id":"n1820938868","loc":[-85.6102576,41.9420844]},"n1820938869":{"id":"n1820938869","loc":[-85.2285213,42.0339938]},"n1820938870":{"id":"n1820938870","loc":[-85.0326238,42.0978003]},"n1820938871":{"id":"n1820938871","loc":[-85.0131389,42.0903736]},"n1820938872":{"id":"n1820938872","loc":[-85.2550859,42.0012259]},"n1820938873":{"id":"n1820938873","loc":[-85.1130029,42.0846966]},"n1820938874":{"id":"n1820938874","loc":[-85.1579041,42.06336]},"n1820938875":{"id":"n1820938875","loc":[-85.0430522,42.1020234]},"n1820938876":{"id":"n1820938876","loc":[-85.2786679,41.9865935]},"n1820938877":{"id":"n1820938877","loc":[-85.1221666,42.0788706]},"n1820938878":{"id":"n1820938878","loc":[-85.2554614,42.0103303]},"n1820938879":{"id":"n1820938879","loc":[-85.2349801,42.0265748]},"n1820938880":{"id":"n1820938880","loc":[-85.0997434,42.0907864]},"n1820938881":{"id":"n1820938881","loc":[-85.0045464,42.0878167]},"n1820938882":{"id":"n1820938882","loc":[-85.2728048,41.9982519]},"n1820938883":{"id":"n1820938883","loc":[-85.3111333,41.9691587]},"n1820938884":{"id":"n1820938884","loc":[-85.3219802,41.9721899]},"n1820938885":{"id":"n1820938885","loc":[-85.3091378,41.9699325]},"n1820938887":{"id":"n1820938887","loc":[-85.4242367,42.0085203]},"n1820938888":{"id":"n1820938888","loc":[-84.9968377,42.0874504]},"n1820938890":{"id":"n1820938890","loc":[-85.5443139,41.9714078]},"n1820938891":{"id":"n1820938891","loc":[-85.6404013,41.9154676]},"n1820938892":{"id":"n1820938892","loc":[-85.3644986,41.9962582]},"n1820938893":{"id":"n1820938893","loc":[-85.0496772,42.1018323]},"n1820938894":{"id":"n1820938894","loc":[-85.297261,41.9737373]},"n1820938895":{"id":"n1820938895","loc":[-85.0327096,42.098071]},"n1820938896":{"id":"n1820938896","loc":[-85.3856773,41.9996867]},"n1820938897":{"id":"n1820938897","loc":[-85.0493862,42.1015509]},"n1820938898":{"id":"n1820938898","loc":[-84.9969879,42.0876614]},"n1820938899":{"id":"n1820938899","loc":[-85.0848625,42.1013587]},"n1820938900":{"id":"n1820938900","loc":[-85.5853195,41.9479201]},"n1820938901":{"id":"n1820938901","loc":[-85.6329169,41.9387964]},"n1820938902":{"id":"n1820938902","loc":[-85.0843046,42.1029468]},"n1820938903":{"id":"n1820938903","loc":[-85.1228747,42.0778474]},"n1820938904":{"id":"n1820938904","loc":[-85.4855456,41.984095]},"n1820938905":{"id":"n1820938905","loc":[-85.0573269,42.1026801]},"n1820938906":{"id":"n1820938906","loc":[-85.2425868,42.0131523]},"n1820938907":{"id":"n1820938907","loc":[-85.1149622,42.0860053]},"n1820938908":{"id":"n1820938908","loc":[-85.4833097,41.9951578]},"n1820938909":{"id":"n1820938909","loc":[-85.075979,42.1056372]},"n1820938910":{"id":"n1820938910","loc":[-85.0338509,42.0977139]},"n1820938911":{"id":"n1820938911","loc":[-85.6384272,41.9115715]},"n1820938912":{"id":"n1820938912","loc":[-85.0458363,42.1004074]},"n1820938913":{"id":"n1820938913","loc":[-85.0592138,42.1048305]},"n1820938914":{"id":"n1820938914","loc":[-85.2807493,41.9916653]},"n1820938915":{"id":"n1820938915","loc":[-85.1103274,42.0864193]},"n1820938916":{"id":"n1820938916","loc":[-85.6267156,41.9404404]},"n1820938918":{"id":"n1820938918","loc":[-85.0331374,42.0982911]},"n1820938919":{"id":"n1820938919","loc":[-85.5637331,41.965409]},"n1820938920":{"id":"n1820938920","loc":[-85.5457515,41.9714237]},"n1820938922":{"id":"n1820938922","loc":[-85.082073,42.1030104]},"n1820938923":{"id":"n1820938923","loc":[-85.0780765,42.103102]},"n1820938924":{"id":"n1820938924","loc":[-85.4208035,42.0089508]},"n1820938925":{"id":"n1820938925","loc":[-85.3469934,41.9914795]},"n1820938926":{"id":"n1820938926","loc":[-85.0322,42.095619]},"n1820938927":{"id":"n1820938927","loc":[-85.4784431,41.9949401]},"n1820938928":{"id":"n1820938928","loc":[-85.1303095,42.0667523]},"n1820938929":{"id":"n1820938929","loc":[-85.2463784,42.0084781]},"n1820938930":{"id":"n1820938930","loc":[-85.6299986,41.9427707]},"n1820938931":{"id":"n1820938931","loc":[-85.6325907,41.9238499]},"n1820938932":{"id":"n1820938932","loc":[-85.4808464,41.9914476]},"n1820938934":{"id":"n1820938934","loc":[-85.2411599,42.0105292]},"n1820938935":{"id":"n1820938935","loc":[-85.0163213,42.0892379]},"n1820938936":{"id":"n1820938936","loc":[-85.3290934,41.9682322]},"n1820938937":{"id":"n1820938937","loc":[-85.4925623,41.9853231]},"n1820938938":{"id":"n1820938938","loc":[-85.0338294,42.09892]},"n1820938940":{"id":"n1820938940","loc":[-85.4174561,42.008903]},"n1820938941":{"id":"n1820938941","loc":[-85.1165595,42.0838845]},"n1820938942":{"id":"n1820938942","loc":[-85.2954585,41.9717192]},"n1820938943":{"id":"n1820938943","loc":[-85.6330199,41.9257338]},"n1820938944":{"id":"n1820938944","loc":[-85.2294654,42.0324478]},"n1820938945":{"id":"n1820938945","loc":[-85.5601282,41.9728914]},"n1820938946":{"id":"n1820938946","loc":[-85.1176324,42.08568]},"n1820938947":{"id":"n1820938947","loc":[-85.0210245,42.0906005]},"n1820938948":{"id":"n1820938948","loc":[-85.0251887,42.09253]},"n1820938949":{"id":"n1820938949","loc":[-85.0895832,42.0939551]},"n1820938950":{"id":"n1820938950","loc":[-84.9915109,42.085842]},"n1820938951":{"id":"n1820938951","loc":[-85.2187366,42.0393486]},"n1820938952":{"id":"n1820938952","loc":[-85.006605,42.087579]},"n1820938953":{"id":"n1820938953","loc":[-85.046641,42.1012393]},"n1820938954":{"id":"n1820938954","loc":[-85.052102,42.103695]},"n1820938955":{"id":"n1820938955","loc":[-85.283925,41.9912825]},"n1820938956":{"id":"n1820938956","loc":[-85.2326626,42.0316349]},"n1820938957":{"id":"n1820938957","loc":[-85.1174298,42.0859694]},"n1820938958":{"id":"n1820938958","loc":[-85.3802056,41.9994794]},"n1820938959":{"id":"n1820938959","loc":[-85.4586334,41.9999737]},"n1820938960":{"id":"n1820938960","loc":[-85.4302234,42.0069418]},"n1820938961":{"id":"n1820938961","loc":[-85.092201,42.0930674]},"n1820938962":{"id":"n1820938962","loc":[-85.3684511,41.9979382]},"n1820938963":{"id":"n1820938963","loc":[-85.4618735,42.0011856]},"n1820938964":{"id":"n1820938964","loc":[-85.4828205,41.9877793]},"n1820938965":{"id":"n1820938965","loc":[-85.0837789,42.1025726]},"n1820938966":{"id":"n1820938966","loc":[-85.0176195,42.090253]},"n1820938967":{"id":"n1820938967","loc":[-85.3801627,42.001074]},"n1820938968":{"id":"n1820938968","loc":[-85.4767007,41.994488]},"n1820938969":{"id":"n1820938969","loc":[-85.274268,41.9957495]},"n1820938970":{"id":"n1820938970","loc":[-85.2977438,41.9719506]},"n1820938971":{"id":"n1820938971","loc":[-85.2425546,42.0208682]},"n1820938972":{"id":"n1820938972","loc":[-85.2557082,42.002382]},"n1820938973":{"id":"n1820938973","loc":[-85.3187937,41.9691986]},"n1820938975":{"id":"n1820938975","loc":[-85.2448077,42.0153045]},"n1820938977":{"id":"n1820938977","loc":[-85.0343015,42.0997718]},"n1820938978":{"id":"n1820938978","loc":[-85.2449364,42.01874]},"n1820938979":{"id":"n1820938979","loc":[-85.2598391,41.9969602]},"n1820938980":{"id":"n1820938980","loc":[-85.4294724,42.0067665]},"n1820938981":{"id":"n1820938981","loc":[-85.428082,42.0055124]},"n1820938983":{"id":"n1820938983","loc":[-85.5436315,41.9717484]},"n1820938985":{"id":"n1820938985","loc":[-85.5978336,41.9407437]},"n1820938986":{"id":"n1820938986","loc":[-85.491661,41.9860249]},"n1820938987":{"id":"n1820938987","loc":[-85.4942789,41.9801392]},"n1820938988":{"id":"n1820938988","loc":[-85.0416306,42.1010841]},"n1820938989":{"id":"n1820938989","loc":[-85.2653644,41.9984433]},"n1820938990":{"id":"n1820938990","loc":[-85.1028266,42.0881124]},"n1820938991":{"id":"n1820938991","loc":[-85.0163146,42.0887932]},"n1820938992":{"id":"n1820938992","loc":[-85.5282209,41.9678112]},"n1820938993":{"id":"n1820938993","loc":[-85.5442752,41.9715888]},"n1820938994":{"id":"n1820938994","loc":[-85.5634327,41.9658558]},"n1820938995":{"id":"n1820938995","loc":[-85.0384227,42.1037627]},"n1820938996":{"id":"n1820938996","loc":[-85.1144258,42.0854439]},"n1820938997":{"id":"n1820938997","loc":[-85.1870651,42.0506305]},"n1820938998":{"id":"n1820938998","loc":[-85.1256159,42.0747376]},"n1820938999":{"id":"n1820938999","loc":[-85.3272695,41.9715836]},"n1820939000":{"id":"n1820939000","loc":[-85.0543067,42.103098]},"n1820939001":{"id":"n1820939001","loc":[-85.4678173,41.9973585]},"n1820939003":{"id":"n1820939003","loc":[-85.0266626,42.0933154]},"n1820939004":{"id":"n1820939004","loc":[-85.0353046,42.1019728]},"n1820939005":{"id":"n1820939005","loc":[-85.1237961,42.0762798]},"n1820939006":{"id":"n1820939006","loc":[-85.2812214,41.9826702]},"n1820939007":{"id":"n1820939007","loc":[-85.2927763,41.9747343]},"n1820939008":{"id":"n1820939008","loc":[-85.3270979,41.9720862]},"n1820939009":{"id":"n1820939009","loc":[-85.488657,41.9856581]},"n1820939010":{"id":"n1820939010","loc":[-85.3087301,41.9701399]},"n1820939011":{"id":"n1820939011","loc":[-85.0276939,42.093768]},"n1820939012":{"id":"n1820939012","loc":[-85.2956516,41.9748779]},"n1820939013":{"id":"n1820939013","loc":[-85.1298579,42.0726443]},"n1820939014":{"id":"n1820939014","loc":[-85.105144,42.0870893]},"n1820939015":{"id":"n1820939015","loc":[-85.0677486,42.1053917]},"n1820939016":{"id":"n1820939016","loc":[-85.0333681,42.0993459]},"n1820939017":{"id":"n1820939017","loc":[-85.6384272,41.910805]},"n1820939018":{"id":"n1820939018","loc":[-85.399496,42.006894]},"n1820939019":{"id":"n1820939019","loc":[-85.2648427,41.9998318]},"n1820939020":{"id":"n1820939020","loc":[-85.1237424,42.0766779]},"n1820939021":{"id":"n1820939021","loc":[-85.2515025,42.0109442]},"n1820939022":{"id":"n1820939022","loc":[-85.5566306,41.9718385]},"n1820939023":{"id":"n1820939023","loc":[-85.090644,42.0938369]},"n1820939024":{"id":"n1820939024","loc":[-85.1245525,42.074914]},"n1820939025":{"id":"n1820939025","loc":[-85.1099934,42.0863926]},"n1820939026":{"id":"n1820939026","loc":[-85.1251653,42.0744589]},"n1820939027":{"id":"n1820939027","loc":[-85.401792,42.0068143]},"n1820939028":{"id":"n1820939028","loc":[-85.0094763,42.0899584]},"n1820939029":{"id":"n1820939029","loc":[-85.1330779,42.0705605]},"n1820939030":{"id":"n1820939030","loc":[-85.4935064,41.984398]},"n1820939031":{"id":"n1820939031","loc":[-85.5713334,41.9613939]},"n1820939032":{"id":"n1820939032","loc":[-85.0873945,42.0964669]},"n1820939033":{"id":"n1820939033","loc":[-85.0886497,42.0986481]},"n1820939034":{"id":"n1820939034","loc":[-85.3276343,41.9758897]},"n1820939035":{"id":"n1820939035","loc":[-85.1304386,42.0727387]},"n1820939036":{"id":"n1820939036","loc":[-85.2551932,42.0052999]},"n1820939037":{"id":"n1820939037","loc":[-85.2206936,42.0384458]},"n1820939038":{"id":"n1820939038","loc":[-85.2313645,42.0286389]},"n1820939039":{"id":"n1820939039","loc":[-85.0754586,42.1059835]},"n1820939040":{"id":"n1820939040","loc":[-85.0663324,42.1050812]},"n1820939041":{"id":"n1820939041","loc":[-85.2406234,42.0106887]},"n1820939042":{"id":"n1820939042","loc":[-85.0685962,42.1058175]},"n1820939043":{"id":"n1820939043","loc":[-85.0689462,42.1059437]},"n1820939044":{"id":"n1820939044","loc":[-85.0586144,42.1046144]},"n1820939045":{"id":"n1820939045","loc":[-85.3650565,41.9965452]},"n1820939047":{"id":"n1820939047","loc":[-85.5752558,41.9536014]},"n1820939048":{"id":"n1820939048","loc":[-85.5110159,41.9710624]},"n1820939050":{"id":"n1820939050","loc":[-85.2832641,41.9926477]},"n1820939051":{"id":"n1820939051","loc":[-85.0078402,42.0898947]},"n1820939052":{"id":"n1820939052","loc":[-85.3882737,42.0017916]},"n1820939053":{"id":"n1820939053","loc":[-85.1718945,42.0564937]},"n1820939054":{"id":"n1820939054","loc":[-85.0947048,42.0929293]},"n1820939055":{"id":"n1820939055","loc":[-85.4456944,42.0051082]},"n1820939056":{"id":"n1820939056","loc":[-85.3139872,41.9706903]},"n1820939057":{"id":"n1820939057","loc":[-85.3893895,42.0034021]},"n1820939058":{"id":"n1820939058","loc":[-85.2425332,42.0106089]},"n1820939059":{"id":"n1820939059","loc":[-85.6085624,41.9420844]},"n1820939060":{"id":"n1820939060","loc":[-85.210411,42.0397789]},"n1820939061":{"id":"n1820939061","loc":[-85.2762542,41.9960473]},"n1820939062":{"id":"n1820939062","loc":[-85.4686584,41.9969973]},"n1820939063":{"id":"n1820939063","loc":[-85.3860421,42.0018394]},"n1820939064":{"id":"n1820939064","loc":[-85.5636944,41.9644414]},"n1820939065":{"id":"n1820939065","loc":[-85.3267331,41.9766554]},"n1820939066":{"id":"n1820939066","loc":[-85.0868996,42.0943822]},"n1820939067":{"id":"n1820939067","loc":[-85.104861,42.0880038]},"n1820939068":{"id":"n1820939068","loc":[-85.5537123,41.9695093]},"n1820939069":{"id":"n1820939069","loc":[-85.6325092,41.9396743]},"n1820939070":{"id":"n1820939070","loc":[-85.3869648,42.0024454]},"n1820939071":{"id":"n1820939071","loc":[-85.2775349,41.9957335]},"n1820939072":{"id":"n1820939072","loc":[-85.2055616,42.0421533]},"n1820939073":{"id":"n1820939073","loc":[-85.4731431,41.9946531]},"n1820939074":{"id":"n1820939074","loc":[-85.0399609,42.1030833]},"n1820939075":{"id":"n1820939075","loc":[-85.3055758,41.9725169]},"n1820939076":{"id":"n1820939076","loc":[-85.4834599,41.994488]},"n1820939077":{"id":"n1820939077","loc":[-85.3819866,42.0023018]},"n1820939078":{"id":"n1820939078","loc":[-85.1218756,42.0789992]},"n1820939079":{"id":"n1820939079","loc":[-85.2793159,41.9944458]},"n1820939080":{"id":"n1820939080","loc":[-85.2495498,42.0101466]},"n1820939081":{"id":"n1820939081","loc":[-85.0035969,42.0872434]},"n1820939082":{"id":"n1820939082","loc":[-85.1054243,42.0865626]},"n1820939083":{"id":"n1820939083","loc":[-85.0917665,42.0934774]},"n1820939084":{"id":"n1820939084","loc":[-85.3442211,41.988938]},"n1820939086":{"id":"n1820939086","loc":[-85.273989,41.9953588]},"n1820939087":{"id":"n1820939087","loc":[-85.1142541,42.0852488]},"n1820939089":{"id":"n1820939089","loc":[-85.1526684,42.0615758]},"n1820939090":{"id":"n1820939090","loc":[-85.2538843,42.0110159]},"n1820939091":{"id":"n1820939091","loc":[-85.28341,41.9909635]},"n1820939092":{"id":"n1820939092","loc":[-85.3963178,42.0050217]},"n1820939093":{"id":"n1820939093","loc":[-85.0851682,42.1012472]},"n1820939095":{"id":"n1820939095","loc":[-85.2811784,41.986243]},"n1820939096":{"id":"n1820939096","loc":[-85.4274125,42.0052995]},"n1820939097":{"id":"n1820939097","loc":[-85.0871262,42.0951652]},"n1820939099":{"id":"n1820939099","loc":[-85.1314253,42.0671665]},"n1820939100":{"id":"n1820939100","loc":[-85.2778997,41.991001]},"n1820939101":{"id":"n1820939101","loc":[-85.112107,42.0862812]},"n1820939102":{"id":"n1820939102","loc":[-85.299911,41.9729955]},"n1820939103":{"id":"n1820939103","loc":[-85.639822,41.9094796]},"n1820939104":{"id":"n1820939104","loc":[-85.122294,42.0785334]},"n1820939105":{"id":"n1820939105","loc":[-85.2476294,42.015719]},"n1820939106":{"id":"n1820939106","loc":[-85.4946007,41.9814631]},"n1820939107":{"id":"n1820939107","loc":[-85.0879524,42.0986919]},"n1820939108":{"id":"n1820939108","loc":[-85.0342814,42.098274]},"n1820939109":{"id":"n1820939109","loc":[-85.2450695,42.0095463]},"n1820939110":{"id":"n1820939110","loc":[-85.3847546,42.0024135]},"n1820939111":{"id":"n1820939111","loc":[-85.2961344,41.9742558]},"n1820939112":{"id":"n1820939112","loc":[-85.27899,41.994317]},"n1820939114":{"id":"n1820939114","loc":[-85.1017644,42.0886618]},"n1820939115":{"id":"n1820939115","loc":[-85.076215,42.1056333]},"n1820939116":{"id":"n1820939116","loc":[-85.1198009,42.0805349]},"n1820939117":{"id":"n1820939117","loc":[-85.11988,42.0798513]},"n1820939118":{"id":"n1820939118","loc":[-85.147819,42.0625476]},"n1820939119":{"id":"n1820939119","loc":[-85.0585969,42.1029042]},"n1820939120":{"id":"n1820939120","loc":[-85.1248596,42.0745744]},"n1820939121":{"id":"n1820939121","loc":[-85.3023786,41.9725249]},"n1820939123":{"id":"n1820939123","loc":[-85.0119332,42.0900699]},"n1820939124":{"id":"n1820939124","loc":[-85.2466852,42.0170343]},"n1820939125":{"id":"n1820939125","loc":[-85.0033019,42.0872792]},"n1820939126":{"id":"n1820939126","loc":[-85.0042084,42.0875778]},"n1820939128":{"id":"n1820939128","loc":[-85.0052961,42.0885424]},"n1820939130":{"id":"n1820939130","loc":[-85.0647942,42.10508]},"n1820939131":{"id":"n1820939131","loc":[-85.2824123,41.9825107]},"n1820939132":{"id":"n1820939132","loc":[-85.3210039,41.9723255]},"n1820939133":{"id":"n1820939133","loc":[-85.0491033,42.1014184]},"n1820939134":{"id":"n1820939134","loc":[-85.1127776,42.0855168]},"n1820939135":{"id":"n1820939135","loc":[-85.1243768,42.0759322]},"n1820939137":{"id":"n1820939137","loc":[-85.125974,42.0747547]},"n1820939138":{"id":"n1820939138","loc":[-85.1071248,42.0859973]},"n1820939139":{"id":"n1820939139","loc":[-85.5326175,41.9674833]},"n1820939140":{"id":"n1820939140","loc":[-85.1338715,42.0660833]},"n1820939142":{"id":"n1820939142","loc":[-85.649671,41.9135675]},"n1820939144":{"id":"n1820939144","loc":[-85.0236545,42.0920444]},"n1820939145":{"id":"n1820939145","loc":[-85.1084391,42.0859376]},"n1820939146":{"id":"n1820939146","loc":[-85.1539988,42.0618626]},"n1820939147":{"id":"n1820939147","loc":[-85.2354521,42.026511]},"n1820939148":{"id":"n1820939148","loc":[-85.2362246,42.0260408]},"n1820939149":{"id":"n1820939149","loc":[-85.2401342,42.0115233]},"n1820939150":{"id":"n1820939150","loc":[-85.295319,41.9747423]},"n1820939151":{"id":"n1820939151","loc":[-85.1164696,42.0835409]},"n1820939152":{"id":"n1820939152","loc":[-85.3232891,41.9712885]},"n1820939153":{"id":"n1820939153","loc":[-85.2574463,42.0068944]},"n1820939155":{"id":"n1820939155","loc":[-85.5704064,41.9598246]},"n1820939156":{"id":"n1820939156","loc":[-85.0349077,42.0998116]},"n1820939157":{"id":"n1820939157","loc":[-85.0949529,42.0925619]},"n1820939159":{"id":"n1820939159","loc":[-85.0179829,42.0902343]},"n1820939160":{"id":"n1820939160","loc":[-85.0405832,42.1016942]},"n1820939161":{"id":"n1820939161","loc":[-85.2534015,42.0111833]},"n1820939162":{"id":"n1820939162","loc":[-85.0839881,42.102708]},"n1820939163":{"id":"n1820939163","loc":[-85.0341996,42.1008385]},"n1820939164":{"id":"n1820939164","loc":[-85.1037761,42.0879731]},"n1820939173":{"id":"n1820939173","loc":[-85.0460616,42.1005786]},"n1820939177":{"id":"n1820939177","loc":[-85.0061651,42.0878059]},"n1820939181":{"id":"n1820939181","loc":[-85.1456775,42.0654684]},"n1820939183":{"id":"n1820939183","loc":[-85.1325508,42.0718439]},"n1820939185":{"id":"n1820939185","loc":[-85.2485842,42.008329]},"n1820939187":{"id":"n1820939187","loc":[-85.2744128,41.9949322]},"n1820939189":{"id":"n1820939189","loc":[-85.2579025,41.9999542]},"n1820939191":{"id":"n1820939191","loc":[-85.3358998,41.9828987]},"n1820939193":{"id":"n1820939193","loc":[-85.3192658,41.9716714]},"n1820939194":{"id":"n1820939194","loc":[-85.6400795,41.9130725]},"n1820939195":{"id":"n1820939195","loc":[-85.3278489,41.9780591]},"n1820939196":{"id":"n1820939196","loc":[-85.2800197,41.983061]},"n1820939197":{"id":"n1820939197","loc":[-85.3278167,41.9692943]},"n1820939198":{"id":"n1820939198","loc":[-85.3366894,41.9838653]},"n1820939199":{"id":"n1820939199","loc":[-85.0328383,42.0969923]},"n1820939201":{"id":"n1820939201","loc":[-85.3259284,41.9720383]},"n1820939217":{"id":"n1820939217","loc":[-85.1840181,42.0503277]},"n1820939220":{"id":"n1820939220","loc":[-85.422563,42.0089986]},"n1820939222":{"id":"n1820939222","loc":[-85.555386,41.9707856]},"n1820939224":{"id":"n1820939224","loc":[-85.3830809,42.002254]},"n1820939226":{"id":"n1820939226","loc":[-84.9917938,42.0857517]},"n1820939227":{"id":"n1820939227","loc":[-85.2936775,41.9740484]},"n1820939228":{"id":"n1820939228","loc":[-85.2632133,41.9975024]},"n1820939229":{"id":"n1820939229","loc":[-85.2809424,41.9853259]},"n1820939230":{"id":"n1820939230","loc":[-85.242104,42.0131204]},"n1820939232":{"id":"n1820939232","loc":[-85.2610246,41.9963901]},"n1820939233":{"id":"n1820939233","loc":[-85.2335531,42.0268378]},"n1820939234":{"id":"n1820939234","loc":[-85.3188839,41.9713575]},"n1820939235":{"id":"n1820939235","loc":[-85.2413637,42.0225658]},"n1820939237":{"id":"n1820939237","loc":[-85.0010796,42.0887215]},"n1820939239":{"id":"n1820939239","loc":[-85.2241697,42.0362624]},"n1820939243":{"id":"n1820939243","loc":[-85.0368456,42.1040134]},"n1820939244":{"id":"n1820939244","loc":[-85.1327986,42.069524]},"n1820939260":{"id":"n1820939260","loc":[-85.5408163,41.9711206]},"n1820939261":{"id":"n1820939261","loc":[-85.2959199,41.9746546]},"n1820939262":{"id":"n1820939262","loc":[-85.3298659,41.9683598]},"n1820939263":{"id":"n1820939263","loc":[-85.2240581,42.0358425]},"n1820939264":{"id":"n1820939264","loc":[-85.2438206,42.0101944]},"n1820939265":{"id":"n1820939265","loc":[-85.3984489,42.0059589]},"n1820939266":{"id":"n1820939266","loc":[-85.2330811,42.0294279]},"n1820939268":{"id":"n1820939268","loc":[-85.1126877,42.0857704]},"n1820939271":{"id":"n1820939271","loc":[-85.254925,42.0106253]},"n1820939273":{"id":"n1820939273","loc":[-85.4328046,42.0064662]},"n1820939277":{"id":"n1820939277","loc":[-85.289622,41.9789616]},"n1820939279":{"id":"n1820939279","loc":[-85.4574532,42.0004043]},"n1820939281":{"id":"n1820939281","loc":[-85.4803486,41.9867211]},"n1820939283":{"id":"n1820939283","loc":[-85.157475,42.0631848]},"n1820939285":{"id":"n1820939285","loc":[-85.2571458,42.0059935]},"n1820939287":{"id":"n1820939287","loc":[-85.2818544,41.9825984]},"n1820939289":{"id":"n1820939289","loc":[-85.2298302,42.0328781]},"n1820939291":{"id":"n1820939291","loc":[-85.4819523,41.984821]},"n1820939301":{"id":"n1820939301","loc":[-85.3139765,41.9701159]},"n1820939304":{"id":"n1820939304","loc":[-85.0424447,42.101742]},"n1820939306":{"id":"n1820939306","loc":[-85.6360283,41.9338482]},"n1820939310":{"id":"n1820939310","loc":[-85.3463025,41.9913622]},"n1820939312":{"id":"n1820939312","loc":[-85.4664869,41.9988097]},"n1820939314":{"id":"n1820939314","loc":[-85.149364,42.0622449]},"n1820939316":{"id":"n1820939316","loc":[-85.2460415,42.0153125]},"n1820939318":{"id":"n1820939318","loc":[-85.4806103,41.9924523]},"n1820939320":{"id":"n1820939320","loc":[-85.2449042,42.0190987]},"n1820939322":{"id":"n1820939322","loc":[-85.5280165,41.9689263]},"n1820939324":{"id":"n1820939324","loc":[-85.0051204,42.0882625]},"n1820939326":{"id":"n1820939326","loc":[-85.1240925,42.0771546]},"n1820939329":{"id":"n1820939329","loc":[-85.2261653,42.0342225]},"n1820939331":{"id":"n1820939331","loc":[-85.5259933,41.972211]},"n1820939333":{"id":"n1820939333","loc":[-85.0074754,42.0883183]},"n1820939335":{"id":"n1820939335","loc":[-85.0764014,42.1055549]},"n1820939336":{"id":"n1820939336","loc":[-85.2908773,41.9769597]},"n1820939337":{"id":"n1820939337","loc":[-85.4095382,42.0083449]},"n1820939346":{"id":"n1820939346","loc":[-85.2514166,42.0111753]},"n1820939348":{"id":"n1820939348","loc":[-85.0030377,42.0873799]},"n1820939350":{"id":"n1820939350","loc":[-85.3659362,41.9964974]},"n1820939352":{"id":"n1820939352","loc":[-85.226058,42.0348281]},"n1820939355":{"id":"n1820939355","loc":[-85.1902408,42.0507101]},"n1820939357":{"id":"n1820939357","loc":[-85.2781854,41.9946001]},"n1820939359":{"id":"n1820939359","loc":[-85.2139988,42.0405175]},"n1820939361":{"id":"n1820939361","loc":[-85.0086609,42.0908262]},"n1820939363":{"id":"n1820939363","loc":[-85.0627128,42.1043398]},"n1820939365":{"id":"n1820939365","loc":[-85.1311346,42.072501]},"n1820939369":{"id":"n1820939369","loc":[-85.248198,42.0082652]},"n1820939370":{"id":"n1820939370","loc":[-84.99792,42.087794]},"n1820939371":{"id":"n1820939371","loc":[-85.2786775,41.9942783]},"n1820939372":{"id":"n1820939372","loc":[-85.0342103,42.1013957]},"n1820939373":{"id":"n1820939373","loc":[-85.2022357,42.0444799]},"n1820939374":{"id":"n1820939374","loc":[-85.2279205,42.0337388]},"n1820939375":{"id":"n1820939375","loc":[-85.1337699,42.0712614]},"n1820939376":{"id":"n1820939376","loc":[-85.317517,41.9707062]},"n1820939377":{"id":"n1820939377","loc":[-85.1326326,42.070218]},"n1820939394":{"id":"n1820939394","loc":[-85.0197746,42.0899118]},"n1820939397":{"id":"n1820939397","loc":[-85.2590076,41.9984632]},"n1820939399":{"id":"n1820939399","loc":[-85.2469964,42.0083449]},"n1820939400":{"id":"n1820939400","loc":[-85.2470929,42.0146668]},"n1820939401":{"id":"n1820939401","loc":[-84.9984095,42.0878087]},"n1820939402":{"id":"n1820939402","loc":[-85.2372653,42.0243273]},"n1820939403":{"id":"n1820939403","loc":[-85.2454986,42.0091955]},"n1820939404":{"id":"n1820939404","loc":[-85.0539205,42.1035995]},"n1820939405":{"id":"n1820939405","loc":[-85.550601,41.9706101]},"n1820939406":{"id":"n1820939406","loc":[-85.0351343,42.0999656]},"n1820939407":{"id":"n1820939407","loc":[-85.0082908,42.0905755]},"n1820939408":{"id":"n1820939408","loc":[-85.0132904,42.0902251]},"n1820939410":{"id":"n1820939410","loc":[-85.0892546,42.094012]},"n1820939412":{"id":"n1820939412","loc":[-85.0350793,42.1030315]},"n1820939416":{"id":"n1820939416","loc":[-85.0012406,42.0886777]},"n1820939418":{"id":"n1820939418","loc":[-85.0577453,42.1029229]},"n1820939420":{"id":"n1820939420","loc":[-85.1230786,42.0776722]},"n1820939422":{"id":"n1820939422","loc":[-85.571136,41.9649304]},"n1820939436":{"id":"n1820939436","loc":[-85.1137968,42.0848997]},"n1820939437":{"id":"n1820939437","loc":[-85.3559584,41.9925105]},"n1820939438":{"id":"n1820939438","loc":[-85.0080172,42.0903565]},"n1820939439":{"id":"n1820939439","loc":[-85.0048897,42.0880913]},"n1820939441":{"id":"n1820939441","loc":[-85.0406959,42.1018574]},"n1820939443":{"id":"n1820939443","loc":[-85.3897328,42.0029078]},"n1820939445":{"id":"n1820939445","loc":[-85.122349,42.0782814]},"n1820939448":{"id":"n1820939448","loc":[-85.4872193,41.985036]},"n1820939450":{"id":"n1820939450","loc":[-85.0120459,42.0904919]},"n1820939452":{"id":"n1820939452","loc":[-85.6320543,41.921982]},"n1820939456":{"id":"n1820939456","loc":[-85.0844749,42.1036843]},"n1820939458":{"id":"n1820939458","loc":[-85.0968037,42.091296]},"n1820939463":{"id":"n1820939463","loc":[-85.5339747,41.9681841]},"n1820939465":{"id":"n1820939465","loc":[-85.4125423,42.0072129]},"n1820939467":{"id":"n1820939467","loc":[-85.6335563,41.9303626]},"n1820939469":{"id":"n1820939469","loc":[-85.2821014,41.9932126]},"n1820939471":{"id":"n1820939471","loc":[-85.374691,41.9969917]},"n1820939485":{"id":"n1820939485","loc":[-85.4471321,42.0049806]},"n1820939487":{"id":"n1820939487","loc":[-85.3752532,41.9972206]},"n1820939489":{"id":"n1820939489","loc":[-85.4517283,42.005927]},"n1820939492":{"id":"n1820939492","loc":[-85.4662552,42.0005693]},"n1820939494":{"id":"n1820939494","loc":[-85.0120083,42.0902928]},"n1820939496":{"id":"n1820939496","loc":[-85.044463,42.1004631]},"n1820939498":{"id":"n1820939498","loc":[-85.418293,42.0089667]},"n1820939500":{"id":"n1820939500","loc":[-85.0554762,42.1027358]},"n1820939504":{"id":"n1820939504","loc":[-85.1246289,42.0746858]},"n1820939507":{"id":"n1820939507","loc":[-85.0408139,42.1021838]},"n1820939508":{"id":"n1820939508","loc":[-85.1236204,42.0775169]},"n1820939509":{"id":"n1820939509","loc":[-85.0350109,42.1037428]},"n1820939510":{"id":"n1820939510","loc":[-85.0551583,42.1029878]},"n1820939511":{"id":"n1820939511","loc":[-85.0956771,42.0916662]},"n1820939512":{"id":"n1820939512","loc":[-85.2323408,42.0273638]},"n1820939513":{"id":"n1820939513","loc":[-85.1232771,42.0762388]},"n1820939531":{"id":"n1820939531","loc":[-85.264608,41.9997828]},"n1820939533":{"id":"n1820939533","loc":[-85.4198808,42.0087914]},"n1820939535":{"id":"n1820939535","loc":[-85.3080864,41.9715677]},"n1820939536":{"id":"n1820939536","loc":[-85.1189426,42.0812596]},"n1820939537":{"id":"n1820939537","loc":[-85.2642741,41.9996764]},"n1820939538":{"id":"n1820939538","loc":[-85.2572531,42.0079627]},"n1820939539":{"id":"n1820939539","loc":[-85.2907807,41.9790174]},"n1820939540":{"id":"n1820939540","loc":[-85.3171415,41.9707301]},"n1820939541":{"id":"n1820939541","loc":[-85.08777,42.0953841]},"n1820939542":{"id":"n1820939542","loc":[-85.1239262,42.0773218]},"n1820939543":{"id":"n1820939543","loc":[-84.9973956,42.0877968]},"n1820939544":{"id":"n1820939544","loc":[-85.011606,42.0896161]},"n1820939545":{"id":"n1820939545","loc":[-85.4077358,42.0082971]},"n1820939546":{"id":"n1820939546","loc":[-85.3614945,41.9933717]},"n1820939547":{"id":"n1820939547","loc":[-85.3189118,41.9697649]},"n1820939550":{"id":"n1820939550","loc":[-85.1262691,42.0740221]},"n1820939551":{"id":"n1820939551","loc":[-85.3863639,41.9994635]},"n1820939552":{"id":"n1820939552","loc":[-85.2836034,41.9923953]},"n1820939554":{"id":"n1820939554","loc":[-85.3222377,41.9715916]},"n1820939555":{"id":"n1820939555","loc":[-85.0122658,42.0906312]},"n1820939556":{"id":"n1820939556","loc":[-85.0022652,42.0877581]},"n1820939557":{"id":"n1820939557","loc":[-85.1011314,42.0899954]},"n1820939559":{"id":"n1820939559","loc":[-85.0008181,42.0885293]},"n1820939561":{"id":"n1820939561","loc":[-85.3637046,41.9942488]},"n1820939562":{"id":"n1820939562","loc":[-85.4500117,42.0052892]},"n1820939563":{"id":"n1820939563","loc":[-85.0537636,42.1036365]},"n1820939565":{"id":"n1820939565","loc":[-85.2367503,42.0246939]},"n1820939566":{"id":"n1820939566","loc":[-85.0448479,42.1002653]},"n1820939567":{"id":"n1820939567","loc":[-85.6337065,41.9295006]},"n1820939568":{"id":"n1820939568","loc":[-85.0879792,42.095623]},"n1820939569":{"id":"n1820939569","loc":[-85.6347623,41.9352369]},"n1820939570":{"id":"n1820939570","loc":[-85.1497931,42.0620378]},"n1820939571":{"id":"n1820939571","loc":[-85.5676169,41.9656324]},"n1820939572":{"id":"n1820939572","loc":[-85.638041,41.9166971]},"n1820939573":{"id":"n1820939573","loc":[-85.4993429,41.9781293]},"n1820939574":{"id":"n1820939574","loc":[-85.5352831,41.9692127]},"n1820939575":{"id":"n1820939575","loc":[-84.9924429,42.0857118]},"n1820939577":{"id":"n1820939577","loc":[-85.0581101,42.1026721]},"n1820939578":{"id":"n1820939578","loc":[-85.641088,41.9094477]},"n1820939579":{"id":"n1820939579","loc":[-85.2548821,42.0052282]},"n1820939580":{"id":"n1820939580","loc":[-85.1124463,42.0859734]},"n1820939581":{"id":"n1820939581","loc":[-85.1083479,42.0857624]},"n1820939583":{"id":"n1820939583","loc":[-85.1387424,42.0648893]},"n1820939584":{"id":"n1820939584","loc":[-85.5152645,41.9700892]},"n1820939585":{"id":"n1820939585","loc":[-85.5463738,41.9713439]},"n1820939586":{"id":"n1820939586","loc":[-85.360207,41.9933717]},"n1820939587":{"id":"n1820939587","loc":[-85.2402372,42.0120917]},"n1820939588":{"id":"n1820939588","loc":[-85.3936381,42.0047255]},"n1820939589":{"id":"n1820939589","loc":[-85.3310246,41.973784]},"n1820939590":{"id":"n1820939590","loc":[-85.0329403,42.096642]},"n1820939591":{"id":"n1820939591","loc":[-85.0097271,42.0910981]},"n1820939593":{"id":"n1820939593","loc":[-85.0446562,42.1003437]},"n1820939595":{"id":"n1820939595","loc":[-85.0856671,42.1008452]},"n1820939596":{"id":"n1820939596","loc":[-85.4087228,42.0083449]},"n1820939597":{"id":"n1820939597","loc":[-85.0609519,42.1052564]},"n1820939598":{"id":"n1820939598","loc":[-85.3432126,41.9874548]},"n1820939599":{"id":"n1820939599","loc":[-85.4041738,42.0067027]},"n1820939600":{"id":"n1820939600","loc":[-85.0825437,42.1035768]},"n1820939601":{"id":"n1820939601","loc":[-85.048422,42.101498]},"n1820939602":{"id":"n1820939602","loc":[-85.0336256,42.0999031]},"n1820939603":{"id":"n1820939603","loc":[-85.046818,42.1014104]},"n1820939605":{"id":"n1820939605","loc":[-85.2856524,41.98078]},"n1820939607":{"id":"n1820939607","loc":[-85.1118173,42.0864245]},"n1820939609":{"id":"n1820939609","loc":[-85.0443397,42.1006263]},"n1820939610":{"id":"n1820939610","loc":[-85.0336698,42.0978361]},"n1820939611":{"id":"n1820939611","loc":[-85.4630322,42.0014248]},"n1820939612":{"id":"n1820939612","loc":[-85.0613127,42.1052353]},"n1820939613":{"id":"n1820939613","loc":[-85.0137571,42.0887801]},"n1820939614":{"id":"n1820939614","loc":[-85.272487,41.9982013]},"n1820939616":{"id":"n1820939616","loc":[-85.4665727,41.9983791]},"n1820939617":{"id":"n1820939617","loc":[-85.1288078,42.0725476]},"n1820939618":{"id":"n1820939618","loc":[-85.4653282,42.00109]},"n1820939619":{"id":"n1820939619","loc":[-85.2314717,42.0276746]},"n1820939620":{"id":"n1820939620","loc":[-85.255982,42.0003569]},"n1820939621":{"id":"n1820939621","loc":[-85.2886779,41.9787223]},"n1820939622":{"id":"n1820939622","loc":[-85.22438,42.0367509]},"n1820939623":{"id":"n1820939623","loc":[-85.0334713,42.0998382]},"n1820939624":{"id":"n1820939624","loc":[-85.2236504,42.037484]},"n1820939625":{"id":"n1820939625","loc":[-85.636908,41.9175162]},"n1820939627":{"id":"n1820939627","loc":[-85.2669187,41.9989707]},"n1820939628":{"id":"n1820939628","loc":[-85.3247268,41.9720702]},"n1820939629":{"id":"n1820939629","loc":[-85.3785104,41.9987299]},"n1820939630":{"id":"n1820939630","loc":[-85.5267658,41.9720515]},"n1820939631":{"id":"n1820939631","loc":[-85.2445116,42.0098811]},"n1820939632":{"id":"n1820939632","loc":[-85.1271448,42.0725077]},"n1820939633":{"id":"n1820939633","loc":[-85.0345751,42.099724]},"n1820939634":{"id":"n1820939634","loc":[-85.4217476,42.0089986]},"n1820939635":{"id":"n1820939635","loc":[-85.3121848,41.9689433]},"n1820939636":{"id":"n1820939636","loc":[-85.2826419,41.9929985]},"n1820939637":{"id":"n1820939637","loc":[-85.3160257,41.9706344]},"n1820939638":{"id":"n1820939638","loc":[-85.5684967,41.9657919]},"n1820939640":{"id":"n1820939640","loc":[-85.225131,42.0356194]},"n1820939642":{"id":"n1820939642","loc":[-85.1324124,42.0693328]},"n1820939644":{"id":"n1820939644","loc":[-84.9994073,42.0878843]},"n1820939645":{"id":"n1820939645","loc":[-85.1087596,42.0863329]},"n1820939646":{"id":"n1820939646","loc":[-85.2915532,41.9782996]},"n1820939647":{"id":"n1820939647","loc":[-84.9988708,42.0877808]},"n1820939648":{"id":"n1820939648","loc":[-85.2243628,42.0356728]},"n1820939649":{"id":"n1820939649","loc":[-85.0427397,42.1020524]},"n1820939650":{"id":"n1820939650","loc":[-85.6388392,41.9100752]},"n1820939651":{"id":"n1820939651","loc":[-85.0133709,42.0888557]},"n1820939652":{"id":"n1820939652","loc":[-85.318798,41.9701211]},"n1820939653":{"id":"n1820939653","loc":[-85.6335778,41.9190602]},"n1820939654":{"id":"n1820939654","loc":[-85.6338396,41.9370247]},"n1820939655":{"id":"n1820939655","loc":[-85.0939069,42.0931988]},"n1820939656":{"id":"n1820939656","loc":[-85.5702347,41.9651378]},"n1820939657":{"id":"n1820939657","loc":[-85.4235286,42.0088392]},"n1820939658":{"id":"n1820939658","loc":[-85.2740856,41.9972206]},"n1820939659":{"id":"n1820939659","loc":[-85.4824299,41.9934195]},"n1820939660":{"id":"n1820939660","loc":[-85.3857846,42.0014408]},"n1820939661":{"id":"n1820939661","loc":[-85.0451658,42.10028]},"n1820939662":{"id":"n1820939662","loc":[-85.3893036,42.001377]},"n1820939664":{"id":"n1820939664","loc":[-85.2455845,42.0088607]},"n1820939665":{"id":"n1820939665","loc":[-85.2741071,41.9951116]},"n1820939666":{"id":"n1820939666","loc":[-85.1298375,42.0677718]},"n1820939667":{"id":"n1820939667","loc":[-85.5491848,41.9707377]},"n1820939669":{"id":"n1820939669","loc":[-85.2780298,41.995238]},"n1820939670":{"id":"n1820939670","loc":[-85.1330068,42.0716926]},"n1820939671":{"id":"n1820939671","loc":[-85.0811342,42.1025129]},"n1820939672":{"id":"n1820939672","loc":[-85.2325124,42.0290135]},"n1820939673":{"id":"n1820939673","loc":[-85.2975077,41.9716953]},"n1820939674":{"id":"n1820939674","loc":[-85.0951729,42.0922394]},"n1820939676":{"id":"n1820939676","loc":[-85.0363252,42.1043119]},"n1820939677":{"id":"n1820939677","loc":[-85.2960057,41.97349]},"n1820939678":{"id":"n1820939678","loc":[-85.3701849,41.9982515]},"n1820939679":{"id":"n1820939679","loc":[-85.3381486,41.9848861]},"n1820939680":{"id":"n1820939680","loc":[-85.2058448,42.0417286]},"n1820939682":{"id":"n1820939682","loc":[-85.0819335,42.1034443]},"n1820939683":{"id":"n1820939683","loc":[-85.3872223,41.9993359]},"n1820939684":{"id":"n1820939684","loc":[-85.095366,42.091909]},"n1820939685":{"id":"n1820939685","loc":[-85.2327914,42.0291888]},"n1820939686":{"id":"n1820939686","loc":[-85.0433459,42.1018773]},"n1820939687":{"id":"n1820939687","loc":[-85.0585339,42.1027318]},"n1820939688":{"id":"n1820939688","loc":[-85.0062885,42.0876347]},"n1820939689":{"id":"n1820939689","loc":[-85.246299,42.017377]},"n1820939690":{"id":"n1820939690","loc":[-85.2932376,41.9742877]},"n1820939691":{"id":"n1820939691","loc":[-85.2962846,41.9736815]},"n1820939692":{"id":"n1820939692","loc":[-85.6052365,41.9409193]},"n1820939693":{"id":"n1820939693","loc":[-85.2570536,42.0003341]},"n1820939694":{"id":"n1820939694","loc":[-85.0488458,42.1014064]},"n1820939695":{"id":"n1820939695","loc":[-85.4050321,42.0069578]},"n1820939696":{"id":"n1820939696","loc":[-85.4847517,41.9845894]},"n1820939697":{"id":"n1820939697","loc":[-85.0844655,42.1013826]},"n1820939698":{"id":"n1820939698","loc":[-85.1437206,42.0650008]},"n1820939699":{"id":"n1820939699","loc":[-85.1168183,42.0864034]},"n1820939700":{"id":"n1820939700","loc":[-85.5479831,41.9711366]},"n1820939701":{"id":"n1820939701","loc":[-85.0349948,42.1034124]},"n1820939702":{"id":"n1820939702","loc":[-85.0835589,42.1038821]},"n1820939703":{"id":"n1820939703","loc":[-85.0203875,42.0902649]},"n1820939704":{"id":"n1820939704","loc":[-85.0371191,42.1038184]},"n1820939705":{"id":"n1820939705","loc":[-85.1273312,42.0735681]},"n1820939707":{"id":"n1820939707","loc":[-85.1272239,42.0730226]},"n1820939710":{"id":"n1820939710","loc":[-85.0349881,42.1019012]},"n1820939712":{"id":"n1820939712","loc":[-85.2440459,42.0178313]},"n1820939713":{"id":"n1820939713","loc":[-85.2444751,42.0182618]},"n1820939714":{"id":"n1820939714","loc":[-85.0539996,42.1032863]},"n1820939715":{"id":"n1820939715","loc":[-85.2215905,42.0373246]},"n1820939716":{"id":"n1820939716","loc":[-85.0649712,42.1051994]},"n1820939717":{"id":"n1820939717","loc":[-85.0927146,42.0927581]},"n1820939718":{"id":"n1820939718","loc":[-85.3884668,42.0042312]},"n1820939719":{"id":"n1820939719","loc":[-85.0840672,42.1013241]},"n1820939720":{"id":"n1820939720","loc":[-85.304739,41.9725408]},"n1820939721":{"id":"n1820939721","loc":[-85.2243585,42.0371334]},"n1820939722":{"id":"n1820939722","loc":[-85.0599823,42.1049686]},"n1820939723":{"id":"n1820939723","loc":[-85.0298825,42.0944288]},"n1820939724":{"id":"n1820939724","loc":[-85.0366095,42.1042443]},"n1820939725":{"id":"n1820939725","loc":[-85.0698783,42.1058135]},"n1820939726":{"id":"n1820939726","loc":[-85.1054551,42.0873361]},"n1820939727":{"id":"n1820939727","loc":[-84.9952324,42.0864285]},"n1820939728":{"id":"n1820939728","loc":[-85.3442211,41.9897993]},"n1820939729":{"id":"n1820939729","loc":[-85.4386134,42.0056822]},"n1820939730":{"id":"n1820939730","loc":[-85.2438528,42.0146589]},"n1820939731":{"id":"n1820939731","loc":[-85.0355581,42.1041846]},"n1820939732":{"id":"n1820939732","loc":[-85.557682,41.9724447]},"n1820939734":{"id":"n1820939734","loc":[-85.2299418,42.033314]},"n1820939735":{"id":"n1820939735","loc":[-85.6297412,41.9419088]},"n1820939736":{"id":"n1820939736","loc":[-85.2645101,41.9980259]},"n1820939738":{"id":"n1820939738","loc":[-85.082195,42.1035649]},"n1820939739":{"id":"n1820939739","loc":[-85.234272,42.0267102]},"n1820939740":{"id":"n1820939740","loc":[-85.0130758,42.0895006]},"n1820939741":{"id":"n1820939741","loc":[-85.4594702,42.0000375]},"n1820939742":{"id":"n1820939742","loc":[-84.9946745,42.0863687]},"n1820939743":{"id":"n1820939743","loc":[-85.6438775,41.9120186]},"n1820939744":{"id":"n1820939744","loc":[-85.6372685,41.9168089]},"n1820939745":{"id":"n1820939745","loc":[-85.2789468,41.9893208]},"n1820939747":{"id":"n1820939747","loc":[-85.3775019,41.998427]},"n1820939749":{"id":"n1820939749","loc":[-85.0993571,42.0909178]},"n1820939750":{"id":"n1820939750","loc":[-85.1308503,42.0669339]},"n1820939751":{"id":"n1820939751","loc":[-85.4802566,41.9856659]},"n1820939752":{"id":"n1820939752","loc":[-85.2543563,42.0108804]},"n1820939753":{"id":"n1820939753","loc":[-85.1041033,42.0878815]},"n1820939755":{"id":"n1820939755","loc":[-85.4000969,42.0071651]},"n1820939757":{"id":"n1820939757","loc":[-85.3858275,42.0022381]},"n1820939758":{"id":"n1820939758","loc":[-85.3653998,41.996609]},"n1820939759":{"id":"n1820939759","loc":[-85.2432949,42.0202305]},"n1820939760":{"id":"n1820939760","loc":[-85.3878874,42.0042472]},"n1820939761":{"id":"n1820939761","loc":[-85.2516741,42.0114145]},"n1820939762":{"id":"n1820939762","loc":[-85.2788825,41.9865142]},"n1820939763":{"id":"n1820939763","loc":[-85.0009147,42.0886686]},"n1820939764":{"id":"n1820939764","loc":[-85.3918142,42.003434]},"n1820939765":{"id":"n1820939765","loc":[-85.5532832,41.9696848]},"n1820939766":{"id":"n1820939766","loc":[-85.5545063,41.969254]},"n1820939768":{"id":"n1820939768","loc":[-85.1327989,42.0704769]},"n1820939770":{"id":"n1820939770","loc":[-85.0588558,42.1047696]},"n1820939772":{"id":"n1820939772","loc":[-85.555798,41.9713017]},"n1820939773":{"id":"n1820939773","loc":[-85.0565853,42.1023589]},"n1820939774":{"id":"n1820939774","loc":[-85.2582941,41.9992765]},"n1820939775":{"id":"n1820939775","loc":[-85.3007264,41.9727642]},"n1820939776":{"id":"n1820939776","loc":[-85.2477045,42.0082652]},"n1820939777":{"id":"n1820939777","loc":[-85.2415247,42.0104973]},"n1821006698":{"id":"n1821006698","loc":[-85.6345227,41.9382009]},"n1821006700":{"id":"n1821006700","loc":[-85.6344894,41.938975]},"n1821006704":{"id":"n1821006704","loc":[-85.6351181,41.9370157]},"n1821006706":{"id":"n1821006706","loc":[-85.6357554,41.9361657]},"n1821006708":{"id":"n1821006708","loc":[-85.6351235,41.9368481]},"n1821006710":{"id":"n1821006710","loc":[-85.6352844,41.9364211]},"n1821006712":{"id":"n1821006712","loc":[-85.6351503,41.937307]},"n1821006716":{"id":"n1821006716","loc":[-85.6350366,41.9379774]},"n1821006725":{"id":"n1821006725","loc":[-85.6352147,41.9375903]},"n1821137607":{"id":"n1821137607","loc":[-85.5297057,41.9669915]},"n1821137608":{"id":"n1821137608","loc":[-85.5288598,41.9673094]},"n1821139530":{"id":"n1821139530","loc":[-85.4832228,41.9881686]},"n1821139531":{"id":"n1821139531","loc":[-85.4812101,41.9851258]},"n1821139532":{"id":"n1821139532","loc":[-85.4799127,41.9860244]},"n1821139533":{"id":"n1821139533","loc":[-85.4800313,41.9865555]},"n1841425201":{"id":"n1841425201","loc":[-85.4334577,42.0063713]},"n1841425222":{"id":"n1841425222","loc":[-85.4382449,42.0055785]},"n1914861007":{"id":"n1914861007","loc":[-85.394959,42.0057472]},"n1914861057":{"id":"n1914861057","loc":[-85.3967185,42.0049695]},"n1914861112":{"id":"n1914861112","loc":[-85.394179,42.0056906]},"n1914861306":{"id":"n1914861306","loc":[-85.3900226,42.0028488]},"n2114807565":{"id":"n2114807565","loc":[-85.6385979,41.9577824]},"n2114807568":{"id":"n2114807568","loc":[-85.6325097,41.9775713]},"n2114807572":{"id":"n2114807572","loc":[-85.6328996,41.9980965]},"n2114807578":{"id":"n2114807578","loc":[-85.6344818,41.9696956]},"n2114807583":{"id":"n2114807583","loc":[-85.6326289,41.9757853]},"n2114807593":{"id":"n2114807593","loc":[-85.6360828,41.9650674]},"n2130304159":{"id":"n2130304159","loc":[-85.6352537,41.9450015],"tags":{"railway":"level_crossing"}},"n2139795852":{"id":"n2139795852","loc":[-85.6374708,41.9311633]},"n2139858882":{"id":"n2139858882","loc":[-85.635178,41.9356158]},"n2139858883":{"id":"n2139858883","loc":[-85.63533,41.9355886]},"n2139858884":{"id":"n2139858884","loc":[-85.6353819,41.93556]},"n2139858885":{"id":"n2139858885","loc":[-85.6353665,41.9355157]},"n2139858886":{"id":"n2139858886","loc":[-85.6353165,41.9354971]},"n2139858887":{"id":"n2139858887","loc":[-85.6352454,41.9355328]},"n2139858888":{"id":"n2139858888","loc":[-85.6350184,41.9357846]},"n2139858889":{"id":"n2139858889","loc":[-85.634978,41.9359448]},"n2139858890":{"id":"n2139858890","loc":[-85.6347723,41.9361523]},"n2139858891":{"id":"n2139858891","loc":[-85.6347165,41.9362667]},"n2139858892":{"id":"n2139858892","loc":[-85.6346992,41.9364312]},"n2139858893":{"id":"n2139858893","loc":[-85.634603,41.9366329]},"n2139858894":{"id":"n2139858894","loc":[-85.6345973,41.9367488]},"n2139858895":{"id":"n2139858895","loc":[-85.6345127,41.9369734]},"n2139858896":{"id":"n2139858896","loc":[-85.634478,41.9371923]},"n2139858897":{"id":"n2139858897","loc":[-85.6344838,41.9373768]},"n2139858898":{"id":"n2139858898","loc":[-85.6346242,41.9375299]},"n2139858899":{"id":"n2139858899","loc":[-85.6347723,41.9376357]},"n2139858900":{"id":"n2139858900","loc":[-85.6347607,41.9377788]},"n2139858901":{"id":"n2139858901","loc":[-85.6346204,41.9379533]},"n2139858902":{"id":"n2139858902","loc":[-85.6344184,41.9380105]},"n2139858903":{"id":"n2139858903","loc":[-85.6341627,41.9380406]},"n2139858904":{"id":"n2139858904","loc":[-85.634005,41.9381679]},"n2139858905":{"id":"n2139858905","loc":[-85.63393,41.9383353]},"n2139858906":{"id":"n2139858906","loc":[-85.6338588,41.9384597]},"n2139858907":{"id":"n2139858907","loc":[-85.6336627,41.9387759]},"n2139858908":{"id":"n2139858908","loc":[-85.6335127,41.9389361]},"n2139858933":{"id":"n2139858933","loc":[-85.6353118,41.9432646]},"n2139858934":{"id":"n2139858934","loc":[-85.6353952,41.9433002]},"n2139858935":{"id":"n2139858935","loc":[-85.6356496,41.9433255]},"n2139858936":{"id":"n2139858936","loc":[-85.6363128,41.9433373]},"n2139858937":{"id":"n2139858937","loc":[-85.6365467,41.9433779]},"n2139858938":{"id":"n2139858938","loc":[-85.6368692,41.9435265]},"n2139858939":{"id":"n2139858939","loc":[-85.6370986,41.9437039]},"n2139858940":{"id":"n2139858940","loc":[-85.6372371,41.9437732]},"n2139858941":{"id":"n2139858941","loc":[-85.6374756,41.9438171]},"n2139858942":{"id":"n2139858942","loc":[-85.6376164,41.9439286]},"n2139858943":{"id":"n2139858943","loc":[-85.6377504,41.944138]},"n2139858944":{"id":"n2139858944","loc":[-85.6384204,41.9443137]},"n2139858945":{"id":"n2139858945","loc":[-85.6385726,41.9444506]},"n2139858946":{"id":"n2139858946","loc":[-85.638702,41.9445739]},"n2139858947":{"id":"n2139858947","loc":[-85.6387179,41.9446516]},"n2139858948":{"id":"n2139858948","loc":[-85.6387088,41.9447985]},"n2139858949":{"id":"n2139858949","loc":[-85.6387656,41.9449877]},"n2139858950":{"id":"n2139858950","loc":[-85.638777,41.9451448]},"n2139858951":{"id":"n2139858951","loc":[-85.6387088,41.9452631]},"n2139858964":{"id":"n2139858964","loc":[-85.6383346,41.9442912]},"n2139858966":{"id":"n2139858966","loc":[-85.6384724,41.9443605]},"n2139858967":{"id":"n2139858967","loc":[-85.6354078,41.9434285]},"n2139858968":{"id":"n2139858968","loc":[-85.635271,41.943654]},"n2139858969":{"id":"n2139858969","loc":[-85.6352657,41.9437437]},"n2139858970":{"id":"n2139858970","loc":[-85.635271,41.9438195]},"n2139858971":{"id":"n2139858971","loc":[-85.6351563,41.9438906]},"n2139858972":{"id":"n2139858972","loc":[-85.6351384,41.9438882]},"n2139858973":{"id":"n2139858973","loc":[-85.6351514,41.9438034]},"n2139858974":{"id":"n2139858974","loc":[-85.6351237,41.9436641]},"n2139858975":{"id":"n2139858975","loc":[-85.6351498,41.9436108]},"n2139858976":{"id":"n2139858976","loc":[-85.6351058,41.9435345]},"n2139858977":{"id":"n2139858977","loc":[-85.6349641,41.9432051]},"n2139858986":{"id":"n2139858986","loc":[-85.6341205,41.9380746]},"n2139858990":{"id":"n2139858990","loc":[-85.6345671,41.9381816]},"n2139858995":{"id":"n2139858995","loc":[-85.6339783,41.9382273]},"n2139859003":{"id":"n2139859003","loc":[-85.6340477,41.9373489]},"n2139859004":{"id":"n2139859004","loc":[-85.6339784,41.9374752]},"n2139870406":{"id":"n2139870406","loc":[-85.6342265,41.9432605]},"n2139877106":{"id":"n2139877106","loc":[-85.6346323,41.9438746]},"n2139982399":{"id":"n2139982399","loc":[-85.6324055,41.9408537]},"n2139982400":{"id":"n2139982400","loc":[-85.632488,41.941063],"tags":{"leisure":"slipway"}},"n2139982401":{"id":"n2139982401","loc":[-85.6327261,41.9415366]},"n2139982402":{"id":"n2139982402","loc":[-85.6326391,41.9413598]},"n2139982403":{"id":"n2139982403","loc":[-85.6327041,41.9414391]},"n2139982405":{"id":"n2139982405","loc":[-85.6322891,41.9406009]},"n2139982406":{"id":"n2139982406","loc":[-85.6325412,41.9425257]},"n2139989333":{"id":"n2139989333","loc":[-85.6340584,41.9431731]},"n2140006331":{"id":"n2140006331","loc":[-85.6361751,41.9459744]},"n2140006334":{"id":"n2140006334","loc":[-85.636528,41.9459751]},"n2140006336":{"id":"n2140006336","loc":[-85.6370918,41.9458926]},"n2140006338":{"id":"n2140006338","loc":[-85.6378806,41.9456474]},"n2140006340":{"id":"n2140006340","loc":[-85.6385831,41.9454343]},"n2140006342":{"id":"n2140006342","loc":[-85.639341,41.945157]},"n2140006344":{"id":"n2140006344","loc":[-85.6393497,41.9450232]},"n2140006346":{"id":"n2140006346","loc":[-85.6388245,41.9450145]},"n2140006348":{"id":"n2140006348","loc":[-85.6388167,41.9441739]},"n2140006351":{"id":"n2140006351","loc":[-85.6382915,41.9441797]},"n2140006353":{"id":"n2140006353","loc":[-85.63828,41.9438109]},"n2140006355":{"id":"n2140006355","loc":[-85.6381949,41.9436009]},"n2140006357":{"id":"n2140006357","loc":[-85.6371904,41.9435918]},"n2140006359":{"id":"n2140006359","loc":[-85.6366966,41.9432727]},"n2140006361":{"id":"n2140006361","loc":[-85.6353755,41.9432744]},"n2140006365":{"id":"n2140006365","loc":[-85.6350906,41.9435472]},"n2140006366":{"id":"n2140006366","loc":[-85.6343461,41.9441573]},"n2140006395":{"id":"n2140006395","loc":[-85.6351171,41.9437175]},"n2140006397":{"id":"n2140006397","loc":[-85.635352,41.9450206]},"n2140006399":{"id":"n2140006399","loc":[-85.6358194,41.9454937]},"n2140006401":{"id":"n2140006401","loc":[-85.6348693,41.9445739]},"n2140006431":{"id":"n2140006431","loc":[-85.6376737,41.9438023]},"n2140006437":{"id":"n2140006437","loc":[-85.6382631,41.9442724]},"n2189123379":{"id":"n2189123379","loc":[-85.6342671,41.9352665]},"w203974076":{"id":"w203974076","tags":{"highway":"footway"},"nodes":["n2139870442","n2139870457","n2139870458","n2139870459","n2139870460","n2139870452"]},"w170989131":{"id":"w170989131","tags":{"name":"St Joseph River","waterway":"river"},"nodes":["n1820938225","n1820938712","n1820937596","n1820937574","n1820938515","n1820938330","n1820938678","n1820938240","n1820938950","n1820939226","n1820939575","n1820937913","n1820938223","n1820937668","n1820938545","n1820937584","n1820939742","n1820939727","n1820937578","n1820938149","n1820938124","n1820938888","n1820938898","n1820937922","n1820939543","n1820939370","n1820939401","n1820939647","n1820938345","n1820939644","n1820938333","n1820938370","n1820938624","n1820938493","n1820939559","n1820939763","n1820939237","n1820939416","n1820937810","n1820938317","n1820938324","n1820937558","n1820939556","n1820938298","n1820939348","n1820939125","n1820939081","n1820938859","n1820939126","n1820938881","n1820939439","n1820939324","n1820939128","n1820938101","n1820937706","n1820938382","n1820938776","n1820937815","n1820939177","n1820939688","n1820938952","n1820938216","n1820938387","n1820939333","n1820938243","n1820938248","n1820937666","n1820939051","n1820938332","n1820939438","n1820939407","n1820939361","n1820937517","n1820938770","n1820939591","n1820937857","n1820938491","n1820937993","n1820938125","n1820938166","n1820937746","n1820939028","n1820937638","n1820938676","n1820938843","n1820938844","n1820937978","n1820938730","n1820939544","n1820938304","n1820939123","n1820939494","n1820939450","n1820939555","n1820938133","n1820938129","n1820938871","n1820939408","n1820938669","n1820938260","n1820939740","n1820937625","n1820938631","n1820939651","n1820939613","n1820937850","n1820938325","n1820937736","n1820938804","n1820938837","n1820938014","n1820938991","n1820938722","n1820938935","n1820937870","n1820938432","n1820937986","n1820938756","n1820938966","n1820939159","n1820937744","n1820938334","n1820937645","n1820939394","n1820937656","n1820938392","n1820939703","n1820938385","n1820938947","n1820938854","n1820938428","n1820938488","n1820938269","n1820938668","n1820938268","n1820938707","n1820937732","n1820939144","n1820938481","n1820938771","n1820938686","n1820938948","n1820937997","n1820937769","n1820939003","n1820938083","n1820939011","n1820938803","n1820938700","n1820939723","n1820938808","n1820938262","n1820938081","n1820938926","n1820938326","n1820938102","n1820938508","n1820939590","n1820939199","n1820938084","n1820938870","n1820938895","n1820937611","n1820938918","n1820938514","n1820939610","n1820938910","n1820937523","n1820938127","n1820939108","n1820937981","n1820938938","n1820938715","n1820939016","n1820938237","n1820939623","n1820939602","n1820937734","n1820938977","n1820939633","n1820939156","n1820939406","n1820938279","n1820938301","n1820937678","n1820937671","n1820939163","n1820938356","n1820939372","n1820937568","n1820937626","n1820939710","n1820939004","n1820938253","n1820938571","n1820937513","n1820939412","n1820939701","n1820939509","n1820938839","n1820939731","n1820937798","n1820939676","n1820939724","n1820939243","n1820939704","n1820937814","n1820937599","n1820938199","n1820938995","n1820938445","n1820938069","n1820938470","n1820939074","n1820938193","n1820938740","n1820938047","n1820939507","n1820939441","n1820939160","n1820937849","n1820937840","n1820938052","n1820938988","n1820938796","n1820937724","n1820937620","n1820939304","n1820938343","n1820939649","n1820938875","n1820939686","n1820938476","n1820937801","n1820937737","n1820938264","n1820939609","n1820939496","n1820939593","n1820939566","n1820939661","n1820937782","n1820938912","n1820939173","n1820937733","n1820938953","n1820939603","n1820937607","n1820938468","n1820939601","n1820939694","n1820939133","n1820938897","n1820938893","n1820937831","n1820937730","n1820938820","n1820938046","n1820938426","n1820938347","n1820937582","n1820938954","n1820938033","n1820938104","n1820938680","n1820939563","n1820939404","n1820939714","n1820939000","n1820937992","n1820938168","n1820939510","n1820939500","n1820937509","n1820938865","n1820939773","n1820938138","n1820938905","n1820937623","n1820939418","n1820937946","n1820939577","n1820937615","n1820939687","n1820939119","n1820937988","n1820938337","n1820937750","n1820938703","n1820938339","n1820939044","n1820939770","n1820938913","n1820937672","n1820939722","n1820937768","n1820939597","n1820939612","n1820937699","n1820937682","n1820937669","n1820937657","n1820939363","n1820937800","n1820938265","n1820937760","n1820938207","n1820938115","n1820939130","n1820939716","n1820938338","n1820938239","n1820939040","n1820938064","n1820938855","n1820939015","n1820938258","n1820939042","n1820939043","n1820938443","n1820939725","n1820937675","n1820938568","n1820938280","n1820937705","n1820938775","n1820938636","n1820938626","n1820937859","n1820938096","n1820937852","n1820939039","n1820938247","n1820938585","n1820937707","n1820938117","n1820938909","n1820939115","n1820939335","n1820938805","n1820937935","n1820937876","n1820938699","n1820937869","n1820938603","n1820938100","n1820938500","n1820938283","n1820938275","n1820938923","n1820938365","n1820938349","n1820937804","n1820937903","n1820937608","n1820938688","n1820939671","n1820938092","n1820937820","n1820938753","n1820938922","n1820937990","n1820939682","n1820939738","n1820939600","n1820938167","n1820937726","n1820939702","n1820938209","n1820939456","n1820937837","n1820938222","n1820938902","n1820939162","n1820938965","n1820938461","n1820937681","n1820937514","n1820937764","n1820939719","n1820939697","n1820938899","n1820939093","n1820938702","n1820939595","n1820938749","n1820938348","n1820937606","n1820938675","n1820938830","n1820938737","n1820938758","n1820938716","n1820939107","n1820937863","n1820939033","n1820938163","n1820937867","n1820938819","n1820938034","n1820938252","n1820937563","n1820937868","n1820939032","n1820938632","n1820937982","n1820937943","n1820939568","n1820939541","n1820938215","n1820939097","n1820938812","n1820937518","n1820937952","n1820938711","n1820938736","n1820939066","n1820937591","n1820938082","n1820938108","n1820938496","n1820939410","n1820938949","n1820938327","n1820937708","n1820939023","n1820937772","n1820938256","n1820939083","n1820938378","n1820938961","n1820937610","n1820939717","n1820938695","n1820938590","n1820939655","n1820938341","n1820939054","n1820939157","n1820939674","n1820939684","n1820939511","n1820937631","n1820939458","n1820937830","n1820937709","n1820937779","n1820939749","n1820938880","n1820938856","n1820938557","n1820939557","n1820938249","n1820938818","n1820937594","n1820939114","n1820938416","n1820937508","n1820938990","n1820938201","n1820937759","n1820937987","n1820939164","n1820939753","n1820938187","n1820939067","n1820937586","n1820937941","n1820938121","n1820937807","n1820938521","n1820939726","n1820938244","n1820939014","n1820938741","n1820937629","n1820938664","n1820938747","n1820939082","n1820938709","n1820938320","n1820938270","n1820937619","n1820937777","n1820937718","n1820939138","n1820938056","n1820938155","n1820938596","n1820937775","n1820938437","n1820938128","n1820939581","n1820939145","n1820938546","n1820938184","n1820937601","n1820937794","n1820938539","n1820939645","n1820938438","n1820938436","n1820939025","n1820938915","n1820938534","n1820937605","n1820939607","n1820939101","n1820939580","n1820939268","n1820939134","n1820938849","n1820938754","n1820938079","n1820937842","n1820938781","n1820938873","n1820938495","n1820938381","n1820938503","n1820939436","n1820938502","n1820939087","n1820938996","n1820938449","n1820938907","n1820937979","n1820937780","n1820937546","n1820939699","n1820937677","n1820938957","n1820938946","n1820937776","n1820937717","n1820938718","n1820937637","n1820938510","n1820937663","n1820938941","n1820939151","n1820937603","n1820938250","n1820937951","n1820938630","n1820938821","n1820938779","n1820938497","n1820938159","n1820939536","n1820938409","n1820938386","n1820939116","n1820938340","n1820939117","n1820938291","n1820938435","n1820937819","n1820938242","n1820939078","n1820938877","n1820939104","n1820939445","n1820938367","n1820938903","n1820939420","n1820938517","n1820939508","n1820939542","n1820939326","n1820938210","n1820939020","n1820938815","n1820937832","n1820939513","n1820937818","n1820939005","n1820938717","n1820939135","n1820938384","n1820937587","n1820939024","n1820939504","n1820939120","n1820939026","n1820938015","n1820938998","n1820937648","n1820939137","n1820937761","n1820938195","n1820938535","n1820939550","n1820938725","n1820938282","n1820937781","n1820937792","n1820939705","n1820937788","n1820939707","n1820937882","n1820939632","n1820938427","n1820938276","n1820939617","n1820939013","n1820939035","n1820937543","n1820939365","n1820937752","n1820937802","n1820939183","n1820939670","n1820938450","n1820939375","n1820937813","n1820937673","n1820937783","n1820939029","n1820939768","n1820939377","n1820937974","n1820939244","n1820939642","n1820937864","n1820938255","n1820938528","n1820939666","n1820938120","n1820937812","n1820938928","n1820939750","n1820939099","n1820938073","n1820938714","n1820939140","n1820938192","n1820937844","n1820938635","n1820938742","n1820939583","n1820937887","n1820938318","n1820938816","n1820939698","n1820938273","n1820939181","n1820937652","n1820938748","n1820937651","n1820938519","n1820938019","n1820938752","n1820938235","n1820939118","n1820938562","n1820939314","n1820939570","n1820938190","n1820938342","n1820938533","n1820937977","n1820939089","n1820939146","n1820938622","n1820938297","n1820938524","n1820939283","n1820938874","n1820938832","n1820937550","n1820937843","n1820938638","n1820938116","n1820938206","n1820938319","n1820939053","n1820937845","n1820938093","n1820939217","n1820938997","n1820939355","n1820938861","n1820938726","n1820938057","n1820939373","n1820937862","n1820938518","n1820939072","n1820939680","n1820938444","n1820938217","n1820938506","n1820938393","n1820938492","n1820938852","n1820938221","n1820938773","n1820937684","n1820939060","n1820938224","n1820938203","n1820938840","n1820937525","n1820938147","n1820938433","n1820938188","n1820939359","n1820938750","n1820938016","n1820938768","n1820937621","n1820937799","n1820938951","n1820938721","n1820939037","n1820937866","n1820939715","n1820938063","n1820938446","n1820937627","n1820939624","n1820938431","n1820939721","n1820939622","n1820939239","n1820939263","n1820939648","n1820939640","n1820938867","n1820938757","n1820938439","n1820939352","n1820937740","n1820939329","n1820938229","n1820937583","n1820938180","n1820938366","n1820937767","n1820937758","n1820939374","n1820938869","n1820938292","n1820938400","n1820938399","n1820939734","n1820939289","n1820938944","n1820937755","n1820938759","n1820938434","n1820937600","n1820937825","n1820937670","n1820937793","n1820938011","n1820938246","n1820938956","n1820937770","n1820937757","n1820938059","n1820937860","n1820937569","n1820939266","n1820939685","n1820939672","n1820938606","n1820938772","n1820939038","n1820938211","n1820938359","n1820939619","n1820938708","n1820939512","n1820938065","n1820939233","n1820939739","n1820938786","n1820938879","n1820939147","n1820938563","n1820939148","n1820937839","n1820937659","n1820937786","n1820938419","n1820939565","n1820939402","n1820937710","n1820938254","n1820938271","n1820938390","n1820937680","n1820938140","n1820937817","n1820938218","n1820937985","n1820939235","n1820938441","n1820938401","n1820938719","n1820937795","n1820938971","n1820938460","n1820939759","n1820937972","n1820937841","n1820938462","n1820939320","n1820938978","n1820938360","n1820939713","n1820937676","n1820939712","n1820937939","n1820938080","n1820937754","n1820937753","n1820938530","n1820937886","n1820939689","n1820939124","n1820938697","n1820938789","n1820939105","n1820938860","n1820938853","n1820939400","n1820937561","n1820938404","n1820938774","n1820939316","n1820937696","n1820938782","n1820938975","n1820937564","n1820939730","n1820938257","n1820937853","n1820938487","n1820938848","n1820938906","n1820939230","n1820938424","n1820938051","n1820937771","n1820939587","n1820939149","n1820938792","n1820939041","n1820938934","n1820939777","n1820937515","n1820939058","n1820938312","n1820939264","n1820939631","n1820939109","n1820939403","n1820939664","n1820938724","n1820938929","n1820939399","n1820939776","n1820939369","n1820939185","n1820937701","n1820938126","n1820938336","n1820938219","n1820939080","n1820938642","n1820938043","n1820937725","n1820938548","n1820938552","n1820938035","n1820938684","n1820937778","n1820938764","n1820939021","n1820939346","n1820937712","n1820939761","n1820938397","n1820937747","n1820938566","n1820939161","n1820939090","n1820939752","n1820939271","n1820938878","n1820938110","n1820938346","n1820938499","n1820938151","n1820939538","n1820938281","n1820939153","n1820938551","n1820939285","n1820938197","n1820938408","n1820938482","n1820939036","n1820939579","n1820938489","n1820938483","n1820938189","n1820938123","n1820938087","n1820937741","n1820938485","n1820937590","n1820938972","n1820937773","n1820937520","n1820938872","n1820938131","n1820938452","n1820938328","n1820939620","n1820937641","n1820938353","n1820939693","n1820938705","n1820937640","n1820939189","n1820938144","n1820939774","n1820938694","n1820938238","n1820939397","n1820937917","n1820938454","n1820938567","n1820938979","n1820938060","n1820938204","n1820937828","n1820939232","n1820938806","n1820938857","n1820938078","n1820938105","n1820939228","n1820938604","n1820937763","n1820937854","n1820938289","n1820939736","n1820937937","n1820937714","n1820938278","n1820938058","n1820938706","n1820938989","n1820938313","n1820938520","n1820938288","n1820937689","n1820939537","n1820939531","n1820939019","n1820937527","n1820938455","n1820938814","n1820938045","n1820939627","n1820938213","n1820938161","n1820938331","n1820938024","n1820938220","n1820938062","n1820938178","n1820937796","n1820937644","n1820938490","n1820937589","n1820937879","n1820939614","n1820938882","n1820938039","n1820938538","n1820937667","n1820937719","n1820938561","n1820939658","n1820938783","n1820938601","n1820938198","n1820938388","n1820938969","n1820937687","n1820939086","n1820939665","n1820939187","n1820938498","n1820938261","n1820937983","n1820938068","n1820938136","n1820939061","n1820938137","n1820938186","n1820939071","n1820937592","n1820939669","n1820937553","n1820939357","n1820938727","n1820939371","n1820939112","n1820939079","n1820938743","n1820938467","n1820938834","n1820938022","n1820938537","n1820938122","n1820938516","n1820937614","n1820937612","n1820939469","n1820939636","n1820939050","n1820939552","n1820938157","n1820938663","n1820938955","n1820939091","n1820938430","n1820938471","n1820937809","n1820938074","n1820938208","n1820938914","n1820938858","n1820938417","n1820937531","n1820938107","n1820939100","n1820938751","n1820937711","n1820938824","n1820939745","n1820937572","n1820938602","n1820938212","n1820938097","n1820937921","n1820938090","n1820938511","n1820938876","n1820939762","n1820938234","n1820938048","n1820937774","n1820937856","n1820937749","n1820937765","n1820938286","n1820939095","n1820938480","n1820939229","n1820938277","n1820937617","n1820938311","n1820937622","n1820939196","n1820937690","n1820939006","n1820939287","n1820939131","n1820938106","n1820938784","n1820938335","n1820938095","n1820938182","n1820937715","n1820937683","n1820938070","n1820939605","n1820938527","n1820938763","n1820938398","n1820937686","n1820939621","n1820937664","n1820939277","n1820938565","n1820939539","n1820938099","n1820939646","n1820938556","n1820937548","n1820938729","n1820939336","n1820938259","n1820938728","n1820938361","n1820937643","n1820938644","n1820939007","n1820939690","n1820939227","n1820937635","n1820937950","n1820938682","n1820939150","n1820939012","n1820939261","n1820939111","n1820937805","n1820939691","n1820939677","n1820937628","n1820937811","n1820938790","n1820938251","n1820938226","n1820938942","n1820937633","n1820937984","n1820937751","n1820939673","n1820938970","n1820938415","n1820938597","n1820938309","n1820938111","n1820938472","n1820938894","n1820938402","n1820937593","n1820938570","n1820939102","n1820939775","n1820937948","n1820939121","n1820937511","n1820938787","n1820939720","n1820939075","n1820937880","n1820937742","n1820937721","n1820939535","n1820938486","n1820938354","n1820937632","n1820939010","n1820938885","n1820938089","n1820937613","n1820938442","n1820938245","n1820938272","n1820937566","n1820938295","n1820938532","n1820938883","n1820937713","n1820937674","n1820939635","n1820938448","n1820938355","n1820938587","n1820938559","n1820937787","n1820939301","n1820937723","n1820939056","n1820937560","n1820938323","n1820938230","n1820938453","n1820938377","n1820938357","n1820939637","n1820938017","n1820939540","n1820939376","n1820937639","n1820937642","n1820938075","n1820938351","n1820938766","n1820937897","n1820938973","n1820938066","n1820939547","n1820939652","n1820937944","n1820937748","n1820939234","n1820939193","n1820937891","n1820938785","n1820939132","n1820938523","n1820938884","n1820938411","n1820939554","n1820938791","n1820937655","n1820938368","n1820939152","n1820938030","n1820938447","n1820937580","n1820939628","n1820937588","n1820937894","n1820939201","n1820938086","n1820937650","n1820938379","n1820939008","n1820938999","n1820937524","n1820937872","n1820938389","n1820939197","n1820938422","n1820938936","n1820939262","n1820937634","n1820938583","n1820939589","n1820937901","n1820939034","n1820939065","n1820938290","n1820939195","n1820938228","n1820937884","n1820938797","n1820938191","n1820939191","n1820939198","n1820937892","n1820939679","n1820938507","n1820937647","n1820937909","n1820938542","n1820939598","n1820937851","n1820939084","n1820939728","n1820937688","n1820938263","n1820938670","n1820937762","n1820939310","n1820938925","n1820938862","n1820938822","n1820938547","n1820937731","n1820938594","n1820938592","n1820938214","n1820938284","n1820937835","n1820938599","n1820939437","n1820937834","n1820937576","n1820937692","n1820939586","n1820939546","n1820938403","n1820937970","n1820939561","n1820938098","n1820938851","n1820938477","n1820938892","n1820939045","n1820939758","n1820939350","n1820938321","n1820938440","n1820938595","n1820938364","n1820938962","n1820938118","n1820939678","n1820938406","n1820938549","n1820937555","n1820938823","n1820937521","n1820939471","n1820939487","n1820938799","n1820938605","n1820937928","n1820938373","n1820939747","n1820939629","n1820937557","n1820937526","n1820938958","n1820938833","n1820937636","n1820938967","n1820938760","n1820938842","n1820938067","n1820939077","n1820939224","n1820938185","n1820939110","n1820938372","n1820939757","n1820939063","n1820939660","n1820938813","n1820937528","n1820938369","n1820938896","n1820939551","n1820939683","n1820937660","n1820937873","n1820938810","n1820938478","n1820939662","n1820937595","n1820939052","n1820938113","n1820939070","n1820938733","n1820937878","n1820938300","n1820939760","n1820939718","n1820937646","n1820939057","n1820939443","n1914861306","n1820938013","n1820937529","n1820939764","n1820938826","n1820937885","n1820939588","n1820937865","n1820937833","n1914861112","n1820938761","n1914861007","n1820937905","n1820938541","n1820939092","n1914861057","n1820938153","n1820938267","n1820939265","n1820938085","n1820939018","n1820939755","n1820938474","n1820939027","n1820938593","n1820938202","n1820939599","n1820939695","n1820938077","n1820938012","n1820939545","n1820939596","n1820939337","n1820938227","n1820937698","n1820938475","n1820939465","n1820938165","n1820938698","n1820938525","n1820938529","n1820938553","n1820938940","n1820939498","n1820938501","n1820939533","n1820938924","n1820939634","n1820939220","n1820939657","n1820938887","n1820938838","n1820938114","n1820937823","n1820938778","n1820938801","n1820939096","n1820938981","n1820937953","n1820938732","n1820938980","n1820938960","n1820937949","n1820938026","n1820939273","n1841425201","n1820938629","n1820938864","n1820938554","n1820938088","n1820937685","n1841425222","n1820939729","n1820937665","n1820937838","n1820937739","n1820938780","n1820937821","n1820938825","n1820939055","n1820939485","n1820938041","n1820938746","n1820939562","n1820938459","n1820939489","n1820938050","n1820937980","n1820937695","n1820938413","n1820938555","n1820937703","n1820938536","n1820938196","n1820938287","n1820938169","n1820939279","n1820938531","n1820938959","n1820939741","n1820938665","n1820938963","n1820939611","n1820937653","n1820939618","n1820939492","n1820938600","n1820938628","n1820939312","n1820939616","n1820937738","n1820939001","n1820939062","n1820938794","n1820938558","n1820937822","n1820937532","n1820939073","n1820938200","n1820938241","n1820938968","n1820938927","n1820938306","n1820937630","n1820938456","n1820937694","n1820938908","n1820939076","n1820937522","n1820939659","n1820938522","n1820939318","n1820938932","n1820938841","n1820937579","n1820937540","n1820938560","n1821139530","n1820938964","n1820937662","n1820939281","n1821139533","n1820937797","n1821139532","n1820939751","n1821139531","n1820939291","n1820938420","n1820939696","n1820938904","n1820938484","n1820939448","n1820939009","n1820938735","n1820938986","n1820938937","n1820939030","n1820938734","n1820938745","n1820939106","n1820938987","n1820937858","n1820938673","n1820938620","n1820937808","n1820937700","n1820939573","n1820938540","n1820937661","n1820937570","n1820938396","n1820937875","n1820939048","n1820938233","n1820938793","n1820939584","n1820938412","n1820938394","n1820937846","n1820938800","n1820938690","n1820939331","n1820939630","n1820938762","n1820938710","n1820939322","n1820938992","n1821137608","n1821137607","n1820937924","n1820939139","n1820939463","n1820939574","n1820938294","n1820938071","n1820938307","n1820938061","n1820939260","n1820937899","n1820938310","n1820938983","n1820937530","n1820938993","n1820938890","n1820937915","n1820938231","n1820938040","n1820938920","n1820939585","n1820938135","n1820939700","n1820937824","n1820939667","n1820937930","n1820938134","n1820937551","n1820939405","n1820938232","n1820937716","n1820937848","n1820939765","n1820939068","n1820939766","n1820937933","n1820937720","n1820939222","n1820939772","n1820939022","n1820939732","n1820937702","n1820937691","n1820938945","n1820937756","n1820938451","n1820938410","n1820938798","n1820937945","n1820937654","n1820938598","n1820938836","n1820937571","n1820937556","n1820938994","n1820938919","n1820938863","n1820939064","n1820938018","n1820937658","n1820937537","n1820938142","n1820938666","n1820937535","n1820939571","n1820938465","n1820939638","n1820937533","n1820939656","n1820939422","n1820938109","n1820938405","n1820938028","n1820937649","n1820938829","n1820939031","n1820939155","n1820938350","n1820938463","n1820938425","n1820939047","n1820938831","n1820938494","n1820937697","n1820938504","n1820938900","n1820937784","n1820938414","n1820938076","n1820938723","n1820937722","n1820938739","n1820937791","n1820938985","n1820938352","n1820938293","n1820938274","n1820939692","n1820937871","n1820939059","n1820938868","n1820937877","n1820937743","n1820938429","n1820937545","n1820937575","n1820938302","n1820938505","n1820938916","n1820938374","n1820938329","n1820937790","n1820939735","n1820938930","n1820937995","n1820938512","n1820938130","n1820938194","n1820938671","n1820938802","n1820937542","n1820937602","n1820939069","n1820938901","n1820939654","n1820937727","n1820939569","n1820938375","n1820939306","n1820938479","n1820938376","n1820938667","n1820937766","n1820939467","n1820939567","n1820937806","n1820938943","n1820938931","n1820937745","n1820939452","n1820938738","n1820938053","n1820939653","n1820938640","n1820937604","n1820937536","n1820938701","n1820939625","n1820939744","n1820939572","n1820937577","n1820937541","n1820938891","n1820937597","n1820938469","n1820939194","n1820937539","n1820938911","n1820939017","n1820939650","n1820939103","n1820939578","n1820938132","n1820937549","n1820938634","n1820939743","n1820937544","n1820937826","n1820937598","n1820937547","n1820938032","n1820939142"]},"w17963021":{"id":"w17963021","tags":{"highway":"residential"},"nodes":["n185948706","n185948708","n185948710"]},"w203974069":{"id":"w203974069","tags":{"amenity":"shelter","area":"yes","building":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139870431","n2139870432","n2139870433","n2139870434","n2139870431"]},"w209816575":{"id":"w209816575","tags":{"area":"yes","building":"yes"},"nodes":["n2199856288","n2199856289","n2199856290","n2199856291","n2199856292","n2199856293","n2199856294","n2199856295","n2199856296","n2199856297","n2199856298","n2199856299","n2199856300","n2199856301","n2199856302","n2199856303","n2199856288"]},"w203841838":{"id":"w203841838","tags":{"area":"yes","natural":"water"},"nodes":["n2138493826","n2138493827","n2138493828","n2138493829","n2138493830","n2138493831","n2138493833","n2138493832","n2138493826"]},"w203972937":{"id":"w203972937","tags":{"highway":"path","name":"Riverwalk Trail","surface":"asphalt","width":"3"},"nodes":["n2139858882","n2139858883","n2139858884","n2139858885","n2139858886","n2139858887","n2139858882","n2139858888","n2139858889","n2139858890","n2139858891","n2139858892","n2139858893","n2139858894","n2139858895","n2139858896","n2139858897","n2139858898","n2139858899","n2139858900","n2139858901","n2139858902","n2139858903","n2139858986","n2139858904","n2139858995","n2139858905","n2139858906","n2139858907","n2139858908","n2139858909","n2139858910","n2139858911","n2139858912","n2139858913","n2139858914","n2139858915","n2139858916","n2139858917","n2139858918","n2139858919","n2139858920","n2139858921","n2139858922","n2139858923","n2139858924","n2139858925","n2139858926","n2139858927","n2139858982","n2139858928","n2139858929","n2139858930","n2139858931","n2139858932","n2139858981","n2139858933","n2139858934","n2139858935","n2139858936","n2139858937","n2139858938","n2139858939","n2139858940","n2139858941","n2139858942","n2139858943","n2140006437","n2139858964","n2139858944","n2139858966","n2139858945","n2139858946","n2139858947","n2139858948","n2139858949","n2139858950","n2139858951"]},"w17964015":{"id":"w17964015","tags":{"highway":"residential"},"nodes":["n185954680","n185954683","n185954685","n185954687","n185954689","n185954690","n185954691","n2139870379","n2139870456","n185954692","n185954693","n185954695"]},"w17967315":{"id":"w17967315","tags":{"highway":"residential","name":"South Andrews Street"},"nodes":["n185981999","n185974477","n185964963"]},"w203974071":{"id":"w203974071","tags":{"highway":"footway"},"nodes":["n2139870439","n2139870440","n2139870441","n2139870442","n2139870443","n2139870444","n2139870445","n2139870446","n2139870447","n2139870448","n2139870449"]},"w170848824":{"id":"w170848824","tags":{"name":"Rocky River","waterway":"river"},"nodes":["n1819858503","n1819858531","n1819858526","n1819858518","n1819858505","n1819858508","n1819858512","n1819858514","n1819858528","n1819858509","n1819858511","n1819858507","n1819858521"]},"w203986458":{"id":"w203986458","tags":{"amenity":"shelter","area":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139989357","n2139989359","n2139989360","n2139989362","n2139989357"]},"w170844917":{"id":"w170844917","tags":{"waterway":"riverbank"},"nodes":["n1819805911","n1819805690","n1819805812","n1819805766","n1819805802","n1819805885","n1819805626","n1819805842","n1819805715","n1819805694","n1819805618","n1819805629","n1819805731","n1819805636","n1819805878","n1819805718","n1819805798","n1819849057","n1819805666","n1819805852","n1819805805","n1819805789","n1819805868","n1819805680","n1819805918","n1819848888","n1819805762","n2139989328","n1819805907","n2139989330","n1819805915","n1819858521","n1819805854","n1819805876","n1819805864","n1819805922","n2139859004","n1819805702","n2139859003","n1819805614","n1819805792","n1819805786","n1819805777","n1819805645","n1819805838","n1819805889","n1819805795","n1819805707","n1819805774","n1819805808","n1819805810","n1819805724","n1819805676","n1819805728","n1819805783","n1819805687","n1819805727","n2189123379","n1819805632","n1819805641","n1819805760","n1819805887","n1819805861","n1819805722","n1819805880","n2139982405","n2139982399","n2139982400","n1819805770","n2139982402","n2139982403","n2139982401","n1819805780","n1819805834","n2139982406","n1819805698","n1819805647","n1819805870","n1819805683","n1819805622","n1819805639","n1819805858","n1819805643","n1819805673","n1819805925","n1819805849","n1819805711","n1819805846","n1819805669","n1819805883","n1819805814","n1819805873","n1819805911"]},"w17967326":{"id":"w17967326","tags":{"highway":"residential","name":"North Constantine Street"},"nodes":["n185985217","n185985219","n185985221","n185985222","n185985223","n185985225","n2140006431","n185985227","n185985229","n185985231","n185985233","n185985235","n185985238","n185985240","n2140018998","n185964965"]},"w134150789":{"id":"w134150789","tags":{"highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964971","n2139870406","n185964972"]},"w17966400":{"id":"w17966400","tags":{"highway":"tertiary","name":"South Constantine Street"},"nodes":["n185958672","n185964965"]},"w203974066":{"id":"w203974066","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139870417","n2139870418","n2139870420","n2139870419"]},"w17965998":{"id":"w17965998","tags":{"name":"Conrail Railroad","railway":"rail"},"nodes":["n185972775","n185972777","n185972779","n185972781","n185972783","n185972785","n185972787","n185972788","n185972789","n185972790","n185972791","n185972793","n185972795","n185972797","n185972798","n185972800","n185972802","n185972805","n185972807","n185972809","n185972811","n185972813","n185972814","n185972815","n185972816","n185972817","n185972819","n185972821","n185972824","n185972826","n185972830","n185972832","n185972834","n185972835","n185972836","n185972839","n185990434","n2114807572","n2114807568","n185972845","n2114807583","n185972847","n185972849","n185972851","n2114807578","n1475293254","n2114807593","n1475293226","n185972862","n2114807565","n185951869","n1475293234","n1475293252","n185972868","n1475293264","n1475293222","n185972878","n1475293261","n185972882","n185972885","n1475293260","n1475293240","n185972891","n185972895","n185972897","n185972899","n2130304159","n1475284023","n185972903"]},"w134150795":{"id":"w134150795","tags":{"bridge":"yes","highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964970","n185964971"]},"w203974067":{"id":"w203974067","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139870420","n2139870421"]},"w170995908":{"id":"w170995908","tags":{"highway":"residential","name":"Thomas Street"},"nodes":["n1821006702","n1821006700","n1821006698","n2139858990","n1821006716","n1821006725","n1821006712","n1821006704","n1821006708","n1821006710","n1821006706"]},"w17965834":{"id":"w17965834","tags":{"highway":"residential","name":"Spring Street"},"nodes":["n185971361","n185971364","n185971366","n185971368","n185954695","n185964968"]},"w203974070":{"id":"w203974070","tags":{"amenity":"shelter","area":"yes","building":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139870435","n2139870436","n2139870437","n2139870438","n2139870435"]},"w203989879":{"id":"w203989879","tags":{"highway":"service"},"nodes":["n2140018998","n2140018999","n2140019000"]},"w203974062":{"id":"w203974062","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139870387","n2139870388","n2139870389","n2139870390","n2139870391","n2139870392","n2139870397","n2139870393","n2139870396","n2139870395","n2139870394","n2139870387"]},"w203974061":{"id":"w203974061","tags":{"bridge":"yes","highway":"footway"},"nodes":["n2139870382","n2139870383"]},"w203049587":{"id":"w203049587","tags":{"area":"yes","name":"Scidmore Park Petting Zoo","tourism":"zoo","zoo":"petting_zoo"},"nodes":["n2130304133","n2130304136","n2130304138","n2130304140","n2130304142","n2130304144","n2130304146","n2130304147","n2130304148","n2130304149","n2130304150","n2130304151","n2130304133"]},"w203972941":{"id":"w203972941","tags":{"highway":"path"},"nodes":["n2139858982","n2139858983","n2139858984","n2139858985","n2139858927"]},"w203974065":{"id":"w203974065","tags":{"highway":"service"},"nodes":["n2139870406","n2139870407","n2139870408","n2139870417","n2139870409","n2139870410","n2139870411","n2139870412","n2139870426","n2139870413","n2139870414","n2139870415","n2139870419","n2139870416","n2139870421","n2139870408"]},"w203972940":{"id":"w203972940","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139858934","n2139858967","n2139858968","n2139858969","n2139858970","n2139858971","n2139858972","n2139858973","n2139858974","n2139858975","n2139858976","n2139858977","n2139858978","n2139858979","n2139858980","n2139858981"]},"w203974072":{"id":"w203974072","tags":{"highway":"footway"},"nodes":["n2139858925","n2139870450","n2139870453","n2139870451","n2139870452","n2139870441"]},"w203974074":{"id":"w203974074","tags":{"highway":"footway"},"nodes":["n2139870454","n2139870456","n2139870429"]},"w203974060":{"id":"w203974060","tags":{"highway":"footway"},"nodes":["n2139870383","n2139870384","n2139870422","n2139870385","n2139870386","n2139870388"]},"w203841837":{"id":"w203841837","tags":{"area":"yes","natural":"water"},"nodes":["n2138493807","n2138493808","n2138493809","n2138493810","n2138493811","n2138493812","n2138493813","n2138493814","n2138493815","n2138493816","n2138493825","n2138493817","n2138493824","n2138493818","n2138493819","n2138493820","n2138493821","n2138493822","n2138493823","n2138493807"]},"w134150845":{"id":"w134150845","tags":{"bridge":"yes","name":"Conrail Railroad","railway":"rail"},"nodes":["n185972903","n185972905"]},"w203974059":{"id":"w203974059","tags":{"highway":"footway"},"nodes":["n2139870430","n2139870439","n2139870429","n2139870428","n2139870379","n2139870455","n2139870380","n2139870381","n2139858925","n2139870382"]},"w203986457":{"id":"w203986457","tags":{"area":"yes","leisure":"park","name":"Scidmore Park"},"nodes":["n2139989333","n2139989335","n2139989337","n2139989339","n1819805762","n2139989328","n1819805907","n2139989330","n1819805915","n2139989341","n2139989344","n2139989346","n2139989348","n2139989350","n2139989351","n2139989353","n2139989355","n2139989333"]},"w170848331":{"id":"w170848331","tags":{"name":"Rocky River","waterway":"river"},"nodes":["n1819848937","n1819849104","n1819849076","n1819849183","n1819848928","n1819848972","n1819848948","n1819848971","n1819848859","n1819849008","n1819848889","n1819849026","n1819849094","n1819849083","n1819849079","n1819849187","n1819848992","n1819849060","n1819849056","n1819849071","n1819849067","n1819849048","n1819849036","n1819849150","n1819849075","n1819849051","n1819849062","n1819848926","n1819849035","n1819848987","n1819849012","n1819848933","n1819848996","n1819848990","n1819849005","n1819849021","n1819848892","n1819849092","n1819848863","n1819848922","n1819848858","n1819848855","n1819848974","n1819848953","n1819849019","n1819849049","n1819848979","n1819849140","n1819849193","n1819849147","n1819849151","n1819849163","n1819849023","n1819848878","n1819849004","n1819848857","n1819848879","n1819849041","n1819849165","n1819849107","n1819849156","n1819848934","n1819848914","n1819848955","n1819848931","n1819848927","n1819849084","n1819849169","n1819849045","n1819848945","n1819849095","n1819848924","n1819849171","n1819849141","n1819849046","n1819849197","n1819849011","n1819849108","n1819849158","n1819849160","n1819848870","n1819849006","n1819849157","n1819848993","n1819848970","n1819849202","n1819848903","n1819848975","n1819848849","n1819849025","n1819849105","n1819849033","n1819849176","n1819849099","n1819849086","n1819848960","n1819848961","n1819849001","n1819848980","n1819849038","n1819848854","n1819849127","n1819849170","n1819849139","n1819848873","n1819848929","n1819849201","n1819849121","n1819849031","n1819849131","n1819848875","n1819849080","n1819849066","n1819849081","n1819849096","n1819849172","n1819849114","n1819849182","n1819848905","n1819849054","n1819848920","n1819848851","n1819848968","n1819848917","n1819849111","n1819849119","n1819849074","n1819848893","n1819849129","n1819848850","n1819848956","n1819849154","n1819848877","n1819848986","n1819849191","n1819848952","n1819848954","n1819848942","n1819849028","n1819849195","n1819848938","n1819848962","n1819849070","n1819849034","n1819849052","n1819849059","n1819848916","n1819849162","n1819849167","n1819849093","n1819849030","n1819849002","n1819849161","n1819848886","n1819848958","n1819849064","n1819849112","n1819849148","n1819848856","n1819848976","n1819848977","n1819849144","n1819848918","n1819849200","n1819848919","n1819849042","n1819849166","n1819849186","n1819849152","n1819849058","n1819849185","n1819849199","n1819849053","n1819849194","n1819849068","n1819849146","n1819849174","n1819848967","n1819848932","n1819849155","n1819849198","n1819848964","n1819848894","n1819848969","n1819849184","n1819849055","n1819849179","n1819848865","n1819848860","n1819849082","n1819848966","n1819849040","n1819849069","n1819849078","n1819849077","n1819848904","n1819848959","n1819849133","n1819849089","n1819849000","n1819849124","n1819849032","n1819849097","n1819848939","n1819849072","n1819848915","n1819849196","n1819848946","n1819849047","n1819849029","n1819849164","n1819848994","n1819849022","n1819858513","n1819849126","n1819849063","n1819848941","n1819849085","n1819848871","n1819848943","n1819849192","n1819858501","n1819849159","n1819858523","n1819848901","n1819849189","n1819858503","n1819849065","n2139877106","n1819848909","n1819848930","n1819848888"]},"w17967397":{"id":"w17967397","tags":{"highway":"residential","name":"North Andrews Street"},"nodes":["n185964963","n185985217"]},"w17964497":{"id":"w17964497","tags":{"highway":"tertiary","name":"Constantine St"},"nodes":["n185958643","n185958645","n2139795852","n185958647","n185958649","n185958651","n185958653","n185958656","n185958658","n185958660","n185958662","n185958664","n185958666","n185958668","n185958670","n185948710","n185958672"]},"w203974068":{"id":"w203974068","tags":{"highway":"footway"},"nodes":["n2139870422","n2139870423","n2139870424","n2139870425","n2139870426","n2139870427"]},"w203974063":{"id":"w203974063","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139870398","n2139870399","n2139870400","n2139870401","n2139870398"]},"w203986459":{"id":"w203986459","tags":{"amenity":"shelter","area":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139989364","n2139989366","n2139989368","n2139989370","n2139989364"]},"w203988286":{"id":"w203988286","tags":{"area":"yes","leisure":"park","name":"Memory Isle Park"},"nodes":["n2140006331","n2140006334","n2140006336","n2140006338","n2140006340","n2140006342","n2140006344","n2140006346","n2140006348","n2140006351","n2140006353","n2140006355","n2140006357","n2140006359","n2140006361","n2140006363","n2140006364","n2140006365","n2140006395","n2140006366","n2140006401","n2140006397","n2140006399","n2140006331"]},"w203974073":{"id":"w203974073","tags":{"highway":"footway"},"nodes":["n2139870453","n2139870454","n2139870455"]},"w203974064":{"id":"w203974064","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139870402","n2139870403","n2139870404","n2139870405","n2139870402"]},"n185966959":{"id":"n185966959","loc":[-85.642185,41.946411]},"n1475283980":{"id":"n1475283980","loc":[-85.6398249,41.9451425]},"n1475284013":{"id":"n1475284013","loc":[-85.6396448,41.9451666]},"n1475284042":{"id":"n1475284042","loc":[-85.6386382,41.9454789]},"n185975925":{"id":"n185975925","loc":[-85.6393332,41.9452388]},"n185975919":{"id":"n185975919","loc":[-85.6391279,41.9453044]},"n185975917":{"id":"n185975917","loc":[-85.6389034,41.9453872]},"n2140006369":{"id":"n2140006369","loc":[-85.6386163,41.9451631]},"n2140006370":{"id":"n2140006370","loc":[-85.6385144,41.9449357]},"n2140006417":{"id":"n2140006417","loc":[-85.6385785,41.9450299]},"n2140006419":{"id":"n2140006419","loc":[-85.6385781,41.9452152]},"n2189123361":{"id":"n2189123361","loc":[-85.6404948,41.947015]},"n2189123363":{"id":"n2189123363","loc":[-85.6395765,41.946495]},"n2189123365":{"id":"n2189123365","loc":[-85.6389347,41.9460875]},"n185966962":{"id":"n185966962","loc":[-85.644417,41.946364]},"n185975911":{"id":"n185975911","loc":[-85.637532,41.9458276]},"n185975913":{"id":"n185975913","loc":[-85.6376323,41.9457936]},"n185975915":{"id":"n185975915","loc":[-85.6383596,41.9455425]},"n185975932":{"id":"n185975932","loc":[-85.644403,41.945088]},"n185975934":{"id":"n185975934","loc":[-85.645486,41.945084]},"n185979974":{"id":"n185979974","loc":[-85.644381,41.943831]},"n2139795809":{"id":"n2139795809","loc":[-85.6464756,41.9450813]},"n2139795810":{"id":"n2139795810","loc":[-85.6466646,41.945174]},"n2139858952":{"id":"n2139858952","loc":[-85.6383567,41.9454039]},"n2139858953":{"id":"n2139858953","loc":[-85.6380506,41.9455301]},"n2139858954":{"id":"n2139858954","loc":[-85.6377321,41.9455546]},"n2139858955":{"id":"n2139858955","loc":[-85.6376571,41.9455245]},"n2139858956":{"id":"n2139858956","loc":[-85.6375859,41.9454544]},"n2139858957":{"id":"n2139858957","loc":[-85.6376686,41.9453185]},"n2139858958":{"id":"n2139858958","loc":[-85.6378936,41.9451712]},"n2139858959":{"id":"n2139858959","loc":[-85.6379225,41.9450825]},"n2139858960":{"id":"n2139858960","loc":[-85.6379302,41.9447564]},"n2139858961":{"id":"n2139858961","loc":[-85.6379763,41.9446963]},"n2139858962":{"id":"n2139858962","loc":[-85.6380436,41.9446706]},"n2139858963":{"id":"n2139858963","loc":[-85.6381286,41.9445969]},"n2139858965":{"id":"n2139858965","loc":[-85.6382523,41.9444134]},"n2140006367":{"id":"n2140006367","loc":[-85.6380923,41.9454418]},"n2140006368":{"id":"n2140006368","loc":[-85.6384089,41.9453146]},"n2140006372":{"id":"n2140006372","loc":[-85.6383252,41.9447706]},"n2140006374":{"id":"n2140006374","loc":[-85.6381033,41.9447436]},"n2140006376":{"id":"n2140006376","loc":[-85.6379759,41.9447815]},"n2140006378":{"id":"n2140006378","loc":[-85.6379832,41.9448654]},"n2140006380":{"id":"n2140006380","loc":[-85.6380632,41.9450738]},"n2140006382":{"id":"n2140006382","loc":[-85.6380414,41.9452064]},"n2140006389":{"id":"n2140006389","loc":[-85.6379068,41.9453092]},"n2140006391":{"id":"n2140006391","loc":[-85.637925,41.9453904]},"n2140006393":{"id":"n2140006393","loc":[-85.6379977,41.94545]},"n2189123275":{"id":"n2189123275","loc":[-85.6371346,41.9462544]},"n2189123278":{"id":"n2189123278","loc":[-85.6368371,41.9466153]},"n2189123280":{"id":"n2189123280","loc":[-85.6379537,41.9489088]},"n2189123282":{"id":"n2189123282","loc":[-85.6383816,41.9497858]},"n2189123285":{"id":"n2189123285","loc":[-85.6393673,41.9512417]},"n2189123287":{"id":"n2189123287","loc":[-85.640554,41.9517766]},"n2189123289":{"id":"n2189123289","loc":[-85.6411,41.9522344]},"n2189123291":{"id":"n2189123291","loc":[-85.6417418,41.9526574]},"n2189123293":{"id":"n2189123293","loc":[-85.642321,41.9529407]},"n2189123295":{"id":"n2189123295","loc":[-85.6427697,41.9532278]},"n2189123297":{"id":"n2189123297","loc":[-85.6433332,41.9538254]},"n2189123300":{"id":"n2189123300","loc":[-85.6435785,41.9543648]},"n2189123301":{"id":"n2189123301","loc":[-85.6444394,41.9541048]},"n2189123303":{"id":"n2189123303","loc":[-85.6450603,41.954]},"n2189123312":{"id":"n2189123312","loc":[-85.6454829,41.9539108]},"n2189123314":{"id":"n2189123314","loc":[-85.6460464,41.9538526]},"n2189123315":{"id":"n2189123315","loc":[-85.6463178,41.9537167]},"n2189123316":{"id":"n2189123316","loc":[-85.646276,41.9534141]},"n2189123317":{"id":"n2189123317","loc":[-85.6459995,41.9531541]},"n2189123318":{"id":"n2189123318","loc":[-85.645222,41.9531929]},"n2189123319":{"id":"n2189123319","loc":[-85.6447316,41.9531813]},"n2189123320":{"id":"n2189123320","loc":[-85.6440637,41.9532977]},"n2189123321":{"id":"n2189123321","loc":[-85.6438185,41.9531774]},"n2189123322":{"id":"n2189123322","loc":[-85.6440011,41.9528398]},"n2189123323":{"id":"n2189123323","loc":[-85.6442672,41.9525914]},"n2189123324":{"id":"n2189123324","loc":[-85.6442881,41.9523276]},"n2189123326":{"id":"n2189123326","loc":[-85.644262,41.952153]},"n2189123328":{"id":"n2189123328","loc":[-85.6441681,41.9520404]},"n2189123330":{"id":"n2189123330","loc":[-85.6442098,41.9517494]},"n2189123333":{"id":"n2189123333","loc":[-85.6438498,41.9515864]},"n2189123336":{"id":"n2189123336","loc":[-85.6435889,41.9513225]},"n2189123339":{"id":"n2189123339","loc":[-85.6425349,41.9510315]},"n2189123342":{"id":"n2189123342","loc":[-85.6422688,41.9508802]},"n2189123345":{"id":"n2189123345","loc":[-85.6418775,41.9508142]},"n2189123348":{"id":"n2189123348","loc":[-85.6415488,41.9508064]},"n2189123351":{"id":"n2189123351","loc":[-85.6411027,41.9505488]},"n2189123353":{"id":"n2189123353","loc":[-85.6410374,41.9498208]},"n2189123355":{"id":"n2189123355","loc":[-85.6410061,41.9494327]},"n2189123357":{"id":"n2189123357","loc":[-85.6411522,41.9482569]},"n2189123359":{"id":"n2189123359","loc":[-85.6410548,41.9473036]},"n2189123368":{"id":"n2189123368","loc":[-85.6380216,41.9458974]},"n2189123370":{"id":"n2189123370","loc":[-85.6386721,41.9507782]},"w17968193":{"id":"w17968193","tags":{"highway":"residential","name":"French St"},"nodes":["n185970906","n185982877","n185967774","n185985823","n185979974"]},"w203972939":{"id":"w203972939","tags":{"highway":"path"},"nodes":["n2139858965","n2139858966"]},"w203988289":{"id":"w203988289","tags":{"area":"yes","natural":"water"},"nodes":["n2140006367","n2140006368","n2140006419","n2140006369","n2140006417","n2140006370","n2140006372","n2140006374","n2140006376","n2140006378","n2140006380","n2140006382","n2140006389","n2140006391","n2140006393","n2140006367"]},"w208640157":{"id":"w208640157","tags":{"area":"yes","natural":"wetland"},"nodes":["n1819849029","n2189123275","n2189123278","n2189123280","n2189123282","n2189123370","n2189123285","n2189123287","n2189123289","n2189123291","n2189123293","n2189123295","n2189123297","n2189123300","n2189123301","n2189123303","n2189123312","n2189123314","n2189123315","n2189123316","n2189123317","n2189123318","n2189123319","n2189123320","n2189123321","n2189123322","n2189123323","n2189123324","n2189123326","n2189123328","n2189123330","n2189123333","n2189123336","n2189123339","n2189123342","n2189123345","n2189123348","n2189123351","n2189123353","n2189123355","n2189123357","n2189123359","n2189123361","n2189123363","n2189123365","n2189123368","n1819849029"]},"w17966281":{"id":"w17966281","tags":{"highway":"residential","name":"Pealer St"},"nodes":["n185975911","n185975913","n185975915","n1475284042","n185975917","n185975919","n185975925","n185970909","n1475284013","n1475283980","n185975928","n185967775","n185975930","n185975932","n185975934","n2139795809","n2139795810"]},"w17965353":{"id":"w17965353","tags":{"highway":"residential","name":"Yauney St"},"nodes":["n185966958","n185966959","n185966960","n185966962"]},"w203972938":{"id":"w203972938","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139858964","n2139858965","n2139858963","n2139858962","n2139858961","n2139858960","n2139858959","n2139858958","n2139858957","n2139858956","n2139858955","n2139858954","n2139858953","n2139858952","n2139858951"]},"n354002665":{"id":"n354002665","loc":[-85.6366599,41.9444923],"tags":{"name":"Memory Isle","place":"island"}},"n354031301":{"id":"n354031301","loc":[-85.635,41.9463889],"tags":{"amenity":"post_office","name":"Three Rivers Post Office"}},"n185963454":{"id":"n185963454","loc":[-85.633686,41.946072]},"n185963455":{"id":"n185963455","loc":[-85.633815,41.946131]},"n185963456":{"id":"n185963456","loc":[-85.633951,41.946174]},"n185978375":{"id":"n185978375","loc":[-85.634385,41.94559]},"n185978377":{"id":"n185978377","loc":[-85.634544,41.945725]},"n185978379":{"id":"n185978379","loc":[-85.634573,41.945764]},"n185978381":{"id":"n185978381","loc":[-85.634616,41.945849]},"n185978383":{"id":"n185978383","loc":[-85.634629,41.945893]},"n185984011":{"id":"n185984011","loc":[-85.636058,41.946201]},"n185984013":{"id":"n185984013","loc":[-85.636112,41.946366]},"n185984015":{"id":"n185984015","loc":[-85.636143,41.946551]},"n185988237":{"id":"n185988237","loc":[-85.6354162,41.946044]},"n185988969":{"id":"n185988969","loc":[-85.635374,41.945325]},"n185988971":{"id":"n185988971","loc":[-85.635643,41.945585]},"n185988972":{"id":"n185988972","loc":[-85.635853,41.94586]},"n1475283992":{"id":"n1475283992","loc":[-85.6372968,41.9459007]},"n1475284011":{"id":"n1475284011","loc":[-85.6359415,41.9459797]},"n1475284019":{"id":"n1475284019","loc":[-85.6364433,41.9460423]},"n185984009":{"id":"n185984009","loc":[-85.6360524,41.9460485]},"n185988239":{"id":"n185988239","loc":[-85.6358187,41.9460423]},"n185988243":{"id":"n185988243","loc":[-85.6366156,41.9460282]},"n185988244":{"id":"n185988244","loc":[-85.6368316,41.9460046]},"n185988245":{"id":"n185988245","loc":[-85.6370133,41.9459704]},"n185988241":{"id":"n185988241","loc":[-85.636291,41.9460461]},"n185964976":{"id":"n185964976","loc":[-85.633923,41.9434157]},"n185964980":{"id":"n185964980","loc":[-85.6333656,41.9437293]},"n185978388":{"id":"n185978388","loc":[-85.6346449,41.9460571]},"n1819858504":{"id":"n1819858504","loc":[-85.6365343,41.9447926]},"n1819858506":{"id":"n1819858506","loc":[-85.6370546,41.9451882]},"n1819858516":{"id":"n1819858516","loc":[-85.6358369,41.9444654]},"n1819858519":{"id":"n1819858519","loc":[-85.6361534,41.9446176]},"n1819858525":{"id":"n1819858525","loc":[-85.6368025,41.9449442]},"n1819858527":{"id":"n1819858527","loc":[-85.6334199,41.9457495]},"n185963452":{"id":"n185963452","loc":[-85.633564,41.9458519]},"n185963453":{"id":"n185963453","loc":[-85.6336152,41.9459804]},"n185963451":{"id":"n185963451","loc":[-85.6332888,41.9456871]},"n2130304152":{"id":"n2130304152","loc":[-85.6359466,41.9454599]},"n2130304153":{"id":"n2130304153","loc":[-85.6362773,41.9452683]},"n2130304154":{"id":"n2130304154","loc":[-85.6352028,41.9442868]},"n2130304155":{"id":"n2130304155","loc":[-85.6348756,41.9444769]},"n2130304156":{"id":"n2130304156","loc":[-85.6349723,41.9444207]},"n2130304157":{"id":"n2130304157","loc":[-85.6338698,41.9434443]},"n2130304158":{"id":"n2130304158","loc":[-85.635094,41.9451026]},"n2130304160":{"id":"n2130304160","loc":[-85.6353716,41.9449322]},"n2130304162":{"id":"n2130304162","loc":[-85.6365942,41.9459352]},"n2130304163":{"id":"n2130304163","loc":[-85.6369006,41.9457469]},"n2130304164":{"id":"n2130304164","loc":[-85.6363292,41.9452278]},"n2130304165":{"id":"n2130304165","loc":[-85.6360248,41.9454175]},"n2139824683":{"id":"n2139824683","loc":[-85.6339825,41.9446441]},"n2139824689":{"id":"n2139824689","loc":[-85.6340437,41.9446925]},"n2139824702":{"id":"n2139824702","loc":[-85.6340961,41.9447551]},"n2139824705":{"id":"n2139824705","loc":[-85.6337467,41.944809]},"n2139824707":{"id":"n2139824707","loc":[-85.6341598,41.9448129]},"n2139824710":{"id":"n2139824710","loc":[-85.6342771,41.9448223]},"n2139824712":{"id":"n2139824712","loc":[-85.6346058,41.944841]},"n2139824713":{"id":"n2139824713","loc":[-85.633808,41.9448574]},"n2139824714":{"id":"n2139824714","loc":[-85.6340889,41.9448589]},"n2139824716":{"id":"n2139824716","loc":[-85.6343335,41.944871]},"n2139824717":{"id":"n2139824717","loc":[-85.6343341,41.9448717]},"n2139824720":{"id":"n2139824720","loc":[-85.6338757,41.9449069]},"n2139824721":{"id":"n2139824721","loc":[-85.6341445,41.9449071]},"n2139824724":{"id":"n2139824724","loc":[-85.6334787,41.9449262]},"n2139824726":{"id":"n2139824726","loc":[-85.6347119,41.9449332]},"n2139824727":{"id":"n2139824727","loc":[-85.6347175,41.9449418]},"n2139824728":{"id":"n2139824728","loc":[-85.6344284,41.9449538]},"n2139824729":{"id":"n2139824729","loc":[-85.6339339,41.9449573]},"n2139824730":{"id":"n2139824730","loc":[-85.6339179,41.9449682]},"n2139824732":{"id":"n2139824732","loc":[-85.6335472,41.9449895]},"n2139824733":{"id":"n2139824733","loc":[-85.6339736,41.9450164]},"n2139824735":{"id":"n2139824735","loc":[-85.6336034,41.9450415]},"n2139824736":{"id":"n2139824736","loc":[-85.6348317,41.945043]},"n2139824737":{"id":"n2139824737","loc":[-85.63403,41.9450651]},"n2139824738":{"id":"n2139824738","loc":[-85.6336611,41.9450949]},"n2139824740":{"id":"n2139824740","loc":[-85.6336582,41.9450966]},"n2139824744":{"id":"n2139824744","loc":[-85.6331702,41.9451107]},"n2139824745":{"id":"n2139824745","loc":[-85.6333388,41.9451142]},"n2139824746":{"id":"n2139824746","loc":[-85.6337131,41.9451341]},"n2139824747":{"id":"n2139824747","loc":[-85.6337021,41.9451372]},"n2139824748":{"id":"n2139824748","loc":[-85.6341244,41.9451472]},"n2139824749":{"id":"n2139824749","loc":[-85.6333952,41.945166]},"n2139824750":{"id":"n2139824750","loc":[-85.633395,41.9451661]},"n2139824751":{"id":"n2139824751","loc":[-85.6346258,41.9451725]},"n2139824752":{"id":"n2139824752","loc":[-85.6332387,41.9451741]},"n2139824753":{"id":"n2139824753","loc":[-85.6346901,41.9451853]},"n2139824754":{"id":"n2139824754","loc":[-85.6346611,41.9452035]},"n2139824755":{"id":"n2139824755","loc":[-85.6346574,41.9452059]},"n2139824756":{"id":"n2139824756","loc":[-85.6345611,41.9452133]},"n2139824757":{"id":"n2139824757","loc":[-85.633453,41.9452194]},"n2139824758":{"id":"n2139824758","loc":[-85.6335508,41.9452283]},"n2139824759":{"id":"n2139824759","loc":[-85.6347424,41.9452312]},"n2139824760":{"id":"n2139824760","loc":[-85.6342305,41.9452395]},"n2139824761":{"id":"n2139824761","loc":[-85.6342319,41.9452449]},"n2139824762":{"id":"n2139824762","loc":[-85.6334969,41.94526]},"n2139824763":{"id":"n2139824763","loc":[-85.63468,41.9452706]},"n2139824764":{"id":"n2139824764","loc":[-85.6346772,41.9452724]},"n2139824765":{"id":"n2139824765","loc":[-85.6338611,41.9452763]},"n2139824766":{"id":"n2139824766","loc":[-85.6347811,41.9452939]},"n2139824767":{"id":"n2139824767","loc":[-85.6347375,41.9453211]},"n2139824768":{"id":"n2139824768","loc":[-85.6339171,41.9453301]},"n2139824769":{"id":"n2139824769","loc":[-85.6348307,41.9453377]},"n2139824770":{"id":"n2139824770","loc":[-85.6347067,41.9453405]},"n2139824771":{"id":"n2139824771","loc":[-85.6343461,41.9453461]},"n2139824772":{"id":"n2139824772","loc":[-85.6343481,41.9453475]},"n2139824773":{"id":"n2139824773","loc":[-85.634805,41.9453538]},"n2139824774":{"id":"n2139824774","loc":[-85.6336997,41.9453692]},"n2139824775":{"id":"n2139824775","loc":[-85.6339709,41.9453818]},"n2139824776":{"id":"n2139824776","loc":[-85.6336229,41.9454134]},"n2139824777":{"id":"n2139824777","loc":[-85.6349022,41.9454141]},"n2139824778":{"id":"n2139824778","loc":[-85.6348854,41.9454246]},"n2139824779":{"id":"n2139824779","loc":[-85.6340286,41.9454373]},"n2139824780":{"id":"n2139824780","loc":[-85.6336963,41.9454572]},"n2139824781":{"id":"n2139824781","loc":[-85.6336789,41.9454672]},"n2139824782":{"id":"n2139824782","loc":[-85.6344933,41.945475]},"n2139824783":{"id":"n2139824783","loc":[-85.6340854,41.9454918]},"n2139824784":{"id":"n2139824784","loc":[-85.6350036,41.9455034]},"n2139824785":{"id":"n2139824785","loc":[-85.6337501,41.9455089]},"n2139824786":{"id":"n2139824786","loc":[-85.6337497,41.9455091]},"n2139824787":{"id":"n2139824787","loc":[-85.6345425,41.9455186]},"n2139824788":{"id":"n2139824788","loc":[-85.6341459,41.9455372]},"n2139824789":{"id":"n2139824789","loc":[-85.6341376,41.945542]},"n2139824790":{"id":"n2139824790","loc":[-85.6338394,41.9455462]},"n2139824791":{"id":"n2139824791","loc":[-85.6349171,41.9455588]},"n2139824792":{"id":"n2139824792","loc":[-85.6338074,41.9455646]},"n2139824793":{"id":"n2139824793","loc":[-85.6346229,41.9455894]},"n2139824794":{"id":"n2139824794","loc":[-85.6338983,41.9455995]},"n2139824795":{"id":"n2139824795","loc":[-85.6338962,41.9456007]},"n2139824796":{"id":"n2139824796","loc":[-85.6342475,41.9456348]},"n2139824797":{"id":"n2139824797","loc":[-85.6339505,41.9456497]},"n2139824798":{"id":"n2139824798","loc":[-85.6347243,41.9456788]},"n2139824799":{"id":"n2139824799","loc":[-85.635057,41.9456831]},"n2139824800":{"id":"n2139824800","loc":[-85.635287,41.9457056]},"n2139824801":{"id":"n2139824801","loc":[-85.6350753,41.9457068]},"n2139824802":{"id":"n2139824802","loc":[-85.6347753,41.9457252]},"n2139824803":{"id":"n2139824803","loc":[-85.6340521,41.9457473]},"n2139824804":{"id":"n2139824804","loc":[-85.6352875,41.9457611]},"n2139824805":{"id":"n2139824805","loc":[-85.6352941,41.9457611]},"n2139824806":{"id":"n2139824806","loc":[-85.6350758,41.9457623]},"n2139824807":{"id":"n2139824807","loc":[-85.6348194,41.9457638]},"n2139824808":{"id":"n2139824808","loc":[-85.635296,41.9459428]},"n2139824809":{"id":"n2139824809","loc":[-85.6348212,41.9459455]},"n2139832635":{"id":"n2139832635","loc":[-85.6354612,41.9448791]},"n2139832636":{"id":"n2139832636","loc":[-85.6360241,41.9453844]},"n2139832637":{"id":"n2139832637","loc":[-85.6361452,41.9453121]},"n2139832639":{"id":"n2139832639","loc":[-85.6355997,41.944797]},"n2139832641":{"id":"n2139832641","loc":[-85.6351346,41.9443541]},"n2139832647":{"id":"n2139832647","loc":[-85.6329883,41.9453692]},"n2139832653":{"id":"n2139832653","loc":[-85.6333643,41.9456293]},"n2139832663":{"id":"n2139832663","loc":[-85.6335394,41.9455339]},"n2139832665":{"id":"n2139832665","loc":[-85.6332375,41.9452476]},"n2139832667":{"id":"n2139832667","loc":[-85.6331664,41.9452161]},"n2139832669":{"id":"n2139832669","loc":[-85.6331144,41.9451875]},"n2139832671":{"id":"n2139832671","loc":[-85.6330779,41.9451274]},"n2139832673":{"id":"n2139832673","loc":[-85.6330664,41.9450802]},"n2139832678":{"id":"n2139832678","loc":[-85.6332218,41.9453585]},"n2139832686":{"id":"n2139832686","loc":[-85.6334246,41.945541]},"n2139832691":{"id":"n2139832691","loc":[-85.6329898,41.9454997]},"n2139832693":{"id":"n2139832693","loc":[-85.6343554,41.9443274]},"n2139832694":{"id":"n2139832694","loc":[-85.6336339,41.9437089]},"n2139832696":{"id":"n2139832696","loc":[-85.633532,41.9437708]},"n2139832697":{"id":"n2139832697","loc":[-85.6338316,41.9440868]},"n2139832698":{"id":"n2139832698","loc":[-85.6342258,41.9444141]},"n2139832699":{"id":"n2139832699","loc":[-85.6339164,41.9442166]},"n2139832700":{"id":"n2139832700","loc":[-85.6341389,41.944384]},"n2139832701":{"id":"n2139832701","loc":[-85.634235,41.9443259]},"n2139832702":{"id":"n2139832702","loc":[-85.633613,41.9437875]},"n2139832703":{"id":"n2139832703","loc":[-85.633915,41.9436132]},"n2139832704":{"id":"n2139832704","loc":[-85.6340019,41.9435613]},"n2139832706":{"id":"n2139832706","loc":[-85.6343197,41.9438427]},"n2139832708":{"id":"n2139832708","loc":[-85.6342361,41.9438936]},"n2139832709":{"id":"n2139832709","loc":[-85.6353839,41.9460401]},"n2139832710":{"id":"n2139832710","loc":[-85.6354032,41.9456763]},"n2139832711":{"id":"n2139832711","loc":[-85.6356839,41.9459252]},"n2139832712":{"id":"n2139832712","loc":[-85.6356109,41.945735]},"n2139832713":{"id":"n2139832713","loc":[-85.6353997,41.9457421]},"n2139832714":{"id":"n2139832714","loc":[-85.6353895,41.9459347]},"n2139832715":{"id":"n2139832715","loc":[-85.6334777,41.9436628]},"n2139832716":{"id":"n2139832716","loc":[-85.6333137,41.9435382]},"n2139832717":{"id":"n2139832717","loc":[-85.6330938,41.9435406]},"n2139832721":{"id":"n2139832721","loc":[-85.6333023,41.9434922]},"n2139832722":{"id":"n2139832722","loc":[-85.6330466,41.943623]},"n2139832723":{"id":"n2139832723","loc":[-85.6332746,41.9435624]},"n2139832724":{"id":"n2139832724","loc":[-85.6333511,41.9435176]},"n2139832725":{"id":"n2139832725","loc":[-85.6332241,41.9434001]},"n2139832726":{"id":"n2139832726","loc":[-85.6332355,41.9433686]},"n2139870373":{"id":"n2139870373","loc":[-85.6351783,41.9439117]},"n2139870374":{"id":"n2139870374","loc":[-85.6351431,41.9439217]},"n2139870375":{"id":"n2139870375","loc":[-85.6348853,41.9439117]},"n2139870376":{"id":"n2139870376","loc":[-85.6348317,41.9439105]},"n2139870377":{"id":"n2139870377","loc":[-85.6346384,41.944007]},"n2139870378":{"id":"n2139870378","loc":[-85.6345563,41.9440523]},"n2140006403":{"id":"n2140006403","loc":[-85.6359942,41.9450097]},"n2140006405":{"id":"n2140006405","loc":[-85.6363884,41.9446079]},"n2140006407":{"id":"n2140006407","loc":[-85.6362148,41.9447874]},"n2140006409":{"id":"n2140006409","loc":[-85.6379476,41.9445869]},"n2140006411":{"id":"n2140006411","loc":[-85.6378485,41.9445674]},"n2140006413":{"id":"n2140006413","loc":[-85.6378952,41.9444547]},"n2140006415":{"id":"n2140006415","loc":[-85.6379962,41.944477]},"n2140006421":{"id":"n2140006421","loc":[-85.6355248,41.9433702]},"n2140006423":{"id":"n2140006423","loc":[-85.6378471,41.9439233]},"n2140006425":{"id":"n2140006425","loc":[-85.6378913,41.9441238]},"n2140006426":{"id":"n2140006426","loc":[-85.6381674,41.9442289]},"n2140006427":{"id":"n2140006427","loc":[-85.6382359,41.9440975]},"n2140006428":{"id":"n2140006428","loc":[-85.6382071,41.9440252]},"n2140006429":{"id":"n2140006429","loc":[-85.6381409,41.9439973]},"n2140006430":{"id":"n2140006430","loc":[-85.6380569,41.9440153]},"n2140006433":{"id":"n2140006433","loc":[-85.6379071,41.9442467]},"n2140006435":{"id":"n2140006435","loc":[-85.6381634,41.9443125]},"n2140006436":{"id":"n2140006436","loc":[-85.6382407,41.944301]},"n2140006438":{"id":"n2140006438","loc":[-85.6382761,41.9442188]},"n2140006439":{"id":"n2140006439","loc":[-85.6382429,41.9441761]},"n2140006440":{"id":"n2140006440","loc":[-85.6382016,41.9441632]},"n2140006441":{"id":"n2140006441","loc":[-85.6378185,41.9439835]},"n2166205688":{"id":"n2166205688","loc":[-85.6349963,41.9444392]},"n2168544780":{"id":"n2168544780","loc":[-85.633944,41.945807]},"n2168544781":{"id":"n2168544781","loc":[-85.6340783,41.9458621]},"n2168544782":{"id":"n2168544782","loc":[-85.6338184,41.9457548]},"n2168544783":{"id":"n2168544783","loc":[-85.6339925,41.9459777]},"n2168544784":{"id":"n2168544784","loc":[-85.6337317,41.9458698]},"n2168544785":{"id":"n2168544785","loc":[-85.6337297,41.9460042]},"n2168544786":{"id":"n2168544786","loc":[-85.633919,41.9460797]},"n2168544787":{"id":"n2168544787","loc":[-85.6338672,41.9459263]},"n2168544788":{"id":"n2168544788","loc":[-85.6338246,41.9459853]},"n2168544789":{"id":"n2168544789","loc":[-85.6337615,41.9459601]},"n2168544790":{"id":"n2168544790","loc":[-85.6342079,41.9460399]},"n2168544791":{"id":"n2168544791","loc":[-85.6343346,41.9458503]},"n2168544792":{"id":"n2168544792","loc":[-85.6343759,41.9458116]},"n2168544793":{"id":"n2168544793","loc":[-85.6344394,41.9458109]},"n2168544795":{"id":"n2168544795","loc":[-85.6344827,41.945851]},"n2168544797":{"id":"n2168544797","loc":[-85.6344807,41.945969]},"n2168544798":{"id":"n2168544798","loc":[-85.6344404,41.9459697]},"n2168544799":{"id":"n2168544799","loc":[-85.6344413,41.9460333]},"n2168544800":{"id":"n2168544800","loc":[-85.6342173,41.9460705]},"n2168544801":{"id":"n2168544801","loc":[-85.6342162,41.9460392]},"n2168544802":{"id":"n2168544802","loc":[-85.6344251,41.9460351]},"n2168544805":{"id":"n2168544805","loc":[-85.6344257,41.9460507]},"n2168544807":{"id":"n2168544807","loc":[-85.6344721,41.9460498]},"n2168544809":{"id":"n2168544809","loc":[-85.6344754,41.9461427]},"n2168544811":{"id":"n2168544811","loc":[-85.6344311,41.9461435]},"n2168544813":{"id":"n2168544813","loc":[-85.6344317,41.9461592]},"n2168544815":{"id":"n2168544815","loc":[-85.6343708,41.9461604]},"n2168544817":{"id":"n2168544817","loc":[-85.6343715,41.9461786]},"n2168544819":{"id":"n2168544819","loc":[-85.6343229,41.9461795]},"n2168544821":{"id":"n2168544821","loc":[-85.6343222,41.9461606]},"n2168544823":{"id":"n2168544823","loc":[-85.6342476,41.9461621]},"n2168544825":{"id":"n2168544825","loc":[-85.6342444,41.94607]},"n2168544827":{"id":"n2168544827","loc":[-85.634138,41.9461632]},"n2168544829":{"id":"n2168544829","loc":[-85.6342016,41.9460703]},"n2168544830":{"id":"n2168544830","loc":[-85.6332929,41.9463092]},"n2168544831":{"id":"n2168544831","loc":[-85.633122,41.946239]},"n2168544832":{"id":"n2168544832","loc":[-85.6332954,41.9460055]},"n2168544833":{"id":"n2168544833","loc":[-85.6333954,41.9460466]},"n2168544834":{"id":"n2168544834","loc":[-85.6334044,41.9460345]},"n2168544835":{"id":"n2168544835","loc":[-85.6334594,41.9460571]},"n2168544836":{"id":"n2168544836","loc":[-85.6333871,41.9461544]},"n2168544837":{"id":"n2168544837","loc":[-85.633403,41.9461609]},"n2168544838":{"id":"n2168544838","loc":[-85.6341683,41.9464167]},"n2168544839":{"id":"n2168544839","loc":[-85.6341711,41.9463411]},"n2168544840":{"id":"n2168544840","loc":[-85.6344471,41.9463469]},"n2168544841":{"id":"n2168544841","loc":[-85.6344441,41.9464243]},"n2168544842":{"id":"n2168544842","loc":[-85.6343622,41.9464226]},"n2168544843":{"id":"n2168544843","loc":[-85.6343593,41.9464989]},"n2168544844":{"id":"n2168544844","loc":[-85.6342812,41.9464973]},"n2168544845":{"id":"n2168544845","loc":[-85.634283,41.9464504]},"n2168544846":{"id":"n2168544846","loc":[-85.6342609,41.9464499]},"n2168544847":{"id":"n2168544847","loc":[-85.6342621,41.9464187]},"n2168544848":{"id":"n2168544848","loc":[-85.6348414,41.9463396]},"n2168544849":{"id":"n2168544849","loc":[-85.6348387,41.9461872]},"n2168544850":{"id":"n2168544850","loc":[-85.6351186,41.9461844]},"n2168544851":{"id":"n2168544851","loc":[-85.635119,41.9462112]},"n2168544852":{"id":"n2168544852","loc":[-85.6351918,41.9462104]},"n2168544853":{"id":"n2168544853","loc":[-85.6351944,41.9463515]},"n2168544854":{"id":"n2168544854","loc":[-85.6351049,41.9463524]},"n2168544855":{"id":"n2168544855","loc":[-85.6351046,41.946337]},"n2189153180":{"id":"n2189153180","loc":[-85.6340369,41.9469572]},"n2189153181":{"id":"n2189153181","loc":[-85.6342531,41.946953]},"n2189153183":{"id":"n2189153183","loc":[-85.6348115,41.9465468]},"n2189153184":{"id":"n2189153184","loc":[-85.6348105,41.9464569]},"n2189153185":{"id":"n2189153185","loc":[-85.6351431,41.9464549]},"n2189153186":{"id":"n2189153186","loc":[-85.6351441,41.9465448]},"n2189153187":{"id":"n2189153187","loc":[-85.6350077,41.9465456]},"n2189153188":{"id":"n2189153188","loc":[-85.635008,41.9465721]},"n2189153189":{"id":"n2189153189","loc":[-85.6348965,41.9465727]},"n2189153190":{"id":"n2189153190","loc":[-85.6348962,41.9465463]},"n2189153191":{"id":"n2189153191","loc":[-85.6348963,41.9471586]},"n2189153192":{"id":"n2189153192","loc":[-85.6348944,41.947032]},"n2189153193":{"id":"n2189153193","loc":[-85.6350241,41.947031]},"n2189153194":{"id":"n2189153194","loc":[-85.635026,41.9471575]},"n2189153195":{"id":"n2189153195","loc":[-85.6352328,41.9471053]},"n2189153196":{"id":"n2189153196","loc":[-85.6352359,41.9469906]},"n2189153197":{"id":"n2189153197","loc":[-85.6353694,41.9469925]},"n2189153198":{"id":"n2189153198","loc":[-85.6353664,41.9471072]},"n2189153199":{"id":"n2189153199","loc":[-85.6348241,41.9469287]},"n2189153200":{"id":"n2189153200","loc":[-85.6348248,41.9468185]},"n2189153201":{"id":"n2189153201","loc":[-85.6351199,41.9468195]},"n2189153202":{"id":"n2189153202","loc":[-85.6351192,41.9469298]},"n2189153203":{"id":"n2189153203","loc":[-85.6347965,41.9468057]},"n2189153204":{"id":"n2189153204","loc":[-85.634792,41.9466044]},"n2189153205":{"id":"n2189153205","loc":[-85.6349483,41.9466025]},"n2189153206":{"id":"n2189153206","loc":[-85.6349493,41.9466448]},"n2189153207":{"id":"n2189153207","loc":[-85.6349753,41.9466445]},"n2189153208":{"id":"n2189153208","loc":[-85.6349743,41.9465995]},"n2189153209":{"id":"n2189153209","loc":[-85.6351173,41.9465977]},"n2189153210":{"id":"n2189153210","loc":[-85.6351219,41.9468015]},"n2189153211":{"id":"n2189153211","loc":[-85.6349806,41.9468032]},"n2189153212":{"id":"n2189153212","loc":[-85.6349794,41.9467519]},"n2189153213":{"id":"n2189153213","loc":[-85.6349521,41.9467523]},"n2189153214":{"id":"n2189153214","loc":[-85.6349532,41.9468037]},"n2189153215":{"id":"n2189153215","loc":[-85.6346302,41.9468381]},"n2189153216":{"id":"n2189153216","loc":[-85.6343028,41.9468449]},"n2189153217":{"id":"n2189153217","loc":[-85.6342006,41.9468297]},"n2189153218":{"id":"n2189153218","loc":[-85.6336698,41.9465918]},"n2189153219":{"id":"n2189153219","loc":[-85.6344663,41.9466639]},"n2189153220":{"id":"n2189153220","loc":[-85.6344639,41.9466015]},"n2189153221":{"id":"n2189153221","loc":[-85.6342283,41.9466065]},"n2189153222":{"id":"n2189153222","loc":[-85.6342303,41.9466587]},"n2189153223":{"id":"n2189153223","loc":[-85.6342843,41.9466575]},"n2189153224":{"id":"n2189153224","loc":[-85.6342851,41.9466794]},"n2189153225":{"id":"n2189153225","loc":[-85.6343475,41.9466781]},"n2189153226":{"id":"n2189153226","loc":[-85.634347,41.9466664]},"n2189153227":{"id":"n2189153227","loc":[-85.6354428,41.9470148]},"n2189153228":{"id":"n2189153228","loc":[-85.6354432,41.9468005]},"n2189153229":{"id":"n2189153229","loc":[-85.6360277,41.9468011]},"n2189153230":{"id":"n2189153230","loc":[-85.6360273,41.9470154]},"n2189153231":{"id":"n2189153231","loc":[-85.6354565,41.9465823]},"n2189153232":{"id":"n2189153232","loc":[-85.6354496,41.946218]},"n2189153233":{"id":"n2189153233","loc":[-85.6356355,41.9465788]},"n2189153234":{"id":"n2189153234","loc":[-85.6357155,41.9468008]},"n2189153235":{"id":"n2189153235","loc":[-85.6359539,41.9467969]},"n2189153236":{"id":"n2189153236","loc":[-85.6359561,41.9463036]},"n2189153237":{"id":"n2189153237","loc":[-85.6360129,41.9464793]},"n2189153238":{"id":"n2189153238","loc":[-85.6360152,41.9463898]},"n2189153239":{"id":"n2189153239","loc":[-85.6359607,41.9464928]},"n2189153240":{"id":"n2189153240","loc":[-85.6356903,41.9462227]},"n2189153242":{"id":"n2189153242","loc":[-85.6354163,41.946142]},"n2189153243":{"id":"n2189153243","loc":[-85.6357546,41.9462214]},"n2189153244":{"id":"n2189153244","loc":[-85.6357937,41.9462542]},"n2189153245":{"id":"n2189153245","loc":[-85.6358723,41.9467048]},"n2189153246":{"id":"n2189153246","loc":[-85.6361494,41.946757]},"n2189153247":{"id":"n2189153247","loc":[-85.6354173,41.9469082]},"n2189153248":{"id":"n2189153248","loc":[-85.635443,41.9469079]},"n2189153249":{"id":"n2189153249","loc":[-85.6360275,41.9469093]},"n2189153250":{"id":"n2189153250","loc":[-85.6361542,41.946915]},"n2189153251":{"id":"n2189153251","loc":[-85.6358654,41.9464843]},"n2189153252":{"id":"n2189153252","loc":[-85.6359549,41.9467499]},"n2189153253":{"id":"n2189153253","loc":[-85.6357172,41.9466335]},"n2189153254":{"id":"n2189153254","loc":[-85.6355644,41.9461768]},"n2189153255":{"id":"n2189153255","loc":[-85.6355655,41.946528]},"n2189153256":{"id":"n2189153256","loc":[-85.6357055,41.9465971]},"n2189153257":{"id":"n2189153257","loc":[-85.635869,41.9465971]},"n2189153259":{"id":"n2189153259","loc":[-85.6354561,41.9470278]},"n2189153260":{"id":"n2189153260","loc":[-85.6357961,41.9470233]},"n2189153261":{"id":"n2189153261","loc":[-85.6357977,41.9470907]},"n2189153262":{"id":"n2189153262","loc":[-85.6357297,41.9470916]},"n2189153263":{"id":"n2189153263","loc":[-85.635733,41.947233]},"n2189153264":{"id":"n2189153264","loc":[-85.6362674,41.9468637]},"n2189153265":{"id":"n2189153265","loc":[-85.6362646,41.9467047]},"n2189153266":{"id":"n2189153266","loc":[-85.6363267,41.9467047]},"n2189153267":{"id":"n2189153267","loc":[-85.6362633,41.9465848]},"n2189153268":{"id":"n2189153268","loc":[-85.6363805,41.9465468]},"n2189153269":{"id":"n2189153269","loc":[-85.6364604,41.9466842]},"n2189153270":{"id":"n2189153270","loc":[-85.6364604,41.9468647]},"n2199109756":{"id":"n2199109756","loc":[-85.6337134,41.9471841]},"n2199109757":{"id":"n2199109757","loc":[-85.6336514,41.94716]},"n2199109758":{"id":"n2199109758","loc":[-85.6337043,41.9470847]},"n2199109759":{"id":"n2199109759","loc":[-85.6335997,41.9470441]},"n2199109760":{"id":"n2199109760","loc":[-85.6335064,41.9471771]},"n185960195":{"id":"n185960195","loc":[-85.6295992,41.9524346]},"n185960796":{"id":"n185960796","loc":[-85.634723,41.953681]},"n185961396":{"id":"n185961396","loc":[-85.634767,41.959009]},"n185962625":{"id":"n185962625","loc":[-85.635175,41.97201]},"n185964982":{"id":"n185964982","loc":[-85.632799,41.9440543]},"n185965289":{"id":"n185965289","loc":[-85.634621,41.947323]},"n185965291":{"id":"n185965291","loc":[-85.636166,41.947296]},"n185965399":{"id":"n185965399","loc":[-85.634776,41.959834]},"n185966937":{"id":"n185966937","loc":[-85.633183,41.947315]},"n185966948":{"id":"n185966948","loc":[-85.626406,41.957188]},"n185967422":{"id":"n185967422","loc":[-85.6320229,41.9490123]},"n185967917":{"id":"n185967917","loc":[-85.634763,41.958292]},"n185967918":{"id":"n185967918","loc":[-85.636271,41.958311]},"n185968100":{"id":"n185968100","loc":[-85.630835,41.950656]},"n185970515":{"id":"n185970515","loc":[-85.634832,41.963866]},"n185971578":{"id":"n185971578","loc":[-85.634641,41.948627]},"n185971580":{"id":"n185971580","loc":[-85.6361818,41.9486135]},"n185971631":{"id":"n185971631","loc":[-85.634729,41.954667]},"n185971632":{"id":"n185971632","loc":[-85.636236,41.954656]},"n185972155":{"id":"n185972155","loc":[-85.623333,41.961987]},"n185974583":{"id":"n185974583","loc":[-85.634686,41.951158]},"n185974585":{"id":"n185974585","loc":[-85.6362059,41.9511457]},"n185975064":{"id":"n185975064","loc":[-85.636218,41.953667]},"n185975735":{"id":"n185975735","loc":[-85.634923,41.969269]},"n185978390":{"id":"n185978390","loc":[-85.634668,41.949875]},"n185978392":{"id":"n185978392","loc":[-85.634686,41.952415]},"n185978394":{"id":"n185978394","loc":[-85.634726,41.955921]},"n185978399":{"id":"n185978399","loc":[-85.6347861,41.9606613]},"n185978402":{"id":"n185978402","loc":[-85.634806,41.961485]},"n185978406":{"id":"n185978406","loc":[-85.6348298,41.964783]},"n185978410":{"id":"n185978410","loc":[-85.6348766,41.9677088]},"n185978414":{"id":"n185978414","loc":[-85.634938,41.971566]},"n185978415":{"id":"n185978415","loc":[-85.634942,41.971611]},"n185978417":{"id":"n185978417","loc":[-85.634952,41.971655]},"n185978419":{"id":"n185978419","loc":[-85.634989,41.971741]},"n185978420":{"id":"n185978420","loc":[-85.635063,41.971864]},"n185978787":{"id":"n185978787","loc":[-85.627936,41.954693]},"n185978790":{"id":"n185978790","loc":[-85.626832,41.954677]},"n185978967":{"id":"n185978967","loc":[-85.632278,41.948613]},"n185980735":{"id":"n185980735","loc":[-85.628639,41.953725]},"n185982163":{"id":"n185982163","loc":[-85.636233,41.952398]},"n185982193":{"id":"n185982193","loc":[-85.6313855,41.9499125]},"n185982195":{"id":"n185982195","loc":[-85.6304857,41.9511945]},"n185982196":{"id":"n185982196","loc":[-85.626336,41.957291]},"n185982197":{"id":"n185982197","loc":[-85.625578,41.958664]},"n185982198":{"id":"n185982198","loc":[-85.624619,41.960145]},"n185982200":{"id":"n185982200","loc":[-85.624494,41.960338]},"n185984017":{"id":"n185984017","loc":[-85.636163,41.947382]},"n185984020":{"id":"n185984020","loc":[-85.636188,41.9498803]},"n185984022":{"id":"n185984022","loc":[-85.636276,41.955919]},"n185984024":{"id":"n185984024","loc":[-85.636279,41.956901]},"n185988036":{"id":"n185988036","loc":[-85.631422,41.948294]},"n185988867":{"id":"n185988867","loc":[-85.63102,41.948805]},"n185988869":{"id":"n185988869","loc":[-85.630773,41.949209]},"n185988871":{"id":"n185988871","loc":[-85.63005,41.95016]},"n185988872":{"id":"n185988872","loc":[-85.629423,41.951016]},"n185988873":{"id":"n185988873","loc":[-85.629252,41.951256]},"n185988875":{"id":"n185988875","loc":[-85.629126,41.951489]},"n185988877":{"id":"n185988877","loc":[-85.628991,41.951704]},"n185988878":{"id":"n185988878","loc":[-85.628689,41.952112]},"n185988879":{"id":"n185988879","loc":[-85.628313,41.952666]},"n185988880":{"id":"n185988880","loc":[-85.627687,41.953529]},"n185988882":{"id":"n185988882","loc":[-85.627394,41.953947]},"n185988884":{"id":"n185988884","loc":[-85.627287,41.954128]},"n1819858502":{"id":"n1819858502","loc":[-85.6328435,41.9455473]},"n1819858510":{"id":"n1819858510","loc":[-85.6324841,41.9453438]},"n1819858515":{"id":"n1819858515","loc":[-85.6318511,41.9446409]},"n1819858520":{"id":"n1819858520","loc":[-85.6326558,41.9454708]},"n1819858522":{"id":"n1819858522","loc":[-85.6319048,41.9447407]},"n1819858524":{"id":"n1819858524","loc":[-85.6317718,41.9443666]},"n1819858530":{"id":"n1819858530","loc":[-85.632055,41.9449128]},"n2139795768":{"id":"n2139795768","loc":[-85.6243023,41.9606102]},"n2139832645":{"id":"n2139832645","loc":[-85.6324455,41.9448607]},"n2139832649":{"id":"n2139832649","loc":[-85.6328043,41.9454773]},"n2139832651":{"id":"n2139832651","loc":[-85.6322547,41.9449621]},"n2139832675":{"id":"n2139832675","loc":[-85.6327356,41.944757]},"n2139832677":{"id":"n2139832677","loc":[-85.6325433,41.9448599]},"n2139832680":{"id":"n2139832680","loc":[-85.6328885,41.9455614]},"n2139832682":{"id":"n2139832682","loc":[-85.6320913,41.9449492]},"n2139832684":{"id":"n2139832684","loc":[-85.6325366,41.9447133]},"n2139832688":{"id":"n2139832688","loc":[-85.6322786,41.94485]},"n2139832718":{"id":"n2139832718","loc":[-85.6327486,41.9432475]},"n2139832719":{"id":"n2139832719","loc":[-85.6327926,41.9431773]},"n2139832720":{"id":"n2139832720","loc":[-85.6329033,41.943153]},"n2139832727":{"id":"n2139832727","loc":[-85.6328975,41.9430783]},"n2139844839":{"id":"n2139844839","loc":[-85.6326261,41.9432308]},"n2189015992":{"id":"n2189015992","loc":[-85.6347706,41.9593383]},"n2189153179":{"id":"n2189153179","loc":[-85.6340476,41.9472565]},"n2189153182":{"id":"n2189153182","loc":[-85.6342638,41.9472522]},"n2189153241":{"id":"n2189153241","loc":[-85.6354184,41.9473091]},"n2189153258":{"id":"n2189153258","loc":[-85.6354611,41.9472366]},"n2189153277":{"id":"n2189153277","loc":[-85.6328948,41.9462374]},"n2199109755":{"id":"n2199109755","loc":[-85.6336729,41.9472417]},"w203970139":{"id":"w203970139","tags":{"building":"yes"},"nodes":["n2139824793","n2139824787","n2139824773","n2139824778","n2139824793"]},"w203970098":{"id":"w203970098","tags":{"building":"yes"},"nodes":["n2139824748","n2139824712","n2139824726","n2139824760","n2139824748"]},"w208643132":{"id":"w208643132","tags":{"area":"yes","building":"yes"},"nodes":["n2189153195","n2189153196","n2189153197","n2189153198","n2189153195"]},"w203970094":{"id":"w203970094","tags":{"building":"yes"},"nodes":["n2139824755","n2139824753","n2139824759","n2139824764","n2139824763","n2139824767","n2139824770","n2139824782","n2139824772","n2139824756","n2139824751","n2139824754","n2139824755"]},"w208643138":{"id":"w208643138","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153231","n2189153232","n2189153240","n2189153244","n2189153236","n2189153238","n2189153237","n2189153239","n2189153252","n2189153235","n2189153234","n2189153253","n2189153233","n2189153231"]},"w203970125":{"id":"w203970125","tags":{"building":"yes"},"nodes":["n2139824735","n2139824738","n2139824757","n2139824749","n2139824735"]},"w170848823":{"id":"w170848823","tags":{"name":"Rocky River","waterway":"river"},"nodes":["n1819849189","n1819858516","n1819858519","n1819858504","n1819858525","n1819858506","n1819858513"]},"w203970898":{"id":"w203970898","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832645","n2139832647","n2139832649","n2139832651","n2139832645"]},"w203970134":{"id":"w203970134","tags":{"building":"yes"},"nodes":["n2139824796","n2139824803","n2139824797","n2139824788","n2139824796"]},"w203970104":{"id":"w203970104","tags":{"building":"yes"},"nodes":["n2139824733","n2139824730","n2139824714","n2139824721","n2139824733"]},"w206805245":{"id":"w206805245","tags":{"area":"yes","building":"yes"},"nodes":["n2168544780","n2168544781","n2139824796","n2139824803","n2168544780"]},"w206805252":{"id":"w206805252","tags":{"area":"yes","building":"yes"},"nodes":["n2168544838","n2168544839","n2168544840","n2168544841","n2168544842","n2168544843","n2168544844","n2168544845","n2168544846","n2168544847","n2168544838"]},"w203970099":{"id":"w203970099","tags":{"building":"yes"},"nodes":["n2139824783","n2139824795","n2139824790","n2139824779","n2139824783"]},"w17967730":{"id":"w17967730","tags":{"highway":"residential","name":"Water St"},"nodes":["n185963451","n2189153277","n185988036","n185988867","n185988869","n185988871","n185988872","n185988873","n185988875","n185988877","n185988878","n185988879","n185988880","n185988882","n185988884","n185978790"]},"w208643133":{"id":"w208643133","tags":{"area":"yes","building":"yes"},"nodes":["n2189153199","n2189153200","n2189153201","n2189153202","n2189153199"]},"w203970127":{"id":"w203970127","tags":{"building":"yes"},"nodes":["n2139824794","n2139824783","n2139824789","n2139824797","n2139824794"]},"w208643139":{"id":"w208643139","tags":{"highway":"service"},"nodes":["n185988237","n2189153242","n2189153247","n2189153241"]},"w203988297":{"id":"w203988297","tags":{"amenity":"parking","area":"yes"},"nodes":["n2140006423","n2140006441","n2140006425","n2140006426","n2140006440","n2140006427","n2140006428","n2140006429","n2140006430","n2140006423"]},"w206805250":{"id":"w206805250","tags":{"area":"yes","building":"yes"},"nodes":["n2168544827","n2168544823","n2168544825","n2168544800","n2168544829","n2168544827"]},"w208643140":{"id":"w208643140","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153242","n2189153254","n2189153243","n2189153244","n2189153251","n2189153257","n2189153245","n2189153252","n2189153246"]},"w203974055":{"id":"w203974055","tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870376","n2139870377"]},"w206805247":{"id":"w206805247","tags":{"area":"yes","building":"yes"},"nodes":["n2168544785","n2168544786","n2168544783","n2168544787","n2168544788","n2168544789","n2168544785"]},"w17964996":{"id":"w17964996","tags":{"highway":"residential","name":"Foster St"},"nodes":["n1819858524","n1819858515","n1819858522","n1819858530","n2139832682","n1819858510","n1819858520","n1819858502","n2139832680","n185963451","n1819858527","n185963452","n185963453","n185963454","n185963455","n185963456"]},"w208643144":{"id":"w208643144","tags":{"area":"yes","building":"yes"},"nodes":["n2189153264","n2189153265","n2189153266","n2189153267","n2189153268","n2189153269","n2189153270","n2189153264"]},"w203970914":{"id":"w203970914","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832722","n2139832723","n2139832724","n2139832725","n2139832726","n2139832727","n2139844839","n2139832722"]},"w208643143":{"id":"w208643143","tags":{"area":"yes","building":"yes"},"nodes":["n2189153258","n2189153259","n2189153260","n2189153261","n2189153262","n2189153263","n2189153258"]},"w203049590":{"id":"w203049590","tags":{"amenity":"parking","area":"yes"},"nodes":["n2130304152","n2130304153","n2140006403","n2130304154","n2130304156","n2130304155","n2130304160","n2130304152"]},"w203974054":{"id":"w203974054","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139858971","n2139870373","n2139870374"]},"w203049595":{"id":"w203049595","tags":{"highway":"service"},"nodes":["n2130304158","n2130304159","n2130304160","n2139832635","n2139832639"]},"w203970913":{"id":"w203970913","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832715","n2139832716","n2139832717","n2139832718","n2139832719","n2139832720","n2139832721","n2139832716"]},"w208643134":{"id":"w208643134","tags":{"area":"yes","building":"yes"},"nodes":["n2189153203","n2189153204","n2189153205","n2189153206","n2189153207","n2189153208","n2189153209","n2189153210","n2189153211","n2189153212","n2189153213","n2189153214","n2189153203"]},"w134150808":{"id":"w134150808","tags":{"bridge":"yes","highway":"residential","name":"Moore St"},"nodes":["n185988239","n185984009","n185988241","n1475284019"]},"w203970115":{"id":"w203970115","tags":{"building":"yes"},"nodes":["n2139824761","n2139824727","n2139824736","n2139824771","n2139824761"]},"w208643130":{"id":"w208643130","tags":{"area":"yes","building":"yes"},"nodes":["n2189153183","n2189153184","n2189153185","n2189153186","n2189153187","n2189153188","n2189153189","n2189153190","n2189153183"]},"w206805246":{"id":"w206805246","tags":{"area":"yes","building":"yes"},"nodes":["n2168544782","n2168544780","n2168544781","n2168544783","n2168544787","n2168544784","n2168544782"]},"w203970138":{"id":"w203970138","tags":{"building":"yes"},"nodes":["n2139824729","n2139824720","n2139824702","n2139824707","n2139824729"]},"w203970133":{"id":"w203970133","tags":{"building":"yes"},"nodes":["n2139824748","n2139824737","n2139824717","n2139824728","n2139824748"]},"w203970907":{"id":"w203970907","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832700","n2139832701","n2139832702"]},"w203974056":{"id":"w203974056","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870377","n2139870378"]},"w203970897":{"id":"w203970897","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2130304156","n2166205688","n2139832635","n2139832636","n2139832637","n2139832639","n2139832641","n2166205688"]},"w203974057":{"id":"w203974057","tags":{"highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870375","n2139870376"]},"w203049594":{"id":"w203049594","tags":{"highway":"service"},"nodes":["n2130304156","n2139870378","n2139832706","n2139832704","n2130304157"]},"w203970122":{"id":"w203970122","tags":{"building":"yes"},"nodes":["n2139824757","n2139824740","n2139824747","n2139824762","n2139824757"]},"w208643136":{"id":"w208643136","tags":{"area":"yes","building":"yes"},"nodes":["n2189153219","n2189153220","n2189153221","n2189153222","n2189153223","n2189153224","n2189153225","n2189153226","n2189153219"]},"w203970128":{"id":"w203970128","tags":{"building":"yes"},"nodes":["n2139824732","n2139824752","n2139824744","n2139824724","n2139824732"]},"w203970097":{"id":"w203970097","tags":{"building":"yes"},"nodes":["n2139824737","n2139824733","n2139824710","n2139824716","n2139824737"]},"w203970137":{"id":"w203970137","tags":{"building":"yes"},"nodes":["n2139824765","n2139824774","n2139824758","n2139824746","n2139824765"]},"w134150840":{"id":"w134150840","tags":{"highway":"residential","name":"Moore St"},"nodes":["n1475284019","n185988243","n185988244","n185988245"]},"w17967628":{"id":"w17967628","tags":{"highway":"residential","name":"Moore St"},"nodes":["n185978388","n2139832709","n185988237","n185988239"]},"w203988292":{"id":"w203988292","tags":{"bridge":"yes","highway":"footway"},"nodes":["n2140006407","n2140006405"]},"w203970118":{"id":"w203970118","tags":{"building":"yes"},"nodes":["n2139824775","n2139824785","n2139824780","n2139824768","n2139824775"]},"w203970121":{"id":"w203970121","tags":{"building":"yes"},"nodes":["n2139824768","n2139824781","n2139824776","n2139824765","n2139824768"]},"w17967752":{"id":"w17967752","tags":{"highway":"residential","name":"Railroad Drive"},"nodes":["n185964980","n2139832699","n2139832700","n2130304158","n185988969","n185988971","n185988972","n1475284011"]},"w203970136":{"id":"w203970136","tags":{"building":"yes"},"nodes":["n2139824798","n2139824793","n2139824777","n2139824784","n2139824798"]},"w203970142":{"id":"w203970142","tags":{"building":"yes"},"nodes":["n2139824808","n2139824809","n2139824807","n2139824806","n2139824801","n2139824800","n2139824804","n2139824805","n2139824808"]},"w208643137":{"id":"w208643137","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153227","n2189153248","n2189153228","n2189153234","n2189153235","n2189153229","n2189153249","n2189153230","n2189153227"]},"w208643129":{"id":"w208643129","tags":{"area":"yes","building":"yes"},"nodes":["n2189153179","n2189153180","n2189153181","n2189153182","n2189153179"]},"w203970909":{"id":"w203970909","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832703","n2139832704","n2139832706","n2139832708","n2139832703"]},"w203970905":{"id":"w203970905","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832688","n2139832691"]},"w203988298":{"id":"w203988298","tags":{"highway":"service"},"nodes":["n2140006431","n2140006433","n2140006435","n2140006436","n2140006437","n2140006438","n2140006439","n2140006440"]},"w203970106":{"id":"w203970106","tags":{"building":"yes"},"nodes":["n2139824798","n2139824791","n2139824799","n2139824802","n2139824798"]},"w203970129":{"id":"w203970129","tags":{"building":"yes"},"nodes":["n2139824787","n2139824782","n2139824766","n2139824769","n2139824787"]},"w208643131":{"id":"w208643131","tags":{"area":"yes","building":"yes"},"nodes":["n2189153191","n2189153192","n2189153193","n2189153194","n2189153191"]},"w206805249":{"id":"w206805249","tags":{"area":"yes","building":"yes"},"nodes":["n2168544800","n2168544801","n2168544802","n2168544805","n2168544807","n2168544809","n2168544811","n2168544813","n2168544815","n2168544817","n2168544819","n2168544821","n2168544823","n2168544825","n2168544800"]},"w134150800":{"id":"w134150800","tags":{"bridge":"yes","highway":"primary","name":"W Michigan Ave","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964972","n185964976"]},"w17966984":{"id":"w17966984","tags":{"highway":"residential","name":"Portage Avenue"},"nodes":["n185978375","n185963456","n2189153218","n185966937","n185978967","n185967422","n185982193","n185968100","n185982195","n185960195","n185980735","n185978787","n185966948","n185982196","n185982197","n185982198","n185982200","n2139795768","n185972155"]},"w203988294":{"id":"w203988294","tags":{"amenity":"shelter","area":"yes","building":"yes","shelter_type":"picnic_shelter"},"nodes":["n2140006409","n2140006411","n2140006413","n2140006415","n2140006409"]},"w203970912":{"id":"w203970912","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832711","n2139832712","n2139832713","n2139832714","n2139832711"]},"w203970119":{"id":"w203970119","tags":{"building":"yes"},"nodes":["n2139824713","n2139824705","n2139824683","n2139824689","n2139824713"]},"w203970114":{"id":"w203970114","tags":{"building":"yes"},"nodes":["n2139824735","n2139824750","n2139824745","n2139824732","n2139824735"]},"w208643142":{"id":"w208643142","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153254","n2189153255","n2189153256","n2189153257"]},"w206805253":{"id":"w206805253","tags":{"area":"yes","building":"yes"},"nodes":["n2168544848","n2168544849","n2168544850","n2168544851","n2168544852","n2168544853","n2168544854","n2168544855","n2168544848"]},"w143497377":{"id":"w143497377","tags":{"highway":"primary","name":"North Main Street","old_ref":"US 131","ref":"US 131 Business"},"nodes":["n185962625","n185978420","n185978419","n185978417","n185978415","n185978414","n185975735","n1475293254","n185978410","n185978406","n185970515","n185978402","n185978399","n185965399","n2189015992","n185961396","n185967917","n185978394","n185971631","n185960796","n185978392","n185974583","n185978390","n185971578","n185965289","n2189153215","n185978388","n185978383","n185978381","n185978379","n185978377","n185978375","n185964982"]},"w134150811":{"id":"w134150811","tags":{"highway":"primary","name":"West Michigan Avenue","old_ref":"US 131","ref":"US 131 Business;M 60"},"nodes":["n185964976","n2130304157","n1475284023","n2139832715","n185964980","n185964982"]},"w208643135":{"id":"w208643135","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153215","n2189153216","n2189153217","n2189153218"]},"w17967183":{"id":"w17967183","tags":{"highway":"residential","name":"West Street"},"nodes":["n1475284011","n185984011","n185984013","n185984015","n2189153246","n2189153250","n185965291","n185984017","n185971580","n185984020","n185974585","n185982163","n185975064","n185971632","n185984022","n185984024","n185967918"]},"w134150778":{"id":"w134150778","tags":{"bridge":"yes","highway":"residential","name":"Moore St"},"nodes":["n185988245","n1475283992","n185975911"]},"w206805248":{"id":"w206805248","tags":{"area":"yes","building":"yes"},"nodes":["n2168544790","n2168544791","n2168544792","n2168544793","n2168544795","n2168544797","n2168544798","n2168544799","n2168544802","n2168544801","n2168544790"]},"w203974058":{"id":"w203974058","tags":{"bridge":"yes","highway":"path","name":"Riverwalk Trail"},"nodes":["n2139870374","n2139870375"]},"w203970902":{"id":"w203970902","tags":{"highway":"service"},"nodes":["n2139832678","n2139832691","n2139832680"]},"w203988296":{"id":"w203988296","tags":{"highway":"path"},"nodes":["n2139858967","n2140006421","n2139858935"]},"w206805251":{"id":"w206805251","tags":{"area":"yes","building":"yes"},"nodes":["n2168544830","n2168544831","n2168544832","n2168544833","n2168544834","n2168544835","n2168544836","n2168544837","n2168544830"]},"w203970906":{"id":"w203970906","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832693","n2139832694","n2139832696","n2139832697","n2139832698","n2139832693"]},"w203049598":{"id":"w203049598","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2130304162","n2130304163","n2130304164","n2130304165","n2130304162"]},"w203970911":{"id":"w203970911","tags":{"highway":"service"},"nodes":["n2139832709","n2139832714","n2139832713","n2139832710","n185988971"]},"w203970105":{"id":"w203970105","tags":{"building":"yes"},"nodes":["n2139824779","n2139824792","n2139824786","n2139824775","n2139824779"]},"w203988290":{"id":"w203988290","tags":{"highway":"footway"},"nodes":["n2140006403","n2140006407"]},"w203970900":{"id":"w203970900","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139832653","n2139832663","n2139832665","n2139832667","n2139832669","n2139832671","n2139832673","n2139832675","n2139832677","n2139832653"]},"w209717048":{"id":"w209717048","tags":{"area":"yes","building":"yes"},"nodes":["n2199109755","n2199109756","n2199109757","n2199109758","n2199109759","n2199109760","n2199109755"]},"w208643141":{"id":"w208643141","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153247","n2189153248","n2189153249","n2189153250"]},"w203970903":{"id":"w203970903","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2139832682","n2139832688","n2139832684","n2139832678","n2139832686"]},"n354002527":{"id":"n354002527","loc":[-85.6236039,41.9458813],"tags":{"amenity":"school","name":"Barrows School"}},"n185963396":{"id":"n185963396","loc":[-85.627401,41.943496]},"n185963397":{"id":"n185963397","loc":[-85.627403,41.943625]},"n185965101":{"id":"n185965101","loc":[-85.626409,41.943215]},"n185971474":{"id":"n185971474","loc":[-85.624884,41.943508]},"n185971475":{"id":"n185971475","loc":[-85.625191,41.943509]},"n185971482":{"id":"n185971482","loc":[-85.624882,41.94382]},"n185983135":{"id":"n185983135","loc":[-85.624893,41.945616]},"n185983137":{"id":"n185983137","loc":[-85.624912,41.946524]},"n185988027":{"id":"n185988027","loc":[-85.622721,41.946535]},"n185963398":{"id":"n185963398","loc":[-85.6273993,41.9446899]},"n185983238":{"id":"n185983238","loc":[-85.6227157,41.9456321]},"n185980374":{"id":"n185980374","loc":[-85.6248856,41.9447242]},"n185980373":{"id":"n185980373","loc":[-85.6226744,41.9447371]},"n2196831342":{"id":"n2196831342","loc":[-85.6250924,41.945063]},"n2196831343":{"id":"n2196831343","loc":[-85.6252335,41.9450636]},"n2196831344":{"id":"n2196831344","loc":[-85.6252286,41.9448707]},"n2196831345":{"id":"n2196831345","loc":[-85.6250661,41.9448707]},"n2196831346":{"id":"n2196831346","loc":[-85.6250243,41.9449012]},"n2196831347":{"id":"n2196831347","loc":[-85.6250251,41.9449244]},"n2196831348":{"id":"n2196831348","loc":[-85.6250867,41.9449257]},"n2196831349":{"id":"n2196831349","loc":[-85.625349,41.9445058]},"n2196831350":{"id":"n2196831350","loc":[-85.6253471,41.9443882]},"n2196831351":{"id":"n2196831351","loc":[-85.6251516,41.94439]},"n2196831352":{"id":"n2196831352","loc":[-85.6251522,41.9444308]},"n2196831353":{"id":"n2196831353","loc":[-85.6251344,41.9444309]},"n2196831354":{"id":"n2196831354","loc":[-85.6251356,41.9445077]},"n2196831355":{"id":"n2196831355","loc":[-85.6232357,41.9463406]},"n2196831356":{"id":"n2196831356","loc":[-85.6232409,41.9460668]},"n2196831357":{"id":"n2196831357","loc":[-85.6232072,41.9460665]},"n2196831358":{"id":"n2196831358","loc":[-85.6232117,41.9458272]},"n2196831359":{"id":"n2196831359","loc":[-85.6229808,41.9458248]},"n2196831360":{"id":"n2196831360","loc":[-85.6229763,41.9460627]},"n2196831361":{"id":"n2196831361","loc":[-85.623006,41.946063]},"n2196831362":{"id":"n2196831362","loc":[-85.6230023,41.9462557]},"n2196831363":{"id":"n2196831363","loc":[-85.6230755,41.9462565]},"n2196831364":{"id":"n2196831364","loc":[-85.6230739,41.9463389]},"n185947349":{"id":"n185947349","loc":[-85.618327,41.945607]},"n185947359":{"id":"n185947359","loc":[-85.615453,41.945597]},"n185947378":{"id":"n185947378","loc":[-85.617231,41.945603]},"n185947474":{"id":"n185947474","loc":[-85.616136,41.945602]},"n185948972":{"id":"n185948972","loc":[-85.615273,41.945637]},"n185955019":{"id":"n185955019","loc":[-85.620172,41.945627]},"n185960682":{"id":"n185960682","loc":[-85.622759,41.951845]},"n185961369":{"id":"n185961369","loc":[-85.622758,41.947444]},"n185961371":{"id":"n185961371","loc":[-85.624908,41.947416]},"n185963392":{"id":"n185963392","loc":[-85.6270462,41.9409953]},"n185963393":{"id":"n185963393","loc":[-85.627295,41.941304]},"n185963394":{"id":"n185963394","loc":[-85.627352,41.94148]},"n185963395":{"id":"n185963395","loc":[-85.62737,41.942261]},"n185965099":{"id":"n185965099","loc":[-85.6264,41.942263]},"n185965108":{"id":"n185965108","loc":[-85.622769,41.949224]},"n185965110":{"id":"n185965110","loc":[-85.624937,41.949237]},"n185966295":{"id":"n185966295","loc":[-85.6299942,41.9446689]},"n185966342":{"id":"n185966342","loc":[-85.624873,41.942022]},"n185970222":{"id":"n185970222","loc":[-85.622761,41.948357]},"n185970224":{"id":"n185970224","loc":[-85.624924,41.9483338]},"n185971477":{"id":"n185971477","loc":[-85.620051,41.94383]},"n185971478":{"id":"n185971478","loc":[-85.621219,41.943801]},"n185971481":{"id":"n185971481","loc":[-85.621812,41.943807]},"n185973866":{"id":"n185973866","loc":[-85.627629,41.946498]},"n185974699":{"id":"n185974699","loc":[-85.6227688,41.950119]},"n185978800":{"id":"n185978800","loc":[-85.623953,41.954684]},"n185980372":{"id":"n185980372","loc":[-85.621459,41.944756]},"n185980378":{"id":"n185980378","loc":[-85.6286375,41.9446764]},"n185980380":{"id":"n185980380","loc":[-85.630139,41.944661]},"n185980382":{"id":"n185980382","loc":[-85.630298,41.944635]},"n185980384":{"id":"n185980384","loc":[-85.630759,41.94454]},"n185980386":{"id":"n185980386","loc":[-85.6312369,41.9444548]},"n185983133":{"id":"n185983133","loc":[-85.6248672,41.9415903]},"n185983139":{"id":"n185983139","loc":[-85.624951,41.950239]},"n185983140":{"id":"n185983140","loc":[-85.624934,41.950681]},"n185983141":{"id":"n185983141","loc":[-85.624813,41.950983]},"n185983143":{"id":"n185983143","loc":[-85.6246225,41.951591]},"n185983144":{"id":"n185983144","loc":[-85.623908,41.9539165]},"n185983145":{"id":"n185983145","loc":[-85.6238903,41.9540956]},"n185983146":{"id":"n185983146","loc":[-85.623898,41.95431]},"n185983236":{"id":"n185983236","loc":[-85.628481,41.945611]},"n185985914":{"id":"n185985914","loc":[-85.620072,41.946538]},"n185986812":{"id":"n185986812","loc":[-85.6227785,41.9510005]},"n185988028":{"id":"n185988028","loc":[-85.6281401,41.9469632]},"n185988030":{"id":"n185988030","loc":[-85.6282451,41.9470314]},"n185988032":{"id":"n185988032","loc":[-85.6283312,41.9470656]},"w17964989":{"id":"w17964989","tags":{"highway":"residential","name":"Middle St"},"nodes":["n185963392","n185963393","n185963394","n185963395","n185963396","n185963397","n185963398"]},"w17965158":{"id":"w17965158","tags":{"access":"private","highway":"service","name":"Battle St"},"nodes":["n185965099","n185965101"]},"w41074896":{"id":"w41074896","tags":{"highway":"secondary","name":"East Michigan Avenue","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185980372","n185980373","n185980374","n185963398","n185980378","n185966295","n185980380","n185980382","n185980384","n185980386"]},"w17965846":{"id":"w17965846","tags":{"highway":"residential","name":"2nd Ave"},"nodes":["n185971477","n185971478","n185971481","n185971482"]},"w209470306":{"id":"w209470306","tags":{"area":"yes","building":"yes"},"nodes":["n2196831349","n2196831350","n2196831351","n2196831352","n2196831353","n2196831354","n2196831349"]},"w17965845":{"id":"w17965845","tags":{"highway":"residential","name":"2nd Ave"},"nodes":["n185971474","n185971475","n185963396"]},"w209470307":{"id":"w209470307","tags":{"area":"yes","building":"yes"},"nodes":["n2196831355","n2196831356","n2196831357","n2196831358","n2196831359","n2196831360","n2196831361","n2196831362","n2196831363","n2196831364","n2196831355"]},"w17968192":{"id":"w17968192","tags":{"highway":"residential","name":"Washington St"},"nodes":["n185980373","n185983238","n185988027","n185961369","n185970222","n185965108","n185974699","n185986812","n185960682"]},"w17967603":{"id":"w17967603","tags":{"highway":"residential","name":"5th Ave"},"nodes":["n185985914","n185988027","n185983137","n185973866","n185988028","n185988030","n185988032"]},"w209470305":{"id":"w209470305","tags":{"area":"yes","building":"yes"},"nodes":["n2196831342","n2196831343","n2196831344","n2196831345","n2196831346","n2196831347","n2196831348","n2196831342"]},"w17967092":{"id":"w17967092","tags":{"highway":"residential","name":"Wood St"},"nodes":["n185983133","n185966342","n185971474","n185971482","n185980374","n185983135","n185983137","n185961371","n185970224","n185965110","n185983139","n185983140","n185983141","n185983143","n185983144","n185983145","n185983146","n185978800"]},"w17967107":{"id":"w17967107","tags":{"highway":"residential","name":"4th Ave"},"nodes":["n185983236","n185983135","n185983238","n185955019","n185947349","n185947378","n185947474","n185947359","n185948972"]},"n354030330":{"id":"n354030330","loc":[-85.6297222,41.9444444],"tags":{"leisure":"park","name":"Scouter Park"}},"n185966296":{"id":"n185966296","loc":[-85.629998,41.944078]},"n185966298":{"id":"n185966298","loc":[-85.629972,41.943927]},"n185966300":{"id":"n185966300","loc":[-85.629948,41.943783]},"n185980391":{"id":"n185980391","loc":[-85.6322992,41.9442766]},"n185980393":{"id":"n185980393","loc":[-85.6324925,41.9442136]},"n185980389":{"id":"n185980389","loc":[-85.6320272,41.9443281]},"n185980388":{"id":"n185980388","loc":[-85.6315778,41.9443959]},"n354031320":{"id":"n354031320","loc":[-85.6280556,41.9447222],"tags":{"amenity":"place_of_worship","name":"Riverside Church","religion":"christian"}},"n185987309":{"id":"n185987309","loc":[-85.6286497,41.9453531]},"n185987311":{"id":"n185987311","loc":[-85.6285942,41.9454805]},"n185988034":{"id":"n185988034","loc":[-85.6285815,41.9471692]},"n185988896":{"id":"n185988896","loc":[-85.6318433,41.9437929]},"n185977764":{"id":"n185977764","loc":[-85.6322988,41.943472]},"n1819848852":{"id":"n1819848852","loc":[-85.6315188,41.9448808]},"n1819848912":{"id":"n1819848912","loc":[-85.6284289,41.9472189]},"n1819848925":{"id":"n1819848925","loc":[-85.6314501,41.9451617]},"n1819848949":{"id":"n1819848949","loc":[-85.6309394,41.9455192]},"n1819848951":{"id":"n1819848951","loc":[-85.6290297,41.9457187]},"n1819848963":{"id":"n1819848963","loc":[-85.630521,41.9455591]},"n1819848981":{"id":"n1819848981","loc":[-85.6292936,41.9455846]},"n1819848989":{"id":"n1819848989","loc":[-85.6298451,41.9455431]},"n1819848998":{"id":"n1819848998","loc":[-85.6314973,41.9446254]},"n1819849018":{"id":"n1819849018","loc":[-85.6302807,41.9455527]},"n1819849043":{"id":"n1819849043","loc":[-85.6285533,41.9469731]},"n1819849087":{"id":"n1819849087","loc":[-85.6314501,41.9453532]},"n1819849090":{"id":"n1819849090","loc":[-85.628843,41.9461033]},"n1819849109":{"id":"n1819849109","loc":[-85.6311926,41.9454729]},"n1819849116":{"id":"n1819849116","loc":[-85.6288967,41.9459437]},"n1819849177":{"id":"n1819849177","loc":[-85.6287894,41.9464544]},"n1819858529":{"id":"n1819858529","loc":[-85.6325485,41.9445625]},"n2189112797":{"id":"n2189112797","loc":[-85.6275271,41.944555]},"n2189112798":{"id":"n2189112798","loc":[-85.6275196,41.9437258]},"n2189112799":{"id":"n2189112799","loc":[-85.6278937,41.943723]},"n2189112800":{"id":"n2189112800","loc":[-85.6278969,41.9439191]},"n2189112801":{"id":"n2189112801","loc":[-85.6279907,41.9439345]},"n2189112802":{"id":"n2189112802","loc":[-85.6280817,41.9439663]},"n2189112803":{"id":"n2189112803","loc":[-85.6281768,41.9440145]},"n2189112804":{"id":"n2189112804","loc":[-85.6281933,41.9440483]},"n2189112805":{"id":"n2189112805","loc":[-85.6281671,41.9440535]},"n2189112806":{"id":"n2189112806","loc":[-85.6281933,41.9440935]},"n2189112807":{"id":"n2189112807","loc":[-85.6282126,41.9441437]},"n2189112808":{"id":"n2189112808","loc":[-85.628214,41.9441991]},"n2189112809":{"id":"n2189112809","loc":[-85.6283298,41.944196]},"n2189112810":{"id":"n2189112810","loc":[-85.6283285,41.9442616]},"n2189112811":{"id":"n2189112811","loc":[-85.6281727,41.9442616]},"n2189112812":{"id":"n2189112812","loc":[-85.6281713,41.9442934]},"n2189112813":{"id":"n2189112813","loc":[-85.6280386,41.9442963]},"n2189112814":{"id":"n2189112814","loc":[-85.6280405,41.9443292]},"n2189112815":{"id":"n2189112815","loc":[-85.627829,41.9443349]},"n2189112816":{"id":"n2189112816","loc":[-85.6278347,41.9445495]},"n2189153271":{"id":"n2189153271","loc":[-85.6321053,41.9460342]},"n2189153272":{"id":"n2189153272","loc":[-85.632278,41.9457841]},"n2189153273":{"id":"n2189153273","loc":[-85.632823,41.9459936]},"n2189153274":{"id":"n2189153274","loc":[-85.6326845,41.9461963]},"n2189153275":{"id":"n2189153275","loc":[-85.6325664,41.9461507]},"n2189153276":{"id":"n2189153276","loc":[-85.6325323,41.946198]},"n2189153278":{"id":"n2189153278","loc":[-85.6321916,41.9459733]},"n2189153279":{"id":"n2189153279","loc":[-85.6322598,41.9458703]},"n2189153280":{"id":"n2189153280","loc":[-85.6327208,41.9460358]},"n2189153281":{"id":"n2189153281","loc":[-85.6326413,41.9461422]},"n185959079":{"id":"n185959079","loc":[-85.6293702,41.9474668]},"n185966301":{"id":"n185966301","loc":[-85.629692,41.943136]},"n185966304":{"id":"n185966304","loc":[-85.629565,41.942916]},"n185966308":{"id":"n185966308","loc":[-85.629501,41.942751]},"n185966315":{"id":"n185966315","loc":[-85.629472,41.942578]},"n185966319":{"id":"n185966319","loc":[-85.629444,41.942414]},"n185966321":{"id":"n185966321","loc":[-85.629391,41.94205]},"n185966323":{"id":"n185966323","loc":[-85.629369,41.941858]},"n185966327":{"id":"n185966327","loc":[-85.629297,41.941604]},"n185966331":{"id":"n185966331","loc":[-85.629233,41.941549]},"n185966336":{"id":"n185966336","loc":[-85.628504,41.941364]},"n185966338":{"id":"n185966338","loc":[-85.628275,41.941303]},"n185966340":{"id":"n185966340","loc":[-85.6269038,41.9410983]},"n185973867":{"id":"n185973867","loc":[-85.626843,41.947333]},"n185977762":{"id":"n185977762","loc":[-85.6318441,41.9429453]},"n1819848853":{"id":"n1819848853","loc":[-85.625854,41.9492218]},"n1819848861":{"id":"n1819848861","loc":[-85.6251459,41.9552376]},"n1819848874":{"id":"n1819848874","loc":[-85.6267445,41.9482961]},"n1819848882":{"id":"n1819848882","loc":[-85.6257209,41.9552396]},"n1819848883":{"id":"n1819848883","loc":[-85.624706,41.9523173]},"n1819848907":{"id":"n1819848907","loc":[-85.62609,41.9561471]},"n1819848908":{"id":"n1819848908","loc":[-85.6244013,41.9549284]},"n1819848911":{"id":"n1819848911","loc":[-85.6265578,41.9553672]},"n1819848923":{"id":"n1819848923","loc":[-85.6246802,41.9550959]},"n1819848936":{"id":"n1819848936","loc":[-85.6241588,41.9539291]},"n1819848940":{"id":"n1819848940","loc":[-85.62506,41.9511129]},"n1819848944":{"id":"n1819848944","loc":[-85.624942,41.9515912]},"n1819848950":{"id":"n1819848950","loc":[-85.6273989,41.9475461]},"n1819848957":{"id":"n1819848957","loc":[-85.627695,41.947404]},"n1819849009":{"id":"n1819849009","loc":[-85.6259248,41.94896]},"n1819849037":{"id":"n1819849037","loc":[-85.6257252,41.9502112]},"n1819849061":{"id":"n1819849061","loc":[-85.6270084,41.9479626]},"n1819849073":{"id":"n1819849073","loc":[-85.6243734,41.9534583]},"n1819849091":{"id":"n1819849091","loc":[-85.6241373,41.9543918]},"n1819849130":{"id":"n1819849130","loc":[-85.6282572,41.9473067]},"n1819849143":{"id":"n1819849143","loc":[-85.625281,41.9506596]},"n1819849153":{"id":"n1819849153","loc":[-85.6258647,41.9498043]},"n1819849168":{"id":"n1819849168","loc":[-85.6265084,41.9559317]},"n1819849173":{"id":"n1819849173","loc":[-85.6263325,41.9552156]},"n1819849175":{"id":"n1819849175","loc":[-85.6266372,41.9556764]},"n1819849178":{"id":"n1819849178","loc":[-85.6242232,41.9545993]},"n1819849181":{"id":"n1819849181","loc":[-85.6262187,41.9486712]},"n1819849188":{"id":"n1819849188","loc":[-85.6245558,41.9530434]},"n1819849190":{"id":"n1819849190","loc":[-85.6255982,41.9563017]},"n2168544738":{"id":"n2168544738","loc":[-85.6245707,41.9529711]},"w208643145":{"id":"w208643145","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189153271","n2189153272","n2189153273","n2189153274","n2189153275","n2189153276","n2189153271"]},"w17967561":{"id":"w17967561","tags":{"highway":"residential","name":"Garden St"},"nodes":["n185980378","n185987309","n185987311","n185983236","n185973866"]},"w134150802":{"id":"w134150802","tags":{"bridge":"yes","highway":"secondary","name":"East Michigan Avenue","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185980386","n185980388"]},"w208639462":{"id":"w208639462","tags":{"area":"yes","building":"yes"},"nodes":["n2189112797","n2189112798","n2189112799","n2189112800","n2189112801","n2189112802","n2189112803","n2189112804","n2189112805","n2189112806","n2189112807","n2189112808","n2189112809","n2189112810","n2189112811","n2189112812","n2189112813","n2189112814","n2189112815","n2189112816","n2189112797"]},"w134150830":{"id":"w134150830","tags":{"bridge":"yes","highway":"secondary","name":"South Main Street","old_ref":"US 131","ref":"M 86"},"nodes":["n185977762","n185977764"]},"w134150801":{"id":"w134150801","tags":{"highway":"secondary","name":"South Main Street","old_ref":"US 131","ref":"M 86"},"nodes":["n185977764","n185964982"]},"w208643146":{"id":"w208643146","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2189153277","n2189153281","n2189153278","n2189153279","n2189153280","n2189153281"]},"w17966061":{"id":"w17966061","tags":{"highway":"residential","name":"John Glenn Ct"},"nodes":["n185973866","n185973867"]},"w134150772":{"id":"w134150772","tags":{"highway":"residential","name":"5th Ave"},"nodes":["n185988034","n185959079","n185988036","n185978967"]},"w134150836":{"id":"w134150836","tags":{"highway":"secondary","name":"East Michigan Avenue","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185980388","n1819858524","n185980389","n185980391","n185980393","n185964982"]},"w17967734":{"id":"w17967734","tags":{"highway":"residential","name":"Water Street"},"nodes":["n185988896","n185980391","n1819858529"]},"w17965305":{"id":"w17965305","tags":{"highway":"residential","name":"River Dr"},"nodes":["n185966295","n185966296","n185966298","n185966300","n185966301","n185966304","n185966308","n185966315","n185966319","n185966321","n185966323","n185966327","n185966331","n185966336","n185966338","n185963392","n185966340","n185966342"]},"w134150826":{"id":"w134150826","tags":{"bridge":"yes","highway":"residential","name":"5th Ave"},"nodes":["n185988032","n185988034"]},"w170848330":{"id":"w170848330","tags":{"name":"Portage River","waterway":"river"},"nodes":["n1819849190","n1819848907","n1819849168","n1819849175","n1819848911","n1819849173","n1819848882","n1819848861","n1819848923","n1819848908","n1819849178","n1819849091","n1819848936","n1819849073","n1819849188","n2168544738","n1819848883","n1819848944","n1819848940","n1819849143","n1819849037","n1819849153","n1819848853","n1819849009","n1819849181","n1819848874","n1819849061","n1819848950","n1819848957","n1819849130","n1819848912","n1819849043","n1819849177","n1819849090","n1819849116","n1819848951","n1819848981","n1819848989","n1819849018","n1819848963","n1819848949","n1819849109","n1819849087","n1819848925","n1819848852","n1819848998","n1819849057"]},"r270264":{"id":"r270264","tags":{"network":"US:MI","ref":"86","route":"road","state_id":"MI","type":"route","url":"http://en.wikipedia.org/wiki/M-86_%28Michigan_highway%29"},"members":[{"id":"w17737723","type":"way","role":""},{"id":"w17735949","type":"way","role":""},{"id":"w17740404","type":"way","role":""},{"id":"w17966273","type":"way","role":""},{"id":"w17964745","type":"way","role":""},{"id":"w151538068","type":"way","role":""},{"id":"w151538067","type":"way","role":""},{"id":"w17964960","type":"way","role":""},{"id":"w17966099","type":"way","role":""},{"id":"w17968009","type":"way","role":""},{"id":"w41259499","type":"way","role":""},{"id":"w151540401","type":"way","role":""},{"id":"w151540418","type":"way","role":""},{"id":"w17967997","type":"way","role":""},{"id":"w17966029","type":"way","role":""},{"id":"w17964801","type":"way","role":""},{"id":"w41259496","type":"way","role":""},{"id":"w151540399","type":"way","role":""},{"id":"w17968004","type":"way","role":""},{"id":"w17966462","type":"way","role":""},{"id":"w134150830","type":"way","role":""},{"id":"w134150801","type":"way","role":""},{"id":"w17732295","type":"way","role":""}]},"n185980093":{"id":"n185980093","loc":[-85.6271414,41.9407274]},"n185964330":{"id":"n185964330","loc":[-85.6235688,41.9399111]},"n185964328":{"id":"n185964328","loc":[-85.6235609,41.9391301]},"n185958034":{"id":"n185958034","loc":[-85.627102,41.939125]},"n185964331":{"id":"n185964331","loc":[-85.623571,41.940124]},"n185964329":{"id":"n185964329","loc":[-85.623562,41.9392411]},"n185972756":{"id":"n185972756","loc":[-85.623802,41.939102]},"n185972757":{"id":"n185972757","loc":[-85.623584,41.93913]},"n185975325":{"id":"n185975325","loc":[-85.624835,41.939318]},"n185975326":{"id":"n185975326","loc":[-85.624811,41.939435]},"n185975327":{"id":"n185975327","loc":[-85.624635,41.939703]},"n185975328":{"id":"n185975328","loc":[-85.624366,41.940055]},"n185975330":{"id":"n185975330","loc":[-85.624287,41.940113]},"n185975332":{"id":"n185975332","loc":[-85.624215,41.940134]},"n185980088":{"id":"n185980088","loc":[-85.627127,41.940086]},"n185988943":{"id":"n185988943","loc":[-85.622643,41.940128]},"n185988961":{"id":"n185988961","loc":[-85.627263,41.940082]},"n185990192":{"id":"n185990192","loc":[-85.622933,41.939224]},"n185990194":{"id":"n185990194","loc":[-85.621976,41.939203]},"n185991378":{"id":"n185991378","loc":[-85.622643,41.940635]},"n1475283999":{"id":"n1475283999","loc":[-85.6271165,41.9408429]},"n185980090":{"id":"n185980090","loc":[-85.6271315,41.9402001]},"n185958036":{"id":"n185958036","loc":[-85.6248366,41.9391615]},"n1819800188":{"id":"n1819800188","loc":[-85.6246947,41.9401644]},"n1819800199":{"id":"n1819800199","loc":[-85.6233686,41.9430896]},"n1819800204":{"id":"n1819800204","loc":[-85.6223236,41.9408587]},"n1819800213":{"id":"n1819800213","loc":[-85.6247526,41.9414138]},"n1819800216":{"id":"n1819800216","loc":[-85.6230961,41.9407151]},"n1819800218":{"id":"n1819800218","loc":[-85.621991,41.9429336]},"n1819800221":{"id":"n1819800221","loc":[-85.6246088,41.9424708]},"n1819800227":{"id":"n1819800227","loc":[-85.6241368,41.9403081]},"n1819800230":{"id":"n1819800230","loc":[-85.6226776,41.9431012]},"n1819800231":{"id":"n1819800231","loc":[-85.6243728,41.9401644]},"n1819800232":{"id":"n1819800232","loc":[-85.6249629,41.9408907]},"n1819800248":{"id":"n1819800248","loc":[-85.6238685,41.9405555]},"n1819800266":{"id":"n1819800266","loc":[-85.6246882,41.9418367]},"n1819800271":{"id":"n1819800271","loc":[-85.62492,41.9413695]},"n1819800294":{"id":"n1819800294","loc":[-85.6243556,41.9427465]},"n1819800304":{"id":"n1819800304","loc":[-85.6251453,41.94117]},"n1819800325":{"id":"n1819800325","loc":[-85.6248234,41.9405714]},"n1819800362":{"id":"n1819800362","loc":[-85.6239544,41.9429416]},"n1819800368":{"id":"n1819800368","loc":[-85.6243406,41.9402283]},"n1819800375":{"id":"n1819800375","loc":[-85.6226562,41.940755]},"n1819800377":{"id":"n1819800377","loc":[-85.6232033,41.9406512]},"n185945133":{"id":"n185945133","loc":[-85.623501,41.933232]},"n185945135":{"id":"n185945135","loc":[-85.624776,41.933205]},"n185945395":{"id":"n185945395","loc":[-85.624741,41.93019]},"n185952239":{"id":"n185952239","loc":[-85.615166,41.9382]},"n185954490":{"id":"n185954490","loc":[-85.624721,41.929278]},"n185957831":{"id":"n185957831","loc":[-85.625041,41.938662]},"n185958030":{"id":"n185958030","loc":[-85.629033,41.93913]},"n185958032":{"id":"n185958032","loc":[-85.628429,41.939143]},"n185958498":{"id":"n185958498","loc":[-85.621605,41.940143]},"n185961186":{"id":"n185961186","loc":[-85.624792,41.935214]},"n185963099":{"id":"n185963099","loc":[-85.6204461,41.9401485]},"n185963698":{"id":"n185963698","loc":[-85.6297342,41.9400783]},"n185964320":{"id":"n185964320","loc":[-85.623511,41.934216]},"n185964322":{"id":"n185964322","loc":[-85.6235312,41.9362084]},"n185964324":{"id":"n185964324","loc":[-85.6235488,41.9371726]},"n185964326":{"id":"n185964326","loc":[-85.6235512,41.9381718]},"n185967077":{"id":"n185967077","loc":[-85.617359,41.940161]},"n185967634":{"id":"n185967634","loc":[-85.6248039,41.9362012]},"n185970833":{"id":"n185970833","loc":[-85.6248019,41.9381684]},"n185972752":{"id":"n185972752","loc":[-85.624582,41.938848]},"n185972754":{"id":"n185972754","loc":[-85.6242,41.939008]},"n185973251":{"id":"n185973251","loc":[-85.602727,41.936012]},"n185974509":{"id":"n185974509","loc":[-85.62478,41.93217]},"n185975315":{"id":"n185975315","loc":[-85.624703,41.925597]},"n185975316":{"id":"n185975316","loc":[-85.624716,41.927359]},"n185975317":{"id":"n185975317","loc":[-85.62475,41.93119]},"n185975318":{"id":"n185975318","loc":[-85.624782,41.934218]},"n185975320":{"id":"n185975320","loc":[-85.6247949,41.9371708]},"n185977754":{"id":"n185977754","loc":[-85.6276,41.937412]},"n185980075":{"id":"n185980075","loc":[-85.627451,41.937549]},"n185980077":{"id":"n185980077","loc":[-85.627375,41.937618]},"n185980078":{"id":"n185980078","loc":[-85.627278,41.937728]},"n185980079":{"id":"n185980079","loc":[-85.627199,41.937842]},"n185980081":{"id":"n185980081","loc":[-85.627141,41.937981]},"n185980083":{"id":"n185980083","loc":[-85.627109,41.938153]},"n185980085":{"id":"n185980085","loc":[-85.627101,41.938699]},"n185981173":{"id":"n185981173","loc":[-85.61433,41.940167]},"n185987021":{"id":"n185987021","loc":[-85.628311,41.942261]},"n185988963":{"id":"n185988963","loc":[-85.628439,41.940086]},"n185990195":{"id":"n185990195","loc":[-85.621225,41.939143]},"n185990196":{"id":"n185990196","loc":[-85.620576,41.939033]},"n185990198":{"id":"n185990198","loc":[-85.619081,41.938804]},"n185990200":{"id":"n185990200","loc":[-85.617593,41.938552]},"n185990202":{"id":"n185990202","loc":[-85.617372,41.938535]},"n185990204":{"id":"n185990204","loc":[-85.616087,41.93832]},"n185990206":{"id":"n185990206","loc":[-85.615754,41.938289]},"n185990209":{"id":"n185990209","loc":[-85.615438,41.938251]},"n185990211":{"id":"n185990211","loc":[-85.613469,41.937867]},"n185990212":{"id":"n185990212","loc":[-85.610172,41.937298]},"n185990213":{"id":"n185990213","loc":[-85.605537,41.936497]},"n185990214":{"id":"n185990214","loc":[-85.604014,41.936234]},"n1819800180":{"id":"n1819800180","loc":[-85.588775,41.9455032]},"n1819800181":{"id":"n1819800181","loc":[-85.6074212,41.9408827]},"n1819800182":{"id":"n1819800182","loc":[-85.6131397,41.9427022]},"n1819800183":{"id":"n1819800183","loc":[-85.6171523,41.9416807]},"n1819800184":{"id":"n1819800184","loc":[-85.602465,41.9397415]},"n1819800185":{"id":"n1819800185","loc":[-85.6109296,41.9410583]},"n1819800186":{"id":"n1819800186","loc":[-85.6165729,41.9418004]},"n1819800189":{"id":"n1819800189","loc":[-85.5866293,41.9458224]},"n1819800191":{"id":"n1819800191","loc":[-85.5853311,41.9466603]},"n1819800201":{"id":"n1819800201","loc":[-85.6101142,41.9433406]},"n1819800202":{"id":"n1819800202","loc":[-85.600963,41.9428618]},"n1819800206":{"id":"n1819800206","loc":[-85.6154357,41.9427501]},"n1819800207":{"id":"n1819800207","loc":[-85.6040309,41.9414094]},"n1819800209":{"id":"n1819800209","loc":[-85.6113694,41.943189]},"n1819800211":{"id":"n1819800211","loc":[-85.618032,41.9416408]},"n1819800214":{"id":"n1819800214","loc":[-85.5959419,41.9402602]},"n1819800219":{"id":"n1819800219","loc":[-85.5972117,41.9420043]},"n1819800223":{"id":"n1819800223","loc":[-85.6117171,41.9430019]},"n1819800224":{"id":"n1819800224","loc":[-85.5977873,41.9395579]},"n1819800226":{"id":"n1819800226","loc":[-85.5917362,41.9432209]},"n1819800228":{"id":"n1819800228","loc":[-85.6055759,41.9419122]},"n1819800229":{"id":"n1819800229","loc":[-85.6203395,41.9425595]},"n1819800233":{"id":"n1819800233","loc":[-85.6107579,41.9433007]},"n1819800234":{"id":"n1819800234","loc":[-85.6039773,41.9412498]},"n1819800235":{"id":"n1819800235","loc":[-85.6000977,41.9412861]},"n1819800236":{"id":"n1819800236","loc":[-85.6026689,41.9407231]},"n1819800237":{"id":"n1819800237","loc":[-85.615161,41.9428662]},"n1819800238":{"id":"n1819800238","loc":[-85.5878953,41.9454314]},"n1819800239":{"id":"n1819800239","loc":[-85.6035267,41.941569]},"n1819800240":{"id":"n1819800240","loc":[-85.5929738,41.9450208]},"n1819800241":{"id":"n1819800241","loc":[-85.6186329,41.9416488]},"n1819800242":{"id":"n1819800242","loc":[-85.5881136,41.9483963]},"n1819800243":{"id":"n1819800243","loc":[-85.5909208,41.9466922]},"n1819800244":{"id":"n1819800244","loc":[-85.5997721,41.9394941]},"n1819800245":{"id":"n1819800245","loc":[-85.6202064,41.9425712]},"n1819800246":{"id":"n1819800246","loc":[-85.591071,41.9448808]},"n1819800247":{"id":"n1819800247","loc":[-85.5866078,41.9490622]},"n1819800250":{"id":"n1819800250","loc":[-85.602383,41.9420841]},"n1819800251":{"id":"n1819800251","loc":[-85.5957418,41.9426906]},"n1819800255":{"id":"n1819800255","loc":[-85.6157039,41.9416727]},"n1819800256":{"id":"n1819800256","loc":[-85.6080328,41.9410982]},"n1819800258":{"id":"n1819800258","loc":[-85.6192551,41.9414892]},"n1819800260":{"id":"n1819800260","loc":[-85.6104253,41.94117]},"n1819800261":{"id":"n1819800261","loc":[-85.6204503,41.9425709]},"n1819800263":{"id":"n1819800263","loc":[-85.5872194,41.9455431]},"n1819800264":{"id":"n1819800264","loc":[-85.616176,41.9418244]},"n1819800268":{"id":"n1819800268","loc":[-85.6120883,41.9426703]},"n1819800269":{"id":"n1819800269","loc":[-85.5894547,41.9474946]},"n1819800272":{"id":"n1819800272","loc":[-85.6209181,41.9425027]},"n1819800274":{"id":"n1819800274","loc":[-85.6122814,41.9412817]},"n1819800276":{"id":"n1819800276","loc":[-85.5895153,41.9452798]},"n1819800277":{"id":"n1819800277","loc":[-85.5884317,41.9455272]},"n1819800279":{"id":"n1819800279","loc":[-85.5884103,41.9480966]},"n1819800287":{"id":"n1819800287","loc":[-85.5904917,41.9453915]},"n1819800288":{"id":"n1819800288","loc":[-85.6212292,41.9412977]},"n1819800289":{"id":"n1819800289","loc":[-85.5954377,41.9406832]},"n1819800290":{"id":"n1819800290","loc":[-85.593721,41.9420957]},"n1819800291":{"id":"n1819800291","loc":[-85.6162832,41.9427102]},"n1819800292":{"id":"n1819800292","loc":[-85.605018,41.9401804]},"n1819800293":{"id":"n1819800293","loc":[-85.6086443,41.941146]},"n1819800296":{"id":"n1819800296","loc":[-85.6204675,41.9413775]},"n1819800297":{"id":"n1819800297","loc":[-85.612496,41.9424947]},"n1819800299":{"id":"n1819800299","loc":[-85.6065629,41.9423431]},"n1819800301":{"id":"n1819800301","loc":[-85.6036125,41.9398452]},"n1819800303":{"id":"n1819800303","loc":[-85.6114767,41.94117]},"n1819800306":{"id":"n1819800306","loc":[-85.592616,41.9428139]},"n1819800308":{"id":"n1819800308","loc":[-85.6023041,41.9419521]},"n1819800310":{"id":"n1819800310","loc":[-85.6218944,41.9411061]},"n1819800311":{"id":"n1819800311","loc":[-85.6097816,41.941162]},"n1819800312":{"id":"n1819800312","loc":[-85.5922549,41.9457869]},"n1819800313":{"id":"n1819800313","loc":[-85.5986027,41.9417206]},"n1819800314":{"id":"n1819800314","loc":[-85.5918687,41.946138]},"n1819800315":{"id":"n1819800315","loc":[-85.5872875,41.948883]},"n1819800316":{"id":"n1819800316","loc":[-85.594272,41.9436642]},"n1819800317":{"id":"n1819800317","loc":[-85.6176351,41.941577]},"n1819800318":{"id":"n1819800318","loc":[-85.6137834,41.9430853]},"n1819800319":{"id":"n1819800319","loc":[-85.6195383,41.942622],"tags":{"leisure":"slipway"}},"n1819800320":{"id":"n1819800320","loc":[-85.5971006,41.9398053]},"n1819800321":{"id":"n1819800321","loc":[-85.601714,41.9406752]},"n1819800322":{"id":"n1819800322","loc":[-85.5908028,41.9453117]},"n1819800323":{"id":"n1819800323","loc":[-85.6062732,41.9404597]},"n1819800324":{"id":"n1819800324","loc":[-85.62124,41.9425905]},"n1819800327":{"id":"n1819800327","loc":[-85.6008664,41.942766]},"n1819800328":{"id":"n1819800328","loc":[-85.6179355,41.9428538]},"n1819800330":{"id":"n1819800330","loc":[-85.6045566,41.9415131]},"n1819800331":{"id":"n1819800331","loc":[-85.5944935,41.9414653]},"n1819800333":{"id":"n1819800333","loc":[-85.6088911,41.943181]},"n1819800334":{"id":"n1819800334","loc":[-85.5946367,41.943369]},"n1819800336":{"id":"n1819800336","loc":[-85.6150494,41.9429656]},"n1819800343":{"id":"n1819800343","loc":[-85.6096099,41.9433326]},"n1819800345":{"id":"n1819800345","loc":[-85.5915216,41.9435401]},"n1819800347":{"id":"n1819800347","loc":[-85.607786,41.9428698]},"n1819800349":{"id":"n1819800349","loc":[-85.6187616,41.9426623]},"n1819800350":{"id":"n1819800350","loc":[-85.6012527,41.9426064]},"n1819800352":{"id":"n1819800352","loc":[-85.6214867,41.9428379]},"n1819800354":{"id":"n1819800354","loc":[-85.61338,41.94293]},"n1819800355":{"id":"n1819800355","loc":[-85.5923156,41.9428139]},"n1819800357":{"id":"n1819800357","loc":[-85.5901591,41.9453197]},"n1819800359":{"id":"n1819800359","loc":[-85.6033979,41.9408827]},"n1819800360":{"id":"n1819800360","loc":[-85.6186543,41.9414653]},"n1819800363":{"id":"n1819800363","loc":[-85.6128607,41.9425665]},"n1819800365":{"id":"n1819800365","loc":[-85.614234,41.9412977]},"n1819800367":{"id":"n1819800367","loc":[-85.6089662,41.9410902]},"n1819800369":{"id":"n1819800369","loc":[-85.6197379,41.9413695]},"n1819800370":{"id":"n1819800370","loc":[-85.6037348,41.941733]},"n1819800371":{"id":"n1819800371","loc":[-85.5993467,41.9415654]},"n1819800372":{"id":"n1819800372","loc":[-85.598077,41.94196]},"n1819800373":{"id":"n1819800373","loc":[-85.5984203,41.9394781]},"n1819800374":{"id":"n1819800374","loc":[-85.6013315,41.9427066]},"n1819800376":{"id":"n1819800376","loc":[-85.5934673,41.944167]},"n1819800378":{"id":"n1819800378","loc":[-85.6011062,41.9407753]},"n1819800379":{"id":"n1819800379","loc":[-85.6150602,41.9415131]},"n1819800380":{"id":"n1819800380","loc":[-85.6132148,41.9412338]},"n1819800381":{"id":"n1819800381","loc":[-85.5889038,41.9453835]},"n2139966621":{"id":"n2139966621","loc":[-85.6198719,41.9426184]},"n2139966622":{"id":"n2139966622","loc":[-85.6197551,41.9426123]},"n2139966623":{"id":"n2139966623","loc":[-85.6196467,41.9426279]},"n2139966624":{"id":"n2139966624","loc":[-85.6191519,41.9426221]},"n2139966625":{"id":"n2139966625","loc":[-85.6194153,41.9426256]},"n2139966626":{"id":"n2139966626","loc":[-85.6200497,41.9425812]},"n2139966629":{"id":"n2139966629","loc":[-85.6192123,41.9426229]},"n2203933101":{"id":"n2203933101","loc":[-85.6030009,41.9360592]},"w17967539":{"id":"w17967539","tags":{"highway":"residential","name":"1st Ave"},"nodes":["n185965099","n185963395","n185987021"]},"w17967751":{"id":"w17967751","tags":{"highway":"residential","name":"River St"},"nodes":["n185980088","n185988961","n185988963","n185963698"]},"w17965088":{"id":"w17965088","tags":{"highway":"residential","name":"9th St"},"nodes":["n185945133","n185964320","n185964322","n185964324","n185964326","n185964328","n185964329","n185964330","n185964331"]},"w17964467":{"id":"w17964467","tags":{"highway":"residential","name":"Mechanic St"},"nodes":["n185958030","n185958032","n185958034","n185958036"]},"w134150842":{"id":"w134150842","tags":{"bridge":"yes","highway":"residential","name":"6th St"},"nodes":["n185980090","n185980093"]},"w17966740":{"id":"w17966740","tags":{"highway":"residential","name":"6th St"},"nodes":["n185977754","n185980075","n185980077","n185980078","n185980079","n185980081","n185980083","n185980085","n185958034","n185980088","n185980090"]},"w170844765":{"id":"w170844765","tags":{"waterway":"dam"},"nodes":["n1819800304","n1819800232","n1819800325","n1819800188"]},"w17967745":{"id":"w17967745","tags":{"highway":"residential","name":"River St"},"nodes":["n185981173","n185967077","n185963099","n185958498","n185988943","n185964331","n185975332"]},"w17968113":{"id":"w17968113","tags":{"highway":"residential","name":"Green St"},"nodes":["n185988943","n185991378"]},"w134150833":{"id":"w134150833","tags":{"highway":"residential","name":"6th St"},"nodes":["n185980093","n1475283999","n185963392"]},"w17967935":{"id":"w17967935","tags":{"name":"Michigan Central Railroad","railway":"abandoned"},"nodes":["n185972757","n185990192","n185990194","n185990195","n185990196","n185990198","n185990200","n185990202","n185990204","n185990206","n185990209","n185952239","n185990211","n185990212","n185990213","n185990214","n2203933101","n185973251"]},"w17965993":{"id":"w17965993","tags":{"name":"Conrail Railroad","railway":"abandoned"},"nodes":["n185957831","n185972752","n185972754","n185972756","n185972757"]},"w17966211":{"id":"w17966211","tags":{"highway":"residential","name":"8th St"},"nodes":["n185975315","n185975316","n185954490","n185945395","n185975317","n185974509","n185945135","n185975318","n185961186","n185967634","n185975320","n185970833","n185958036","n185975325","n185975326","n185975327","n185975328","n185975330","n185975332"]},"w170844766":{"id":"w170844766","tags":{"waterway":"riverbank"},"nodes":["n1819800229","n1819800245","n2139966626","n2139966621","n2139966622","n2139966623","n1819800319","n2139966625","n2139966629","n2139966624","n1819800349","n1819800328","n1819800291","n1819800206","n1819800237","n1819800336","n1819800318","n1819800354","n1819800182","n1819800363","n1819800297","n1819800268","n1819800223","n1819800209","n1819800233","n1819800201","n1819800343","n1819800333","n1819800347","n1819800299","n1819800228","n1819800330","n1819800370","n1819800250","n1819800374","n1819800202","n1819800327","n1819800350","n1819800308","n1819800239","n1819800207","n1819800234","n1819800359","n1819800236","n1819800321","n1819800378","n1819800235","n1819800371","n1819800313","n1819800372","n1819800219","n1819800251","n1819800334","n1819800316","n1819800376","n1819800240","n1819800312","n1819800314","n1819800243","n1819800269","n1819800279","n1819800242","n1819800315","n1819800247","n1819800191","n1819800189","n1819800263","n1819800238","n1819800277","n1819800180","n1819800381","n1819800276","n1819800357","n1819800287","n1819800322","n1819800246","n1819800345","n1819800226","n1819800355","n1819800306","n1819800290","n1819800331","n1819800289","n1819800214","n1819800320","n1819800224","n1819800373","n1819800244","n1819800184","n1819800301","n1819800292","n1819800323","n1819800181","n1819800256","n1819800293","n1819800367","n1819800311","n1819800260","n1819800185","n1819800303","n1819800274","n1819800380","n1819800365","n1819800379","n1819800255","n1819800264","n1819800186","n1819800183","n1819800317","n1819800211","n1819800241","n1819800360","n1819800258","n1819800369","n1819800296","n1819800288","n1819800310","n1819800204","n1819800375","n1819800216","n1819800377","n1819800248","n1819800227","n1819800368","n1819800231","n1819800188","n1819800325","n1819800232","n1819800304","n1819800271","n1819800213","n1819800266","n1819800221","n1819800294","n1819800362","n1819800199","n1819800230","n1819800218","n1819800352","n1819800324","n1819800272","n1819800261","n1819800229"]},"n1875654132":{"id":"n1875654132","loc":[-85.6297439,41.939808]},"n1475293263":{"id":"n1475293263","loc":[-85.6296235,41.939922]},"n185947850":{"id":"n185947850","loc":[-85.631594,41.942613]},"n185952745":{"id":"n185952745","loc":[-85.630986,41.941786]},"n185972907":{"id":"n185972907","loc":[-85.631797,41.9420055]},"n185972911":{"id":"n185972911","loc":[-85.6309723,41.9411623]},"n185972915":{"id":"n185972915","loc":[-85.6295971,41.939267]},"n1475293223":{"id":"n1475293223","loc":[-85.6313962,41.9416114],"tags":{"railway":"level_crossing"}},"n1475293231":{"id":"n1475293231","loc":[-85.6318779,41.9415447]},"n1475293241":{"id":"n1475293241","loc":[-85.6304613,41.9405499]},"n1475293246":{"id":"n1475293246","loc":[-85.6297512,41.9395393],"tags":{"railway":"level_crossing"}},"n1475293251":{"id":"n1475293251","loc":[-85.6316633,41.9415128]},"n2139982404":{"id":"n2139982404","loc":[-85.6313283,41.9413748]},"n2139982407":{"id":"n2139982407","loc":[-85.6325545,41.9417787]},"n2139982408":{"id":"n2139982408","loc":[-85.6324499,41.9417693]},"n2139982409":{"id":"n2139982409","loc":[-85.6324753,41.9416444]},"n2139982410":{"id":"n2139982410","loc":[-85.6325814,41.9416538]},"n2139982411":{"id":"n2139982411","loc":[-85.6319572,41.9413515]},"n2139982412":{"id":"n2139982412","loc":[-85.6322925,41.941139]},"n2139982413":{"id":"n2139982413","loc":[-85.6323153,41.941153]},"n2139982414":{"id":"n2139982414","loc":[-85.6323019,41.9412617]},"n2139982415":{"id":"n2139982415","loc":[-85.6323703,41.9412667]},"n2139982416":{"id":"n2139982416","loc":[-85.6323555,41.941538]},"n2139982417":{"id":"n2139982417","loc":[-85.6321343,41.9416777]},"n2139982418":{"id":"n2139982418","loc":[-85.6319425,41.9416866]},"n2139982419":{"id":"n2139982419","loc":[-85.6320303,41.9416941]},"n2139982420":{"id":"n2139982420","loc":[-85.6321665,41.9415554]},"n2139982421":{"id":"n2139982421","loc":[-85.632412,41.9414164]},"n2139982422":{"id":"n2139982422","loc":[-85.6324801,41.9413421]},"n2139982423":{"id":"n2139982423","loc":[-85.6325023,41.9412585]},"n2139982424":{"id":"n2139982424","loc":[-85.6324532,41.9411607]},"n2139982425":{"id":"n2139982425","loc":[-85.6323502,41.941103]},"n2139982426":{"id":"n2139982426","loc":[-85.6322362,41.9411183]},"n2139982427":{"id":"n2139982427","loc":[-85.6318941,41.9413551]},"n2139982428":{"id":"n2139982428","loc":[-85.6318592,41.9414105]},"n2139982429":{"id":"n2139982429","loc":[-85.6320111,41.9415866]},"n2139982430":{"id":"n2139982430","loc":[-85.632446,41.9413792]},"n2139982431":{"id":"n2139982431","loc":[-85.6325112,41.941416]},"n2139982432":{"id":"n2139982432","loc":[-85.6325449,41.9416345]},"n2139982433":{"id":"n2139982433","loc":[-85.6326122,41.94164]},"n2139982434":{"id":"n2139982434","loc":[-85.6325954,41.9421966]},"n2139982435":{"id":"n2139982435","loc":[-85.6325655,41.9422411]},"n2139982436":{"id":"n2139982436","loc":[-85.632515,41.9422564]},"n2139982437":{"id":"n2139982437","loc":[-85.6324495,41.94223]},"n2139982438":{"id":"n2139982438","loc":[-85.6324009,41.9421743]},"n2139982439":{"id":"n2139982439","loc":[-85.6323915,41.9421145]},"n2139982440":{"id":"n2139982440","loc":[-85.6320287,41.9418585]},"n2139982441":{"id":"n2139982441","loc":[-85.6318285,41.9416387]},"n1475293258":{"id":"n1475293258","loc":[-85.6318289,41.9415077]},"n2168544754":{"id":"n2168544754","loc":[-85.6312814,41.9431198]},"n2168544755":{"id":"n2168544755","loc":[-85.6314212,41.9430646]},"n2168544756":{"id":"n2168544756","loc":[-85.6313387,41.942949]},"n2168544757":{"id":"n2168544757","loc":[-85.6311989,41.9430041]},"n2168544758":{"id":"n2168544758","loc":[-85.6311024,41.9429313]},"n2168544759":{"id":"n2168544759","loc":[-85.6310087,41.9428087]},"n2168544760":{"id":"n2168544760","loc":[-85.6313831,41.9426504]},"n2168544761":{"id":"n2168544761","loc":[-85.6314768,41.9427729]},"n2168544762":{"id":"n2168544762","loc":[-85.6306376,41.942809]},"n2168544763":{"id":"n2168544763","loc":[-85.6307378,41.9429427]},"n2168544764":{"id":"n2168544764","loc":[-85.630841,41.9428998]},"n2168544765":{"id":"n2168544765","loc":[-85.6307408,41.9427662]},"n2168544766":{"id":"n2168544766","loc":[-85.6305404,41.9426029]},"n2168544767":{"id":"n2168544767","loc":[-85.6304976,41.9426194]},"n2168544768":{"id":"n2168544768","loc":[-85.6305673,41.9427184]},"n2168544769":{"id":"n2168544769","loc":[-85.6306164,41.9426984]},"n2168544770":{"id":"n2168544770","loc":[-85.6306418,41.9427302]},"n2168544771":{"id":"n2168544771","loc":[-85.6306861,41.9427137]},"n2168544772":{"id":"n2168544772","loc":[-85.6307146,41.9427537]},"n2168544773":{"id":"n2168544773","loc":[-85.6308999,41.9426807]},"n2168544774":{"id":"n2168544774","loc":[-85.6308429,41.9426053]},"n2168544775":{"id":"n2168544775","loc":[-85.6308999,41.9425806]},"n2168544776":{"id":"n2168544776","loc":[-85.6308318,41.9424875]},"n2168544777":{"id":"n2168544777","loc":[-85.6307732,41.9425087]},"n2168544778":{"id":"n2168544778","loc":[-85.6307178,41.9424357]},"n2168544779":{"id":"n2168544779","loc":[-85.630485,41.942524]},"n2189099387":{"id":"n2189099387","loc":[-85.631203,41.9393371]},"n2189099404":{"id":"n2189099404","loc":[-85.6301963,41.9391363]},"n2189099405":{"id":"n2189099405","loc":[-85.6304447,41.9391352]},"n2189099406":{"id":"n2189099406","loc":[-85.6304463,41.9393391]},"n2189099407":{"id":"n2189099407","loc":[-85.6308435,41.9393373]},"n2189099408":{"id":"n2189099408","loc":[-85.6308418,41.9391251]},"n2189099409":{"id":"n2189099409","loc":[-85.6310929,41.939124]},"n2189099410":{"id":"n2189099410","loc":[-85.6310946,41.9393376]},"n2189112720":{"id":"n2189112720","loc":[-85.6314677,41.9412327]},"n2189112721":{"id":"n2189112721","loc":[-85.6313337,41.9411397]},"n2189112722":{"id":"n2189112722","loc":[-85.6320521,41.9405678]},"n2189112723":{"id":"n2189112723","loc":[-85.6321899,41.9406633]},"n2189112724":{"id":"n2189112724","loc":[-85.6313229,41.9408344]},"n2189112725":{"id":"n2189112725","loc":[-85.6311223,41.9410018]},"n2189112726":{"id":"n2189112726","loc":[-85.6313205,41.9411333]},"n2189112727":{"id":"n2189112727","loc":[-85.6315211,41.9409659]},"n2189112728":{"id":"n2189112728","loc":[-85.6311035,41.9402529]},"n2189112729":{"id":"n2189112729","loc":[-85.631226,41.9402107]},"n2189112730":{"id":"n2189112730","loc":[-85.6315966,41.9408051]},"n2189112731":{"id":"n2189112731","loc":[-85.6314741,41.9408473]},"n2189112732":{"id":"n2189112732","loc":[-85.6318114,41.940534]},"n2189112733":{"id":"n2189112733","loc":[-85.631588,41.94061]},"n2189112734":{"id":"n2189112734","loc":[-85.6314379,41.940366]},"n2189112735":{"id":"n2189112735","loc":[-85.6316613,41.94029]},"n2189112736":{"id":"n2189112736","loc":[-85.6306214,41.9400415]},"n2189112737":{"id":"n2189112737","loc":[-85.6304362,41.9397728]},"n2189112738":{"id":"n2189112738","loc":[-85.6305899,41.9397142]},"n2189112739":{"id":"n2189112739","loc":[-85.6307751,41.9399828]},"n2189112740":{"id":"n2189112740","loc":[-85.6304695,41.9401673]},"n2189112741":{"id":"n2189112741","loc":[-85.6301298,41.9396855]},"n2189112742":{"id":"n2189112742","loc":[-85.6303016,41.9396184]},"n2189112743":{"id":"n2189112743","loc":[-85.6306413,41.9401003]},"n2189112744":{"id":"n2189112744","loc":[-85.6309656,41.9406189]},"n2189112745":{"id":"n2189112745","loc":[-85.6308738,41.940493]},"n2189112746":{"id":"n2189112746","loc":[-85.6309333,41.940469]},"n2189112747":{"id":"n2189112747","loc":[-85.6307634,41.9402358]},"n2189112748":{"id":"n2189112748","loc":[-85.6308798,41.9401889]},"n2189112749":{"id":"n2189112749","loc":[-85.6311416,41.940548]},"n2189112750":{"id":"n2189112750","loc":[-85.6309577,41.9408708]},"n2189112751":{"id":"n2189112751","loc":[-85.630874,41.9407777]},"n2189112752":{"id":"n2189112752","loc":[-85.6310622,41.9406841]},"n2189112753":{"id":"n2189112753","loc":[-85.6311459,41.9407772]},"n2189112754":{"id":"n2189112754","loc":[-85.6320308,41.9405747]},"n2189112755":{"id":"n2189112755","loc":[-85.6317769,41.9401857]},"n2189112756":{"id":"n2189112756","loc":[-85.6313462,41.9401785]},"n2189112757":{"id":"n2189112757","loc":[-85.6313423,41.9401199]},"n2189112758":{"id":"n2189112758","loc":[-85.6318308,41.9401184]},"n2189112759":{"id":"n2189112759","loc":[-85.6321154,41.9405433]},"n2189112760":{"id":"n2189112760","loc":[-85.6310307,41.941683]},"n2189112761":{"id":"n2189112761","loc":[-85.6309808,41.9416078]},"n2189112762":{"id":"n2189112762","loc":[-85.6312094,41.9415156]},"n2189112763":{"id":"n2189112763","loc":[-85.6312636,41.9415865]},"n2189112764":{"id":"n2189112764","loc":[-85.6309384,41.94155]},"n2189112765":{"id":"n2189112765","loc":[-85.631156,41.9414619]},"n2189112766":{"id":"n2189112766","loc":[-85.6311968,41.94152]},"n2189112767":{"id":"n2189112767","loc":[-85.6308946,41.9414851]},"n2189112768":{"id":"n2189112768","loc":[-85.6308237,41.9413888]},"n2189112769":{"id":"n2189112769","loc":[-85.6309858,41.9413228]},"n2189112770":{"id":"n2189112770","loc":[-85.6310567,41.9414192]},"n2189112771":{"id":"n2189112771","loc":[-85.6307774,41.9413276]},"n2189112772":{"id":"n2189112772","loc":[-85.6309068,41.9412735]},"n2189112773":{"id":"n2189112773","loc":[-85.6309531,41.9413347]},"n2189112774":{"id":"n2189112774","loc":[-85.6307975,41.9412466]},"n2189112775":{"id":"n2189112775","loc":[-85.6307006,41.9411699]},"n2189112776":{"id":"n2189112776","loc":[-85.6308289,41.941113]},"n2189112777":{"id":"n2189112777","loc":[-85.6308997,41.9412012]},"n2189112778":{"id":"n2189112778","loc":[-85.630765,41.9412062]},"n2189112779":{"id":"n2189112779","loc":[-85.630739,41.9412177]},"n2189112780":{"id":"n2189112780","loc":[-85.6305822,41.9410391]},"n2189112781":{"id":"n2189112781","loc":[-85.6304117,41.9408177]},"n2189112782":{"id":"n2189112782","loc":[-85.6305086,41.9407769]},"n2189112783":{"id":"n2189112783","loc":[-85.6306779,41.9410044]},"n2189112784":{"id":"n2189112784","loc":[-85.6307734,41.9421663]},"n2189112785":{"id":"n2189112785","loc":[-85.630708,41.9420741]},"n2189112786":{"id":"n2189112786","loc":[-85.630863,41.9420133]},"n2189112787":{"id":"n2189112787","loc":[-85.6309285,41.9421055]},"n2189112788":{"id":"n2189112788","loc":[-85.6307014,41.9420263]},"n2189112789":{"id":"n2189112789","loc":[-85.6306648,41.941971]},"n2189112790":{"id":"n2189112790","loc":[-85.6307927,41.9419178]},"n2189112791":{"id":"n2189112791","loc":[-85.6308366,41.9419696]},"n2189112792":{"id":"n2189112792","loc":[-85.6307574,41.9418708]},"n2189112793":{"id":"n2189112793","loc":[-85.6306288,41.9419231]},"n2189112794":{"id":"n2189112794","loc":[-85.6306943,41.9417835]},"n2189112795":{"id":"n2189112795","loc":[-85.6305344,41.9418474]},"n2189112796":{"id":"n2189112796","loc":[-85.6305981,41.9419355]},"n2189123410":{"id":"n2189123410","loc":[-85.6315476,41.9393801]},"n2189123412":{"id":"n2189123412","loc":[-85.6315247,41.9399188]},"n2189123415":{"id":"n2189123415","loc":[-85.6316484,41.9400433]},"n185945138":{"id":"n185945138","loc":[-85.627073,41.93319]},"n185945142":{"id":"n185945142","loc":[-85.6296891,41.9331674]},"n185945401":{"id":"n185945401","loc":[-85.6269,41.930199]},"n185945405":{"id":"n185945405","loc":[-85.6296598,41.9301676]},"n185956891":{"id":"n185956891","loc":[-85.6251617,41.9255049]},"n185959979":{"id":"n185959979","loc":[-85.626333,41.928347]},"n185959983":{"id":"n185959983","loc":[-85.6296419,41.9283288]},"n185961192":{"id":"n185961192","loc":[-85.627053,41.9352031]},"n185961200":{"id":"n185961200","loc":[-85.6297088,41.9351902]},"n185963655":{"id":"n185963655","loc":[-85.6296112,41.9273948]},"n185963665":{"id":"n185963665","loc":[-85.626047,41.92737]},"n185963688":{"id":"n185963688","loc":[-85.6296503,41.9292199]},"n185963689":{"id":"n185963689","loc":[-85.6296694,41.931157]},"n185963690":{"id":"n185963690","loc":[-85.6296791,41.9321485]},"n185963691":{"id":"n185963691","loc":[-85.6296991,41.9341973]},"n185967638":{"id":"n185967638","loc":[-85.627089,41.9361884]},"n185972917":{"id":"n185972917","loc":[-85.6293759,41.9388605]},"n185972919":{"id":"n185972919","loc":[-85.6290337,41.9380234]},"n185972921":{"id":"n185972921","loc":[-85.628424,41.936212]},"n185972923":{"id":"n185972923","loc":[-85.628367,41.936029]},"n185974511":{"id":"n185974511","loc":[-85.627064,41.932169]},"n185977728":{"id":"n185977728","loc":[-85.625605,41.925842]},"n185977729":{"id":"n185977729","loc":[-85.625685,41.926163]},"n185977731":{"id":"n185977731","loc":[-85.6257845,41.9264872]},"n185977733":{"id":"n185977733","loc":[-85.62663,41.929251]},"n185977734":{"id":"n185977734","loc":[-85.627008,41.930642]},"n185977736":{"id":"n185977736","loc":[-85.627029,41.930775]},"n185977738":{"id":"n185977738","loc":[-85.627041,41.930946]},"n185977739":{"id":"n185977739","loc":[-85.6270379,41.9311746]},"n185977742":{"id":"n185977742","loc":[-85.627055,41.934206]},"n185977744":{"id":"n185977744","loc":[-85.627084,41.936804]},"n185977746":{"id":"n185977746","loc":[-85.627104,41.936914]},"n185977748":{"id":"n185977748","loc":[-85.627156,41.937026]},"n185977750":{"id":"n185977750","loc":[-85.6272406,41.9371672]},"n185977752":{"id":"n185977752","loc":[-85.627317,41.93723]},"n185977753":{"id":"n185977753","loc":[-85.627422,41.937312]},"n185977755":{"id":"n185977755","loc":[-85.627754,41.937504]},"n185977757":{"id":"n185977757","loc":[-85.627883,41.937623]},"n185977761":{"id":"n185977761","loc":[-85.627984,41.93773]},"n1475283996":{"id":"n1475283996","loc":[-85.6270514,41.9317122],"tags":{"railway":"level_crossing"}},"n1475284004":{"id":"n1475284004","loc":[-85.6278177,41.9342117],"tags":{"railway":"level_crossing"}},"n1475284014":{"id":"n1475284014","loc":[-85.6251877,41.9255913],"tags":{"railway":"level_crossing"}},"n1475284017":{"id":"n1475284017","loc":[-85.6274992,41.9331816],"tags":{"railway":"level_crossing"}},"n1475284021":{"id":"n1475284021","loc":[-85.6297108,41.9353939],"tags":{"railway":"level_crossing"}},"n1475284027":{"id":"n1475284027","loc":[-85.62811,41.935198],"tags":{"railway":"level_crossing"}},"n1475284035":{"id":"n1475284035","loc":[-85.626888,41.9311757],"tags":{"railway":"level_crossing"}},"n1475293245":{"id":"n1475293245","loc":[-85.6286047,41.9367881]},"n1875654302":{"id":"n1875654302","loc":[-85.6296367,41.927491]},"n2189099388":{"id":"n2189099388","loc":[-85.6312007,41.9389988]},"n2189099389":{"id":"n2189099389","loc":[-85.6311003,41.9389992]},"n2189099390":{"id":"n2189099390","loc":[-85.6310988,41.9387847]},"n2189099391":{"id":"n2189099391","loc":[-85.6312165,41.9387843]},"n2189099392":{"id":"n2189099392","loc":[-85.6312152,41.9385857]},"n2189099393":{"id":"n2189099393","loc":[-85.6310877,41.9385862]},"n2189099394":{"id":"n2189099394","loc":[-85.6310858,41.9383161]},"n2189099395":{"id":"n2189099395","loc":[-85.6302002,41.9383196]},"n2189099396":{"id":"n2189099396","loc":[-85.6302011,41.9384472]},"n2189099397":{"id":"n2189099397","loc":[-85.6301018,41.9384476]},"n2189099398":{"id":"n2189099398","loc":[-85.6301025,41.9385419]},"n2189099399":{"id":"n2189099399","loc":[-85.6299275,41.9385427]},"n2189099400":{"id":"n2189099400","loc":[-85.62993,41.9388653]},"n2189099401":{"id":"n2189099401","loc":[-85.630107,41.9388645]},"n2189099402":{"id":"n2189099402","loc":[-85.6301079,41.9389908]},"n2189099403":{"id":"n2189099403","loc":[-85.6301951,41.9389904]},"n2189123382":{"id":"n2189123382","loc":[-85.6336279,41.9354365]},"n2189123384":{"id":"n2189123384","loc":[-85.6328492,41.9355177]},"n2189123387":{"id":"n2189123387","loc":[-85.6323762,41.9357396]},"n2189123388":{"id":"n2189123388","loc":[-85.6315174,41.9358966]},"n2189123389":{"id":"n2189123389","loc":[-85.6304331,41.936124]},"n2189123390":{"id":"n2189123390","loc":[-85.6302075,41.9364271]},"n2189123391":{"id":"n2189123391","loc":[-85.6303458,41.9367953]},"n2189123392":{"id":"n2189123392","loc":[-85.6299601,41.9369739]},"n2189123393":{"id":"n2189123393","loc":[-85.6299164,41.9374882]},"n2189123394":{"id":"n2189123394","loc":[-85.6299455,41.9378022]},"n2189123395":{"id":"n2189123395","loc":[-85.6299771,41.9379053]},"n2189123396":{"id":"n2189123396","loc":[-85.6301597,41.9379091]},"n2189123397":{"id":"n2189123397","loc":[-85.6308042,41.9377913]},"n2189123398":{"id":"n2189123398","loc":[-85.6316885,41.9378082]},"n2189123399":{"id":"n2189123399","loc":[-85.6316848,41.9380079]},"n2189123400":{"id":"n2189123400","loc":[-85.6318449,41.9381161]},"n2189123401":{"id":"n2189123401","loc":[-85.6320705,41.9381811]},"n2189123402":{"id":"n2189123402","loc":[-85.6321433,41.9383706]},"n2189123404":{"id":"n2189123404","loc":[-85.632056,41.9384355]},"n2189123406":{"id":"n2189123406","loc":[-85.6317867,41.9384572]},"n2189123409":{"id":"n2189123409","loc":[-85.6316572,41.9387281]},"n2189123417":{"id":"n2189123417","loc":[-85.6315946,41.93775]},"n2189123419":{"id":"n2189123419","loc":[-85.6302641,41.9378393]},"w208640158":{"id":"w208640158","tags":{"area":"yes","natural":"wetland"},"nodes":["n2189123379","n2189123382","n2189123384","n2189123387","n2189123388","n2189123389","n2189123390","n2189123391","n2189123392","n2189123393","n2189123394","n2189123395","n2189123396","n2189123419","n2189123397","n2189123417","n2189123398","n2189123399","n2189123400","n2189123401","n2189123402","n2189123404","n2189123406","n2189123409","n2189123410","n2189123412","n2189123415","n1819805722","n1819805861","n1819805887","n1819805760","n1819805641","n1819805632","n2189123379"]},"w134150787":{"id":"w134150787","tags":{"name":"Conrail Railroad","railway":"rail"},"nodes":["n185972905","n185972907","n1475293223","n185972911","n1475293241","n1475293246","n185972915","n185972917","n185972919","n1475293245","n185972921","n185972923","n1475284027","n1475284004","n1475284017","n1475283996","n1475284035","n1475284014","n185956891"]},"w208639443":{"id":"w208639443","tags":{"area":"yes","building":"yes"},"nodes":["n2189112720","n2189112721","n2189112722","n2189112723","n2189112720"]},"w17966462":{"id":"w17966462","tags":{"highway":"secondary","name":"South Main Street","old_ref":"US 131","ref":"M 86"},"nodes":["n185977728","n185977729","n185977731","n185963665","n185959979","n185977733","n185945401","n185977734","n185977736","n185977738","n185977739","n1475283996","n185974511","n185945138","n185977742","n185961192","n185967638","n185977744","n185977746","n185977748","n185977750","n185977752","n185977753","n185977754","n185977755","n185977757","n185977761","n185958030","n1475293263","n185963698","n185952745","n185947850","n185977762"]},"w203985741":{"id":"w203985741","tags":{"area":"yes","leisure":"park","name":"Conservation Park"},"nodes":["n2139982404","n2139982405","n2139982399","n2139982400","n1819805770","n2139982402","n2139982403","n2139982401","n1819805780","n1819805834","n2139982406","n2139982404"]},"w17963676":{"id":"w17963676","tags":{"highway":"service"},"nodes":["n1475293258","n2139982428","n2139982427","n2139982426","n2139982425","n2139982424","n2139982423","n2139982422","n2139982430","n2139982421","n2139982420","n2139982429","n1475293231","n1475293258","n1475293251","n1475293223","n185952745"]},"w203985745":{"id":"w203985745","tags":{"highway":"footway"},"nodes":["n2139982430","n2139982431","n2139982432","n2139982433","n2139982434","n2139982435","n2139982436","n2139982437","n2139982438","n2139982439","n2139982440","n2139982441","n1475293231"]},"w208639451":{"id":"w208639451","tags":{"area":"yes","building":"yes"},"nodes":["n2189112754","n2189112755","n2189112756","n2189112757","n2189112758","n2189112759","n2189112754"]},"w208639452":{"id":"w208639452","tags":{"area":"yes","building":"yes"},"nodes":["n2189112760","n2189112761","n2189112766","n2189112762","n2189112763","n2189112760"]},"w206805244":{"id":"w206805244","tags":{"area":"yes","building":"yes"},"nodes":["n2168544766","n2168544767","n2168544768","n2168544769","n2168544770","n2168544771","n2168544772","n2168544773","n2168544774","n2168544775","n2168544776","n2168544777","n2168544778","n2168544779","n2168544766"]},"w208639444":{"id":"w208639444","tags":{"area":"yes","building":"yes"},"nodes":["n2189112724","n2189112725","n2189112726","n2189112727","n2189112724"]},"w208639450":{"id":"w208639450","tags":{"area":"yes","building":"yes"},"nodes":["n2189112750","n2189112751","n2189112752","n2189112753","n2189112750"]},"w208639448":{"id":"w208639448","tags":{"area":"yes","building":"yes"},"nodes":["n2189112740","n2189112741","n2189112742","n2189112743","n2189112740"]},"w208637859":{"id":"w208637859","tags":{"area":"yes","building":"yes"},"nodes":["n2189099387","n2189099388","n2189099389","n2189099390","n2189099391","n2189099392","n2189099393","n2189099394","n2189099395","n2189099396","n2189099397","n2189099398","n2189099399","n2189099400","n2189099401","n2189099402","n2189099403","n2189099404","n2189099405","n2189099406","n2189099407","n2189099408","n2189099409","n2189099410","n2189099387"]},"w208639453":{"id":"w208639453","tags":{"area":"yes","building":"yes"},"nodes":["n2189112764","n2189112765","n2189112766","n2189112761","n2189112764"]},"w208639456":{"id":"w208639456","tags":{"area":"yes","building":"yes"},"nodes":["n2189112774","n2189112778","n2189112779","n2189112775","n2189112776","n2189112777","n2189112774"]},"w208639445":{"id":"w208639445","tags":{"area":"yes","building":"yes"},"nodes":["n2189112728","n2189112729","n2189112730","n2189112731","n2189112728"]},"w17967776":{"id":"w17967776","tags":{"highway":"residential","name":"5th St"},"nodes":["n185958032","n185988963"]},"w208639461":{"id":"w208639461","tags":{"area":"yes","building":"yes"},"nodes":["n2189112792","n2189112794","n2189112795","n2189112796","n2189112793","n2189112792"]},"w206805241":{"id":"w206805241","tags":{"area":"yes","building":"yes"},"nodes":["n2168544754","n2168544755","n2168544756","n2168544757","n2168544754"]},"w208639449":{"id":"w208639449","tags":{"area":"yes","building":"yes"},"nodes":["n2189112744","n2189112745","n2189112746","n2189112747","n2189112748","n2189112749","n2189112744"]},"w208639455":{"id":"w208639455","tags":{"area":"yes","building":"yes"},"nodes":["n2189112771","n2189112772","n2189112773","n2189112768","n2189112771"]},"w208639457":{"id":"w208639457","tags":{"area":"yes","building":"yes"},"nodes":["n2189112780","n2189112781","n2189112782","n2189112783","n2189112780"]},"w208639446":{"id":"w208639446","tags":{"area":"yes","building":"yes"},"nodes":["n2189112732","n2189112733","n2189112734","n2189112735","n2189112732"]},"w208639454":{"id":"w208639454","tags":{"area":"yes","building":"yes"},"nodes":["n2189112767","n2189112768","n2189112773","n2189112769","n2189112770","n2189112767"]},"w203985743":{"id":"w203985743","tags":{"amenity":"parking","area":"yes"},"nodes":["n2139982411","n2139982412","n2139982413","n2139982414","n2139982415","n2139982416","n2139982417","n2139982419","n2139982418","n2139982411"]},"w17965023":{"id":"w17965023","tags":{"highway":"residential","name":"4th St"},"nodes":["n185963655","n1875654302","n185959983","n185963688","n185945405","n185963689","n185963690","n185945142","n185963691","n185961200","n1475284021","n1475293246","n1875654132","n1475293263"]},"w206805242":{"id":"w206805242","tags":{"area":"yes","building":"yes"},"nodes":["n2168544758","n2168544759","n2168544760","n2168544761","n2168544758"]},"w208639460":{"id":"w208639460","tags":{"area":"yes","building":"yes"},"nodes":["n2189112792","n2189112793","n2189112789","n2189112790","n2189112792"]},"w208639447":{"id":"w208639447","tags":{"area":"yes","building":"yes"},"nodes":["n2189112736","n2189112737","n2189112738","n2189112739","n2189112736"]},"w208639458":{"id":"w208639458","tags":{"area":"yes","building":"yes"},"nodes":["n2189112784","n2189112785","n2189112786","n2189112787","n2189112784"]},"w203985744":{"id":"w203985744","tags":{"highway":"service"},"nodes":["n2139982425","n2139982400"]},"w208639459":{"id":"w208639459","tags":{"area":"yes","building":"yes"},"nodes":["n2189112788","n2189112789","n2189112790","n2189112791","n2189112788"]},"w203985742":{"id":"w203985742","tags":{"amenity":"shelter","area":"yes","shelter_type":"picnic_shelter"},"nodes":["n2139982407","n2139982408","n2139982409","n2139982410","n2139982407"]},"w206805243":{"id":"w206805243","tags":{"area":"yes","building":"yes"},"nodes":["n2168544762","n2168544763","n2168544764","n2168544765","n2168544762"]},"n185959081":{"id":"n185959081","loc":[-85.628469,41.948674]},"n185967427":{"id":"n185967427","loc":[-85.632054,41.951174]},"n185967424":{"id":"n185967424","loc":[-85.6320391,41.9499109]},"n185968101":{"id":"n185968101","loc":[-85.6308395,41.9511969]},"n185960792":{"id":"n185960792","loc":[-85.632074,41.953707]},"n185961389":{"id":"n185961389","loc":[-85.630935,41.959037]},"n185961391":{"id":"n185961391","loc":[-85.632169,41.959025]},"n185965395":{"id":"n185965395","loc":[-85.63216,41.959859]},"n185966953":{"id":"n185966953","loc":[-85.630894,41.957428]},"n185966955":{"id":"n185966955","loc":[-85.632122,41.957427]},"n185967430":{"id":"n185967430","loc":[-85.632077,41.952453]},"n185967432":{"id":"n185967432","loc":[-85.632095,41.954685]},"n185967434":{"id":"n185967434","loc":[-85.632121,41.955914]},"n185967436":{"id":"n185967436","loc":[-85.632128,41.9583]},"n185967438":{"id":"n185967438","loc":[-85.632187,41.960681]},"n185967440":{"id":"n185967440","loc":[-85.632182,41.961493]},"n185968102":{"id":"n185968102","loc":[-85.630855,41.952452]},"n185968104":{"id":"n185968104","loc":[-85.630887,41.953714]},"n185968106":{"id":"n185968106","loc":[-85.630883,41.954692]},"n185968108":{"id":"n185968108","loc":[-85.630904,41.955913]},"n185968110":{"id":"n185968110","loc":[-85.630904,41.958058]},"n185968112":{"id":"n185968112","loc":[-85.630952,41.960667]},"n185968114":{"id":"n185968114","loc":[-85.630972,41.961495]},"n185968116":{"id":"n185968116","loc":[-85.630962,41.961967]},"n185978969":{"id":"n185978969","loc":[-85.633214,41.948618]},"n185985812":{"id":"n185985812","loc":[-85.633274,41.951159]},"n185986155":{"id":"n185986155","loc":[-85.633258,41.949893]},"n2208608826":{"id":"n2208608826","loc":[-85.6339222,41.9486225]},"w17964531":{"id":"w17964531","tags":{"highway":"residential","name":"Willow Dr"},"nodes":["n185959079","n185959081"]},"w17967386":{"id":"w17967386","tags":{"highway":"residential","name":"East Armitage Street"},"nodes":["n185982195","n185968101","n185967427","n185985812","n185974583"]},"w17965502":{"id":"w17965502","tags":{"highway":"residential","name":"Elm Street"},"nodes":["n185968100","n185968101","n185968102","n185968104","n185968106","n185968108","n185966953","n185968110","n185961389","n185968112","n185968114","n185968116"]},"w17967844":{"id":"w17967844","tags":{"highway":"residential","name":"East Bennett Street"},"nodes":["n185982193","n185967424","n185986155","n185978390"]},"w17966581":{"id":"w17966581","tags":{"highway":"residential","name":"E Kelsey St"},"nodes":["n185978967","n185978969","n2208608826","n185971578"]},"w17965402":{"id":"w17965402","tags":{"highway":"residential","name":"Walnut Street"},"nodes":["n185967422","n185967424","n185967427","n185967430","n185960792","n185967432","n185967434","n185966955","n185967436","n185961391","n185965395","n185967438","n185967440"]},"n2199093506":{"id":"n2199093506","loc":[-85.6251879,41.9478322]},"n2199093505":{"id":"n2199093505","loc":[-85.6252076,41.9477749]},"n2199093504":{"id":"n2199093504","loc":[-85.6252289,41.9477602]},"n2199093503":{"id":"n2199093503","loc":[-85.625201,41.9477492]},"n2199093502":{"id":"n2199093502","loc":[-85.6251682,41.9477066]},"n2199093501":{"id":"n2199093501","loc":[-85.6251715,41.947609]},"n2199093500":{"id":"n2199093500","loc":[-85.6252125,41.9475639]},"n2199093499":{"id":"n2199093499","loc":[-85.6252896,41.9475602]},"n2199093498":{"id":"n2199093498","loc":[-85.6253027,41.9475334]},"n2199093497":{"id":"n2199093497","loc":[-85.6253437,41.9474822]},"n2199093496":{"id":"n2199093496","loc":[-85.6254421,41.9474675]},"n2199093495":{"id":"n2199093495","loc":[-85.6256503,41.9474944]},"n2199093494":{"id":"n2199093494","loc":[-85.6257257,41.9476127]},"n2199093493":{"id":"n2199093493","loc":[-85.6257028,41.9477285]},"n2199093492":{"id":"n2199093492","loc":[-85.6255339,41.9478102]},"n2199093491":{"id":"n2199093491","loc":[-85.6253912,41.9478224]},"n2199093490":{"id":"n2199093490","loc":[-85.6253043,41.947859]},"n2199093489":{"id":"n2199093489","loc":[-85.6252027,41.9478846]},"n2199093458":{"id":"n2199093458","loc":[-85.6246876,41.9486617]},"n2199093457":{"id":"n2199093457","loc":[-85.6243127,41.9486583]},"n2199093456":{"id":"n2199093456","loc":[-85.624306,41.9490569]},"n2199093455":{"id":"n2199093455","loc":[-85.624681,41.9490603]},"n2199093514":{"id":"n2199093514","loc":[-85.6236228,41.9496059]},"n2199093513":{"id":"n2199093513","loc":[-85.6236231,41.9496997]},"n2199093512":{"id":"n2199093512","loc":[-85.623357,41.9497002]},"n2199093511":{"id":"n2199093511","loc":[-85.6233567,41.9496136]},"n2199093508":{"id":"n2199093508","loc":[-85.6239735,41.9494287]},"n2199093507":{"id":"n2199093507","loc":[-85.6239741,41.9496052]},"n2199093488":{"id":"n2199093488","loc":[-85.624497,41.9512286]},"n2199093487":{"id":"n2199093487","loc":[-85.6244966,41.9511259]},"n2199093486":{"id":"n2199093486","loc":[-85.6243151,41.9511263]},"n2199093485":{"id":"n2199093485","loc":[-85.6243154,41.951229]},"n2199093484":{"id":"n2199093484","loc":[-85.6241205,41.9508665]},"n2199093483":{"id":"n2199093483","loc":[-85.624115,41.9505249]},"n2199093482":{"id":"n2199093482","loc":[-85.6243149,41.9505231]},"n2199093481":{"id":"n2199093481","loc":[-85.6243203,41.9508648]},"n2199093480":{"id":"n2199093480","loc":[-85.624393,41.9508668]},"n2199093479":{"id":"n2199093479","loc":[-85.6243904,41.9505956]},"n2199093478":{"id":"n2199093478","loc":[-85.6246727,41.950594]},"n2199093477":{"id":"n2199093477","loc":[-85.624675,41.9508203]},"n2199093476":{"id":"n2199093476","loc":[-85.6245097,41.9508212]},"n2199093475":{"id":"n2199093475","loc":[-85.6245101,41.9508662]},"n2199093474":{"id":"n2199093474","loc":[-85.6241008,41.9493459]},"n2199093473":{"id":"n2199093473","loc":[-85.6242442,41.9493459]},"n2199093472":{"id":"n2199093472","loc":[-85.6242442,41.9493681]},"n2199093471":{"id":"n2199093471","loc":[-85.6243397,41.9493681]},"n2199093470":{"id":"n2199093470","loc":[-85.6243417,41.9493511]},"n2199093469":{"id":"n2199093469","loc":[-85.6247251,41.9493485]},"n2199093468":{"id":"n2199093468","loc":[-85.6247548,41.9504949]},"n2199093467":{"id":"n2199093467","loc":[-85.6241214,41.9505017]},"n2199093466":{"id":"n2199093466","loc":[-85.6254398,41.950174]},"n2199093465":{"id":"n2199093465","loc":[-85.6254412,41.9499872]},"n2199093464":{"id":"n2199093464","loc":[-85.6255363,41.9499876]},"n2199093463":{"id":"n2199093463","loc":[-85.6255374,41.9498439]},"n2199093462":{"id":"n2199093462","loc":[-85.6255638,41.949844]},"n2199093461":{"id":"n2199093461","loc":[-85.6255652,41.9496672]},"n2199093460":{"id":"n2199093460","loc":[-85.6251823,41.9496656]},"n2199093459":{"id":"n2199093459","loc":[-85.6251785,41.9501729]},"n2199093510":{"id":"n2199093510","loc":[-85.6229922,41.9496143]},"n2199093509":{"id":"n2199093509","loc":[-85.6229915,41.9494306]},"n185948903":{"id":"n185948903","loc":[-85.616514,41.947449]},"n185955120":{"id":"n185955120","loc":[-85.620103,41.951]},"n185955143":{"id":"n185955143","loc":[-85.619784,41.94746]},"n185960124":{"id":"n185960124","loc":[-85.615238,41.947468]},"n185961362":{"id":"n185961362","loc":[-85.617437,41.947451]},"n185961364":{"id":"n185961364","loc":[-85.61861,41.947456]},"n185961367":{"id":"n185961367","loc":[-85.620088,41.947458]},"n185965105":{"id":"n185965105","loc":[-85.620087,41.94924]},"n185970220":{"id":"n185970220","loc":[-85.62156,41.948333]},"n185974697":{"id":"n185974697","loc":[-85.6201059,41.950132]},"n2138420778":{"id":"n2138420778","loc":[-85.616948,41.9474499]},"w17967535":{"id":"w17967535","tags":{"highway":"residential","name":"10th Ave"},"nodes":["n185955120","n185986812","n185983141"]},"w209716130":{"id":"w209716130","tags":{"area":"yes","building":"yes"},"nodes":["n2199093485","n2199093486","n2199093487","n2199093488","n2199093485"]},"w17964788":{"id":"w17964788","tags":{"highway":"residential","name":"6th Ave"},"nodes":["n185960124","n185948903","n2138420778","n185961362","n185961364","n185955143","n185961367","n185961369","n185961371"]},"w17965159":{"id":"w17965159","tags":{"highway":"residential","name":"8th Ave"},"nodes":["n185965105","n185965108","n185965110"]},"w209716125":{"id":"w209716125","tags":{"area":"yes","building":"yes"},"nodes":["n2199093459","n2199093460","n2199093461","n2199093462","n2199093463","n2199093464","n2199093465","n2199093466","n2199093459"]},"w17965699":{"id":"w17965699","tags":{"highway":"residential","name":"7th Ave"},"nodes":["n185970220","n185970222","n185970224"]},"w209716132":{"id":"w209716132","tags":{"area":"yes","building":"yes"},"nodes":["n2199093507","n2199093508","n2199093509","n2199093510","n2199093511","n2199093512","n2199093513","n2199093514","n2199093507"]},"w17966129":{"id":"w17966129","tags":{"highway":"residential","name":"9th Ave"},"nodes":["n185974697","n185974699"]},"w209716127":{"id":"w209716127","tags":{"area":"yes","building":"yes"},"nodes":["n2199093475","n2199093476","n2199093477","n2199093478","n2199093479","n2199093480","n2199093475"]},"w209716131":{"id":"w209716131","tags":{"area":"yes","natural":"water","water":"pond"},"nodes":["n2199093489","n2199093490","n2199093491","n2199093492","n2199093493","n2199093494","n2199093495","n2199093496","n2199093497","n2199093498","n2199093499","n2199093500","n2199093501","n2199093502","n2199093503","n2199093504","n2199093505","n2199093506","n2199093489"]},"w209716126":{"id":"w209716126","tags":{"area":"yes","building":"yes"},"nodes":["n2199093467","n2199093468","n2199093469","n2199093470","n2199093471","n2199093472","n2199093473","n2199093474","n2199093467"]},"w209716124":{"id":"w209716124","tags":{"area":"yes","building":"yes"},"nodes":["n2199093455","n2199093456","n2199093457","n2199093458","n2199093455"]},"w209716128":{"id":"w209716128","tags":{"area":"yes","building":"yes"},"nodes":["n2199093481","n2199093482","n2199093483","n2199093484","n2199093481"]},"n185949872":{"id":"n185949872","loc":[-85.643009,41.949264]},"n185949875":{"id":"n185949875","loc":[-85.642598,41.94929]},"n185949877":{"id":"n185949877","loc":[-85.642127,41.949382]},"n185949881":{"id":"n185949881","loc":[-85.64169,41.949936]},"n185988165":{"id":"n185988165","loc":[-85.642167,41.947657]},"n185988167":{"id":"n185988167","loc":[-85.642347,41.947662]},"n185988169":{"id":"n185988169","loc":[-85.642621,41.947659]},"n185965019":{"id":"n185965019","loc":[-85.6385084,41.951127]},"n1475293248":{"id":"n1475293248","loc":[-85.6386095,41.9512214]},"n185962639":{"id":"n185962639","loc":[-85.649669,41.949161]},"n185962810":{"id":"n185962810","loc":[-85.649907,41.949157]},"n185964355":{"id":"n185964355","loc":[-85.637412,41.9511359]},"n185965021":{"id":"n185965021","loc":[-85.638661,41.952386]},"n185965023":{"id":"n185965023","loc":[-85.638654,41.953665]},"n185965025":{"id":"n185965025","loc":[-85.638694,41.954649]},"n185965027":{"id":"n185965027","loc":[-85.638724,41.955913]},"n185971415":{"id":"n185971415","loc":[-85.644466,41.949246]},"n185971417":{"id":"n185971417","loc":[-85.647021,41.949193]},"n185971420":{"id":"n185971420","loc":[-85.648476,41.949169]},"n185979975":{"id":"n185979975","loc":[-85.644429,41.947633]},"n185988171":{"id":"n185988171","loc":[-85.645377,41.947622]},"w17963211":{"id":"w17963211","tags":{"highway":"residential"},"nodes":["n185949870","n185949872","n185949875","n185949877","n185949881"]},"w17965839":{"id":"w17965839","tags":{"highway":"residential","name":"Arnold St"},"nodes":["n185949870","n185971415","n185971417","n185971420","n185962639","n185962810"]},"w17967618":{"id":"w17967618","tags":{"highway":"residential","name":"Pierson St"},"nodes":["n185967777","n185988165","n185988167","n185988169","n185985824","n185979975","n185988171"]},"w17965149":{"id":"w17965149","tags":{"highway":"residential","name":"Oak St"},"nodes":["n185965019","n1475293248","n185965021","n185965023","n185965025","n185965027"]},"w17966118":{"id":"w17966118","tags":{"highway":"residential","name":"West Armitage Street"},"nodes":["n185974583","n185974585","n185964355","n185965019"]},"n2208608800":{"id":"n2208608800","loc":[-85.6354294,41.9486201]},"n2199109806":{"id":"n2199109806","loc":[-85.6350474,41.9477884]},"n2199109804":{"id":"n2199109804","loc":[-85.6350476,41.9477962]},"n2199109802":{"id":"n2199109802","loc":[-85.635002,41.9477969]},"n2199109799":{"id":"n2199109799","loc":[-85.6350018,41.9477883]},"n2199109797":{"id":"n2199109797","loc":[-85.6349141,41.9477897]},"n2199109795":{"id":"n2199109795","loc":[-85.6349131,41.9477535]},"n2199109793":{"id":"n2199109793","loc":[-85.6349395,41.9477531]},"n2199109791":{"id":"n2199109791","loc":[-85.6349382,41.9477077]},"n2199109789":{"id":"n2199109789","loc":[-85.6351236,41.9477049]},"n2199109787":{"id":"n2199109787","loc":[-85.6351259,41.9477872]},"n2199109785":{"id":"n2199109785","loc":[-85.634972,41.9475992]},"n2199109783":{"id":"n2199109783","loc":[-85.6349206,41.9475997]},"n2199109770":{"id":"n2199109770","loc":[-85.6348499,41.9475461]},"n2199109768":{"id":"n2199109768","loc":[-85.6348499,41.9475084]},"n2199109765":{"id":"n2199109765","loc":[-85.6349241,41.9474569]},"n2199109763":{"id":"n2199109763","loc":[-85.634967,41.9474564]},"n2199109762":{"id":"n2199109762","loc":[-85.6350405,41.9475121]},"n2199109761":{"id":"n2199109761","loc":[-85.6350405,41.9475419]},"n2199109753":{"id":"n2199109753","loc":[-85.6342443,41.9478391]},"n2199109751":{"id":"n2199109751","loc":[-85.6342427,41.9477927]},"n2199109745":{"id":"n2199109745","loc":[-85.6342439,41.9476859]},"n2199109743":{"id":"n2199109743","loc":[-85.6342429,41.9476575]},"n2199109741":{"id":"n2199109741","loc":[-85.6344615,41.9476533]},"n2199109739":{"id":"n2199109739","loc":[-85.6344678,41.9478348]},"n2199109737":{"id":"n2199109737","loc":[-85.634416,41.9480059]},"n2199109735":{"id":"n2199109735","loc":[-85.6344145,41.9478983]},"n2199109733":{"id":"n2199109733","loc":[-85.6342749,41.9478993]},"n2199109731":{"id":"n2199109731","loc":[-85.6342753,41.9479272]},"n2199109729":{"id":"n2199109729","loc":[-85.6342498,41.9479274]},"n2199109727":{"id":"n2199109727","loc":[-85.6342505,41.9479762]},"n2199109725":{"id":"n2199109725","loc":[-85.6342743,41.947976]},"n2199109723":{"id":"n2199109723","loc":[-85.6342747,41.948007]},"n2199109721":{"id":"n2199109721","loc":[-85.6343415,41.9476355]},"n2199109719":{"id":"n2199109719","loc":[-85.6343391,41.9474973]},"n2199109717":{"id":"n2199109717","loc":[-85.6343133,41.9474798]},"n2199109715":{"id":"n2199109715","loc":[-85.6342874,41.9474737]},"n2199109709":{"id":"n2199109709","loc":[-85.6349804,41.94815]},"n2199109707":{"id":"n2199109707","loc":[-85.6348915,41.9481505]},"n2199109705":{"id":"n2199109705","loc":[-85.6348917,41.9481692]},"n2199109702":{"id":"n2199109702","loc":[-85.6348522,41.9481694]},"n2199109700":{"id":"n2199109700","loc":[-85.6348532,41.9482679]},"n2199109698":{"id":"n2199109698","loc":[-85.6348315,41.948268]},"n2199109696":{"id":"n2199109696","loc":[-85.6348318,41.9482955]},"n2199109694":{"id":"n2199109694","loc":[-85.6349653,41.9482946]},"n2199109692":{"id":"n2199109692","loc":[-85.6349656,41.9483211]},"n2199109690":{"id":"n2199109690","loc":[-85.634999,41.9483209]},"n2199109688":{"id":"n2199109688","loc":[-85.6349987,41.9482947]},"n2199109686":{"id":"n2199109686","loc":[-85.6351753,41.9482935]},"n2199109684":{"id":"n2199109684","loc":[-85.6351749,41.9482617]},"n2199109682":{"id":"n2199109682","loc":[-85.6351588,41.9482618]},"n2199109680":{"id":"n2199109680","loc":[-85.6351575,41.9481518]},"n2199109678":{"id":"n2199109678","loc":[-85.6350671,41.9481524]},"n2199109676":{"id":"n2199109676","loc":[-85.6350649,41.9479659]},"n2199109674":{"id":"n2199109674","loc":[-85.6349785,41.9479665]},"n2199109671":{"id":"n2199109671","loc":[-85.6343069,41.9483263]},"n2199109669":{"id":"n2199109669","loc":[-85.6343052,41.9482981]},"n2199109658":{"id":"n2199109658","loc":[-85.6343314,41.9480549]},"n2199109656":{"id":"n2199109656","loc":[-85.6343305,41.9480461]},"n2199109654":{"id":"n2199109654","loc":[-85.634435,41.9480468]},"n2199109652":{"id":"n2199109652","loc":[-85.6344342,41.9483746]},"n2199109650":{"id":"n2199109650","loc":[-85.6344629,41.9483727]},"n2199109648":{"id":"n2199109648","loc":[-85.6344637,41.9484561]},"n2199109645":{"id":"n2199109645","loc":[-85.63443,41.9484567]},"n2199109642":{"id":"n2199109642","loc":[-85.6344317,41.948505]},"n185964352":{"id":"n185964352","loc":[-85.6373958,41.9489943]},"n185964351":{"id":"n185964351","loc":[-85.637113,41.9486]},"n2208608825":{"id":"n2208608825","loc":[-85.6354483,41.9494241]},"n2208608823":{"id":"n2208608823","loc":[-85.6360418,41.949416]},"n2208608821":{"id":"n2208608821","loc":[-85.6360458,41.9495802]},"n2208608811":{"id":"n2208608811","loc":[-85.6357458,41.9495843]},"n2208608808":{"id":"n2208608808","loc":[-85.6357508,41.9497835]},"n2208608806":{"id":"n2208608806","loc":[-85.6354573,41.9497875]},"n2208608795":{"id":"n2208608795","loc":[-85.6354595,41.9498778]},"n2199109638":{"id":"n2199109638","loc":[-85.6349605,41.949749]},"n2199109636":{"id":"n2199109636","loc":[-85.6349605,41.9497639]},"n2199109634":{"id":"n2199109634","loc":[-85.6349061,41.94971]},"n2199109632":{"id":"n2199109632","loc":[-85.6349048,41.9496569]},"n2199109630":{"id":"n2199109630","loc":[-85.6348835,41.9496571]},"n2199109628":{"id":"n2199109628","loc":[-85.6348829,41.9497103]},"n2199109626":{"id":"n2199109626","loc":[-85.635227,41.9497738]},"n2199109624":{"id":"n2199109624","loc":[-85.6352184,41.9497787]},"n2199109622":{"id":"n2199109622","loc":[-85.6351181,41.9497806]},"n2199109620":{"id":"n2199109620","loc":[-85.6351181,41.9497456]},"n2199109618":{"id":"n2199109618","loc":[-85.6348842,41.9497651]},"n2199109616":{"id":"n2199109616","loc":[-85.6348827,41.9496238]},"n2199109615":{"id":"n2199109615","loc":[-85.6351268,41.9496206]},"n2199109614":{"id":"n2199109614","loc":[-85.6351261,41.9495891]},"n2199109613":{"id":"n2199109613","loc":[-85.6351957,41.9495881]},"n2199109612":{"id":"n2199109612","loc":[-85.6351924,41.9494515]},"n2199109611":{"id":"n2199109611","loc":[-85.6353997,41.9494488]},"n2199109610":{"id":"n2199109610","loc":[-85.6354074,41.9497715]},"n2189015681":{"id":"n2189015681","loc":[-85.6344229,41.9509639]},"n2189015677":{"id":"n2189015677","loc":[-85.634424,41.9507396]},"n2138493843":{"id":"n2138493843","loc":[-85.6343935,41.9502836]},"n2138493840":{"id":"n2138493840","loc":[-85.634398,41.9506264]},"n354002838":{"id":"n354002838","loc":[-85.6345197,41.9510631]},"n2114807590":{"id":"n2114807590","loc":[-85.634511,41.9499767]},"n185964353":{"id":"n185964353","loc":[-85.6374092,41.9498755]},"n1819849180":{"id":"n1819849180","loc":[-85.6348236,41.94996]},"n1819849115":{"id":"n1819849115","loc":[-85.6354372,41.9499538]},"n1819848921":{"id":"n1819848921","loc":[-85.6348439,41.951064]},"n1819848885":{"id":"n1819848885","loc":[-85.6354575,41.9510578]},"n185984281":{"id":"n185984281","loc":[-85.638075,41.949872]},"n2208608827":{"id":"n2208608827","loc":[-85.6339169,41.9473191]},"n2199109749":{"id":"n2199109749","loc":[-85.6342082,41.9477934]},"n2199109747":{"id":"n2199109747","loc":[-85.6342045,41.9476867]},"n2199109713":{"id":"n2199109713","loc":[-85.6342404,41.9474746]},"n2199109711":{"id":"n2199109711","loc":[-85.6342404,41.9476355]},"n2199109673":{"id":"n2199109673","loc":[-85.6340886,41.9483282]},"n2199109667":{"id":"n2199109667","loc":[-85.6342403,41.9482988]},"n2199109665":{"id":"n2199109665","loc":[-85.6342386,41.9482116]},"n2199109662":{"id":"n2199109662","loc":[-85.6340861,41.9482135]},"n2199109660":{"id":"n2199109660","loc":[-85.6340802,41.9480562]},"n2199109640":{"id":"n2199109640","loc":[-85.6340928,41.9485063]},"n354031366":{"id":"n354031366","loc":[-85.6341667,41.9477778],"tags":{"amenity":"place_of_worship","name":"Faith Tabernacle Church","religion":"christian"}},"n2189015686":{"id":"n2189015686","loc":[-85.6337798,41.95099]},"n2189015684":{"id":"n2189015684","loc":[-85.6337794,41.9509674]},"n2189015673":{"id":"n2189015673","loc":[-85.6337501,41.9507457]},"n2189015669":{"id":"n2189015669","loc":[-85.6337501,41.9506974]},"n2189015665":{"id":"n2189015665","loc":[-85.6339034,41.9506959]},"n2189015662":{"id":"n2189015662","loc":[-85.6339015,41.950436]},"n2189015658":{"id":"n2189015658","loc":[-85.6334916,41.9504376]},"n2189015655":{"id":"n2189015655","loc":[-85.6334939,41.9507558]},"n2189015650":{"id":"n2189015650","loc":[-85.6334543,41.950756]},"n2189015649":{"id":"n2189015649","loc":[-85.633456,41.9509915]},"n2138493842":{"id":"n2138493842","loc":[-85.6339937,41.9502836]},"n2138493841":{"id":"n2138493841","loc":[-85.6339983,41.9506281]},"n2114807579":{"id":"n2114807579","loc":[-85.6333644,41.9510682]},"n2114807573":{"id":"n2114807573","loc":[-85.6333557,41.9499819]},"n354031330":{"id":"n354031330","loc":[-85.6341667,41.9497222],"tags":{"amenity":"place_of_worship","name":"Trinity Episcopal Church","religion":"christian"}},"n185960794":{"id":"n185960794","loc":[-85.633307,41.9537]},"n185964357":{"id":"n185964357","loc":[-85.637432,41.952399]},"n185964358":{"id":"n185964358","loc":[-85.637452,41.953665]},"n185964359":{"id":"n185964359","loc":[-85.63746,41.954658]},"n185964360":{"id":"n185964360","loc":[-85.637473,41.95592]},"n185964361":{"id":"n185964361","loc":[-85.637468,41.956906]},"n185964362":{"id":"n185964362","loc":[-85.637483,41.958313]},"n185966957":{"id":"n185966957","loc":[-85.633361,41.957422]},"n185975351":{"id":"n185975351","loc":[-85.63334,41.9559]},"n185978784":{"id":"n185978784","loc":[-85.633311,41.954679]},"n185986157":{"id":"n185986157","loc":[-85.633287,41.952426]},"n185986158":{"id":"n185986158","loc":[-85.6333607,41.9582301],"tags":{"highway":"turning_circle"}},"w17965182":{"id":"w17965182","tags":{"highway":"residential","name":"W Prutzman St"},"nodes":["n185965289","n2189153241","n185965291"]},"w208627205":{"id":"w208627205","tags":{"area":"yes","building":"yes"},"nodes":["n2189015649","n2189015650","n2189015655","n2189015658","n2189015662","n2189015665","n2189015669","n2189015673","n2189015677","n2189015681","n2189015684","n2189015686","n2189015649"]},"w209717042":{"id":"w209717042","tags":{"amenity":"place_of_worship","area":"yes","building":"yes","denomination":"presbyterian","name":"First Presbyterian Church","religion":"christian"},"nodes":["n2199109610","n2199109611","n2199109612","n2199109613","n2199109614","n2199109615","n2199109616","n2199109630","n2199109632","n2199109634","n2199109628","n2199109618","n2199109636","n2199109638","n2199109620","n2199109622","n2199109624","n2199109626","n2199109610"]},"w209717045":{"id":"w209717045","tags":{"area":"yes","building":"yes"},"nodes":["n2199109711","n2199109713","n2199109715","n2199109717","n2199109719","n2199109721","n2199109711"]},"w209717047":{"id":"w209717047","tags":{"area":"yes","building":"yes"},"nodes":["n2199109739","n2199109741","n2199109743","n2199109745","n2199109747","n2199109749","n2199109751","n2199109753","n2199109739"]},"w209717044":{"id":"w209717044","tags":{"area":"yes","building":"yes"},"nodes":["n2199109674","n2199109676","n2199109678","n2199109680","n2199109682","n2199109684","n2199109686","n2199109688","n2199109690","n2199109692","n2199109694","n2199109696","n2199109698","n2199109700","n2199109702","n2199109705","n2199109707","n2199109709","n2199109674"]},"w210822776":{"id":"w210822776","tags":{"highway":"service","service":"alley","surface":"unpaved"},"nodes":["n2208608795","n2208608806","n2208608825","n2208608800","n2189153241"]},"w210822778":{"id":"w210822778","tags":{"highway":"service","service":"alley"},"nodes":["n2208608826","n2208608827"]},"w209717050":{"id":"w209717050","tags":{"area":"yes","building":"yes"},"nodes":["n2199109787","n2199109789","n2199109791","n2199109793","n2199109795","n2199109797","n2199109799","n2199109802","n2199109804","n2199109806","n2199109787"]},"w17965097":{"id":"w17965097","tags":{"highway":"residential","name":"Maple Street"},"nodes":["n185964351","n185964352","n185964353","n185964355","n185964357","n185964358","n185964359","n185964360","n185964361","n185964362"]},"w17965856":{"id":"w17965856","tags":{"highway":"residential","name":"W Kelsey St"},"nodes":["n185971578","n2208608800","n185971580","n185964351"]},"w17967444":{"id":"w17967444","tags":{"highway":"residential","name":"East Street"},"nodes":["n185966937","n185978969","n185986155","n185985812","n185986157","n185960794","n185978784","n185975351","n185966957","n185986158"]},"w17967764":{"id":"w17967764","tags":{"highway":"residential","name":"Rock River Ave"},"nodes":["n185984017","n185964351"]},"w170848329":{"id":"w170848329","tags":{"leisure":"park","name":"LaFayette Park"},"nodes":["n1819849180","n1819849115","n1819848885","n1819848921","n1819849180"]},"w17967208":{"id":"w17967208","tags":{"highway":"residential","name":"West Bennett Street"},"nodes":["n185978390","n2208608795","n185984020","n185964353","n185984281"]},"w17965349":{"id":"w17965349","tags":{"highway":"residential","name":"E Prutzman St"},"nodes":["n185966937","n2208608827","n185965289"]},"w209717049":{"id":"w209717049","tags":{"area":"yes","building":"yes"},"nodes":["n2199109761","n2199109762","n2199109763","n2199109765","n2199109768","n2199109770","n2199109783","n2199109785","n2199109761"]},"w203841840":{"id":"w203841840","tags":{"area":"yes","leisure":"playground"},"nodes":["n2138493840","n2138493841","n2138493842","n2138493843","n2138493840"]},"w209717043":{"id":"w209717043","tags":{"amenity":"place_of_worship","area":"yes","building":"church","denomination":"methodist","name":"First United Methodist Church","religion":"christian"},"nodes":["n2199109640","n2199109642","n2199109645","n2199109648","n2199109650","n2199109652","n2199109654","n2199109656","n2199109658","n2199109660","n2199109662","n2199109665","n2199109667","n2199109669","n2199109671","n2199109673","n2199109640"]},"w201484341":{"id":"w201484341","tags":{"amenity":"school","name":"Hoppin School"},"nodes":["n354002838","n2114807579","n2114807573","n2114807590","n354002838"]},"w209717046":{"id":"w209717046","tags":{"area":"yes","building":"yes"},"nodes":["n2199109723","n2199109725","n2199109727","n2199109729","n2199109731","n2199109733","n2199109735","n2199109737","n2199109723"]},"w210822777":{"id":"w210822777","tags":{"amenity":"parking","area":"yes"},"nodes":["n2208608806","n2208608808","n2208608811","n2208608821","n2208608823","n2208608825","n2208608806"]},"n185954965":{"id":"n185954965","loc":[-85.6191189,41.9441922]},"n185954968":{"id":"n185954968","loc":[-85.6194384,41.9442405]},"n185954970":{"id":"n185954970","loc":[-85.6196543,41.9443252]},"n185954972":{"id":"n185954972","loc":[-85.6197862,41.9444539]},"n354002931":{"id":"n354002931","loc":[-85.6198991,41.9455269]},"n354030853":{"id":"n354030853","loc":[-85.6219444,41.9455556],"tags":{"amenity":"place_of_worship","name":"Grant Chapel","religion":"christian"}},"n367815963":{"id":"n367815963","loc":[-85.6202778,41.9461111],"tags":{"building":"yes","name":"George Washington Carver Community Center"}},"n185947331":{"id":"n185947331","loc":[-85.618779,41.943269]},"n185947333":{"id":"n185947333","loc":[-85.618795,41.943511]},"n185947336":{"id":"n185947336","loc":[-85.618711,41.94413]},"n185947338":{"id":"n185947338","loc":[-85.618704,41.944189]},"n185947339":{"id":"n185947339","loc":[-85.618597,41.944337]},"n185947340":{"id":"n185947340","loc":[-85.618485,41.944528]},"n185947343":{"id":"n185947343","loc":[-85.618442,41.944716]},"n185947345":{"id":"n185947345","loc":[-85.618457,41.945107]},"n185947347":{"id":"n185947347","loc":[-85.618296,41.945338]},"n185947374":{"id":"n185947374","loc":[-85.616748,41.944453]},"n185947375":{"id":"n185947375","loc":[-85.616813,41.944646]},"n185947376":{"id":"n185947376","loc":[-85.616859,41.945196]},"n185947377":{"id":"n185947377","loc":[-85.616941,41.945352]},"n185947406":{"id":"n185947406","loc":[-85.618184,41.944227]},"n185947409":{"id":"n185947409","loc":[-85.617911,41.943875]},"n185947410":{"id":"n185947410","loc":[-85.617579,41.943682]},"n185947411":{"id":"n185947411","loc":[-85.61713,41.943589]},"n185947412":{"id":"n185947412","loc":[-85.616549,41.943559]},"n185947414":{"id":"n185947414","loc":[-85.616482,41.943556]},"n185947464":{"id":"n185947464","loc":[-85.616526,41.943788]},"n185947466":{"id":"n185947466","loc":[-85.616504,41.944002]},"n185948863":{"id":"n185948863","loc":[-85.619017,41.943391]},"n185948865":{"id":"n185948865","loc":[-85.619059,41.943368]},"n185955022":{"id":"n185955022","loc":[-85.620088,41.945571]},"n185955025":{"id":"n185955025","loc":[-85.620051,41.945505]},"n185955028":{"id":"n185955028","loc":[-85.62001,41.94541]},"n185980371":{"id":"n185980371","loc":[-85.620982,41.944742]},"n185980398":{"id":"n185980398","loc":[-85.621305,41.944782]},"n185980401":{"id":"n185980401","loc":[-85.621174,41.944819]},"n185980403":{"id":"n185980403","loc":[-85.621029,41.944871]},"n185980405":{"id":"n185980405","loc":[-85.620741,41.945011]},"n185980407":{"id":"n185980407","loc":[-85.620616,41.945085]},"n185980409":{"id":"n185980409","loc":[-85.620506,41.945172]},"n185980411":{"id":"n185980411","loc":[-85.620394,41.945273]},"n185980413":{"id":"n185980413","loc":[-85.620316,41.94536]},"n185980415":{"id":"n185980415","loc":[-85.620257,41.945452]},"n185980417":{"id":"n185980417","loc":[-85.620212,41.945535]},"n185985910":{"id":"n185985910","loc":[-85.620101,41.945811]},"n185985912":{"id":"n185985912","loc":[-85.620081,41.945937]},"n1475283972":{"id":"n1475283972","loc":[-85.6198991,41.9437179]},"n1475283982":{"id":"n1475283982","loc":[-85.6195022,41.9433463]},"n1475284007":{"id":"n1475284007","loc":[-85.6193037,41.9433383]},"n1475284040":{"id":"n1475284040","loc":[-85.6197329,41.9434121]},"n1475284044":{"id":"n1475284044","loc":[-85.6198756,41.9435363]},"n1475284050":{"id":"n1475284050","loc":[-85.6199689,41.9432106]},"n1475284053":{"id":"n1475284053","loc":[-85.6198943,41.9432921]},"n185954974":{"id":"n185954974","loc":[-85.6198296,41.94473]},"n185954977":{"id":"n185954977","loc":[-85.6200474,41.9447384]},"n2196831365":{"id":"n2196831365","loc":[-85.6202259,41.9460883]},"n2196831366":{"id":"n2196831366","loc":[-85.6202245,41.9458642]},"n2196831367":{"id":"n2196831367","loc":[-85.6205184,41.9458631]},"n2196831368":{"id":"n2196831368","loc":[-85.6205189,41.9459437]},"n2196831369":{"id":"n2196831369","loc":[-85.6203879,41.9459441]},"n2196831370":{"id":"n2196831370","loc":[-85.6203888,41.9460878]},"n2196831371":{"id":"n2196831371","loc":[-85.6184046,41.9465663]},"n2196831372":{"id":"n2196831372","loc":[-85.6191563,41.9465618]},"n2196831373":{"id":"n2196831373","loc":[-85.6191536,41.946319]},"n2196831374":{"id":"n2196831374","loc":[-85.6187356,41.9463216]},"n2196831375":{"id":"n2196831375","loc":[-85.6187334,41.9461197]},"n2196831376":{"id":"n2196831376","loc":[-85.6193167,41.9461162]},"n2196831377":{"id":"n2196831377","loc":[-85.6193156,41.9460229]},"n2196831378":{"id":"n2196831378","loc":[-85.619622,41.946021]},"n2196831379":{"id":"n2196831379","loc":[-85.6196237,41.9461712]},"n2196831380":{"id":"n2196831380","loc":[-85.6197702,41.9461703]},"n2196831381":{"id":"n2196831381","loc":[-85.6197685,41.9460202]},"n2196831382":{"id":"n2196831382","loc":[-85.6197323,41.9460204]},"n2196831383":{"id":"n2196831383","loc":[-85.6197305,41.9458563]},"n2196831384":{"id":"n2196831384","loc":[-85.6196165,41.945857]},"n2196831385":{"id":"n2196831385","loc":[-85.6196156,41.9457764]},"n2196831386":{"id":"n2196831386","loc":[-85.6194472,41.9457775]},"n2196831387":{"id":"n2196831387","loc":[-85.6194151,41.9457777]},"n2196831388":{"id":"n2196831388","loc":[-85.6183779,41.9457883]},"n2196831389":{"id":"n2196831389","loc":[-85.6183842,41.9461317]},"n2196831390":{"id":"n2196831390","loc":[-85.6185026,41.9461304]},"n2196831391":{"id":"n2196831391","loc":[-85.6185061,41.9463194]},"n2196831392":{"id":"n2196831392","loc":[-85.6184001,41.9463205]},"n2196831393":{"id":"n2196831393","loc":[-85.6182482,41.9464163]},"n2196831394":{"id":"n2196831394","loc":[-85.6182467,41.9463193]},"n2196831395":{"id":"n2196831395","loc":[-85.6180389,41.946321]},"n2196831397":{"id":"n2196831397","loc":[-85.6180404,41.946418]},"n185947303":{"id":"n185947303","loc":[-85.611074,41.943389]},"n185947304":{"id":"n185947304","loc":[-85.611332,41.943267]},"n185947305":{"id":"n185947305","loc":[-85.611635,41.943218]},"n185947306":{"id":"n185947306","loc":[-85.612762,41.943311]},"n185947308":{"id":"n185947308","loc":[-85.613027,41.943327]},"n185947310":{"id":"n185947310","loc":[-85.615377,41.942996]},"n185947312":{"id":"n185947312","loc":[-85.615701,41.943007]},"n185947314":{"id":"n185947314","loc":[-85.61604,41.943067]},"n185947315":{"id":"n185947315","loc":[-85.61626,41.943083]},"n185947316":{"id":"n185947316","loc":[-85.616507,41.943048]},"n185947319":{"id":"n185947319","loc":[-85.616702,41.94299]},"n185947321":{"id":"n185947321","loc":[-85.617078,41.942918]},"n185947322":{"id":"n185947322","loc":[-85.617366,41.942973]},"n185947323":{"id":"n185947323","loc":[-85.617601,41.943033]},"n185947325":{"id":"n185947325","loc":[-85.617799,41.943027]},"n185947327":{"id":"n185947327","loc":[-85.618264,41.942961]},"n185947328":{"id":"n185947328","loc":[-85.618508,41.942972]},"n185947329":{"id":"n185947329","loc":[-85.618707,41.943076]},"n185947361":{"id":"n185947361","loc":[-85.615356,41.944922]},"n185947363":{"id":"n185947363","loc":[-85.61536,41.944893]},"n185947365":{"id":"n185947365","loc":[-85.615406,41.944547]},"n185947367":{"id":"n185947367","loc":[-85.61548,41.944351]},"n185947369":{"id":"n185947369","loc":[-85.615805,41.94419]},"n185947371":{"id":"n185947371","loc":[-85.616166,41.944156]},"n185947373":{"id":"n185947373","loc":[-85.616411,41.944197]},"n185947416":{"id":"n185947416","loc":[-85.616335,41.94343]},"n185947417":{"id":"n185947417","loc":[-85.616069,41.943293]},"n185947419":{"id":"n185947419","loc":[-85.615803,41.943249]},"n185947420":{"id":"n185947420","loc":[-85.615524,41.943342]},"n185947421":{"id":"n185947421","loc":[-85.615311,41.94353]},"n185947422":{"id":"n185947422","loc":[-85.614338,41.943558]},"n185947423":{"id":"n185947423","loc":[-85.61422,41.94369]},"n185947425":{"id":"n185947425","loc":[-85.614221,41.944224]},"n185947427":{"id":"n185947427","loc":[-85.614198,41.944888]},"n185947429":{"id":"n185947429","loc":[-85.614221,41.945439]},"n185947468":{"id":"n185947468","loc":[-85.615908,41.944756]},"n185947470":{"id":"n185947470","loc":[-85.615871,41.944888]},"n185947472":{"id":"n185947472","loc":[-85.615878,41.94507]},"n185955153":{"id":"n185955153","loc":[-85.620087,41.947701]},"n185960690":{"id":"n185960690","loc":[-85.620141,41.951901]},"n185978817":{"id":"n185978817","loc":[-85.617193,41.954706]},"n185985916":{"id":"n185985916","loc":[-85.620088,41.94758]},"n185985918":{"id":"n185985918","loc":[-85.620133,41.951538]},"n185985919":{"id":"n185985919","loc":[-85.62013,41.952104]},"n185985920":{"id":"n185985920","loc":[-85.620104,41.952305]},"n185985921":{"id":"n185985921","loc":[-85.620062,41.952499]},"n185985922":{"id":"n185985922","loc":[-85.619993,41.952702]},"n185985925":{"id":"n185985925","loc":[-85.619879,41.952986]},"n185985927":{"id":"n185985927","loc":[-85.619689,41.95329]},"n185985928":{"id":"n185985928","loc":[-85.619508,41.953521]},"n185985929":{"id":"n185985929","loc":[-85.619286,41.953728]},"n185985930":{"id":"n185985930","loc":[-85.618925,41.954007]},"n185985931":{"id":"n185985931","loc":[-85.618638,41.954189]},"n185985932":{"id":"n185985932","loc":[-85.61831,41.954358]},"n185985934":{"id":"n185985934","loc":[-85.618015,41.954485]},"n185985936":{"id":"n185985936","loc":[-85.617606,41.954611]},"n1475283975":{"id":"n1475283975","loc":[-85.6150935,41.9434118]},"n1475283979":{"id":"n1475283979","loc":[-85.6193367,41.9430252]},"n1475283989":{"id":"n1475283989","loc":[-85.6104771,41.9455269]},"n1475283990":{"id":"n1475283990","loc":[-85.6104771,41.9437179]},"n1475283994":{"id":"n1475283994","loc":[-85.6198042,41.9429763]},"n1475283998":{"id":"n1475283998","loc":[-85.6192101,41.9426716]},"n1475284000":{"id":"n1475284000","loc":[-85.6198622,41.942836]},"n1475284002":{"id":"n1475284002","loc":[-85.6163262,41.9427688]},"n1475284006":{"id":"n1475284006","loc":[-85.6179527,41.9429168]},"n1475284029":{"id":"n1475284029","loc":[-85.6197195,41.9427278]},"n1475284038":{"id":"n1475284038","loc":[-85.6194405,41.9427837]},"n1475284052":{"id":"n1475284052","loc":[-85.6153225,41.942841]},"n1475284055":{"id":"n1475284055","loc":[-85.6129233,41.9437179]},"n2139966627":{"id":"n2139966627","loc":[-85.61958,41.9427558]},"w17966773":{"id":"w17966773","tags":{"highway":"secondary","name":"E Michigan Ave","ref":"M 60"},"nodes":["n185980372","n185980398","n185980401","n185980403","n185980405","n185980407","n185980409","n185980411","n185980413","n185980415","n185980417","n185955019"]},"w17964043":{"id":"w17964043","tags":{"highway":"residential"},"nodes":["n185955019","n185955022","n185955025","n185955028","n185954977","n185971477","n1475284050","n1475284000","n1475284029","n2139966627","n1475284038"]},"w17962834":{"id":"w17962834","tags":{"highway":"service"},"nodes":["n185947316","n185947414","n185947464","n185947466","n185947373","n185947468","n185947470","n185947472","n185947474"]},"w209470310":{"id":"w209470310","tags":{"area":"yes","building":"yes"},"nodes":["n2196831393","n2196831394","n2196831395","n2196831397","n2196831393"]},"w17963058":{"id":"w17963058","tags":{"highway":"service"},"nodes":["n185947333","n185948863","n185948865","n1475284007","n1475283982","n1475284040","n1475284044"]},"w17962823":{"id":"w17962823","tags":{"highway":"service"},"nodes":["n185947359","n185947361","n185947363","n185947365","n185947367","n185947369","n185947371","n185947373","n185947374","n185947375","n185947376","n185947377","n185947378"]},"w17962821":{"id":"w17962821","tags":{"highway":"service"},"nodes":["n185947303","n185947304","n185947305","n185947306","n185947308","n185947310","n185947312","n185947314","n185947315","n185947316","n185947319","n185947321","n185947322","n185947323","n185947325","n185947327","n185947328","n185947329","n185947331","n185947333","n185947336","n185947338","n185947339","n185947340","n185947343","n185947345","n185947347","n185947349"]},"w134150798":{"id":"w134150798","tags":{"amenity":"grave_yard","name":"Riverside Cemetery"},"nodes":["n354002931","n1475283972","n1475284053","n1475283994","n1475283979","n1475283998","n1475284006","n1475284002","n1475284052","n1475283975","n1475284055","n1475283990","n1475283989","n354002931"]},"w17964040":{"id":"w17964040","tags":{"highway":"service"},"nodes":["n185947336","n185954965","n185954968","n185954970","n185954972","n185954974","n185954977"]},"w209470308":{"id":"w209470308","tags":{"area":"yes","building":"yes"},"nodes":["n2196831365","n2196831366","n2196831367","n2196831368","n2196831369","n2196831370","n2196831365"]},"w17962828":{"id":"w17962828","tags":{"highway":"service"},"nodes":["n185947340","n185947406","n185947409","n185947410","n185947411","n185947412","n185947414","n185947416","n185947417","n185947419","n185947420","n185947421","n185947422","n185947423","n185947425","n185947427","n185947429"]},"w209470309":{"id":"w209470309","tags":{"area":"yes","building":"yes"},"nodes":["n2196831371","n2196831372","n2196831373","n2196831374","n2196831375","n2196831376","n2196831377","n2196831378","n2196831379","n2196831380","n2196831381","n2196831382","n2196831383","n2196831384","n2196831385","n2196831386","n2196831387","n2196831388","n2196831389","n2196831390","n2196831391","n2196831392","n2196831371"]},"w17967415":{"id":"w17967415","tags":{"highway":"secondary","name":"Jefferson St","name_1":"State Highway 60","ref":"M 60"},"nodes":["n185955019","n185985910","n185985912","n185985914","n185961367","n185985916","n185955153","n185965105","n185974697","n185955120","n185985918","n185960690","n185985919","n185985920","n185985921","n185985922","n185985925","n185985927","n185985928","n185985929","n185985930","n185985931","n185985932","n185985934","n185985936","n185978817"]},"w17966772":{"id":"w17966772","tags":{"highway":"unclassified","name":"E Michigan Ave","name_1":"State Highway 60"},"nodes":["n185954977","n185980371","n185980372"]},"n185958500":{"id":"n185958500","loc":[-85.621591,41.941075]},"n185963110":{"id":"n185963110","loc":[-85.6204416,41.9408882]},"n2139966628":{"id":"n2139966628","loc":[-85.6196431,41.9426467],"tags":{"leisure":"fishing"}},"n2139966630":{"id":"n2139966630","loc":[-85.6199354,41.9429616]},"n2199127051":{"id":"n2199127051","loc":[-85.6170556,41.939696]},"n2199127052":{"id":"n2199127052","loc":[-85.6170536,41.9392909]},"n2199127053":{"id":"n2199127053","loc":[-85.6172067,41.9392905]},"n2199127054":{"id":"n2199127054","loc":[-85.6172061,41.9391853]},"n2199127055":{"id":"n2199127055","loc":[-85.6171481,41.9391854]},"n2199127060":{"id":"n2199127060","loc":[-85.6167389,41.9392896]},"n2199127061":{"id":"n2199127061","loc":[-85.6168728,41.9392892]},"n2199127062":{"id":"n2199127062","loc":[-85.6168747,41.9396965]},"n2199127071":{"id":"n2199127071","loc":[-85.620196,41.9399446]},"n2199127072":{"id":"n2199127072","loc":[-85.620193,41.9397316]},"n2199127073":{"id":"n2199127073","loc":[-85.6200381,41.9397328]},"n2199127074":{"id":"n2199127074","loc":[-85.6200412,41.9399458]},"n2199127075":{"id":"n2199127075","loc":[-85.6203606,41.9399939]},"n2199127076":{"id":"n2199127076","loc":[-85.6205527,41.9399922]},"n2199127077":{"id":"n2199127077","loc":[-85.6205482,41.9397115]},"n2199127078":{"id":"n2199127078","loc":[-85.6204132,41.9397124]},"n2199127079":{"id":"n2199127079","loc":[-85.6204144,41.9396341]},"n2199127080":{"id":"n2199127080","loc":[-85.6205699,41.9396324]},"n2199127081":{"id":"n2199127081","loc":[-85.6205722,41.939498]},"n2199127082":{"id":"n2199127082","loc":[-85.6204064,41.9394997]},"n2199127083":{"id":"n2199127083","loc":[-85.6204087,41.939561]},"n2199127084":{"id":"n2199127084","loc":[-85.6203103,41.9395618]},"n2199127085":{"id":"n2199127085","loc":[-85.620308,41.9396069]},"n2199127086":{"id":"n2199127086","loc":[-85.6200347,41.9396086]},"n2199127087":{"id":"n2199127087","loc":[-85.6200382,41.9397141]},"n2199127088":{"id":"n2199127088","loc":[-85.6202257,41.9397149]},"n2199127089":{"id":"n2199127089","loc":[-85.6202269,41.9399182]},"n2199127090":{"id":"n2199127090","loc":[-85.6203595,41.9399199]},"n2199127091":{"id":"n2199127091","loc":[-85.6212335,41.939688]},"n2199127092":{"id":"n2199127092","loc":[-85.6212328,41.939595]},"n2199127093":{"id":"n2199127093","loc":[-85.6208807,41.9395966]},"n2199127094":{"id":"n2199127094","loc":[-85.6208815,41.9396896]},"n2199127095":{"id":"n2199127095","loc":[-85.6208676,41.9396872]},"n2199127096":{"id":"n2199127096","loc":[-85.6208583,41.9393539]},"n2199127097":{"id":"n2199127097","loc":[-85.6207006,41.9393563]},"n2199127098":{"id":"n2199127098","loc":[-85.6207099,41.9396896]},"n185967054":{"id":"n185967054","loc":[-85.6173384,41.9356126]},"n185967063":{"id":"n185967063","loc":[-85.617371,41.936243]},"n185967065":{"id":"n185967065","loc":[-85.617337,41.936299]},"n185967068":{"id":"n185967068","loc":[-85.617321,41.936373]},"n185967070":{"id":"n185967070","loc":[-85.6173562,41.9366969]},"n185967074":{"id":"n185967074","loc":[-85.6173635,41.9377414]},"n185967075":{"id":"n185967075","loc":[-85.6173696,41.9381886]},"n185967076":{"id":"n185967076","loc":[-85.617372,41.938535]},"n2199127056":{"id":"n2199127056","loc":[-85.617147,41.9389616]},"n2199127057":{"id":"n2199127057","loc":[-85.6172136,41.9389614]},"n2199127058":{"id":"n2199127058","loc":[-85.6172123,41.9386909]},"n2199127059":{"id":"n2199127059","loc":[-85.616736,41.9386922]},"n2203921041":{"id":"n2203921041","loc":[-85.6173018,41.9346369]},"w203983952":{"id":"w203983952","tags":{"highway":"service"},"nodes":["n2139966627","n1819800319"]},"w209718301":{"id":"w209718301","tags":{"area":"yes","building":"yes"},"nodes":["n2199127051","n2199127052","n2199127053","n2199127054","n2199127055","n2199127056","n2199127057","n2199127058","n2199127059","n2199127060","n2199127061","n2199127062","n2199127051"]},"w209718304":{"id":"w209718304","tags":{"area":"yes","building":"yes"},"nodes":["n2199127071","n2199127072","n2199127073","n2199127074","n2199127071"]},"w17964961":{"id":"w17964961","tags":{"highway":"residential","name":"Whipple St"},"nodes":["n185963099","n185963110"]},"w17964489":{"id":"w17964489","tags":{"highway":"residential","name":"Jackson St"},"nodes":["n185958498","n185958500"]},"w203983953":{"id":"w203983953","tags":{"area":"yes","leisure":"park","name":"Marina Park"},"nodes":["n1475283994","n1475283979","n1475283998","n2139966629","n2139966625","n1819800319","n2139966623","n2139966622","n2139966621","n2139966630","n1475283994"]},"w17965366":{"id":"w17965366","tags":{"highway":"residential","name":"14th St"},"nodes":["n2203921041","n185967054","n185967063","n185967065","n185967068","n185967070","n185967074","n185967075","n185967076","n185967077"]},"w209718306":{"id":"w209718306","tags":{"area":"yes","building":"yes"},"nodes":["n2199127091","n2199127092","n2199127093","n2199127094","n2199127091"]},"w209718307":{"id":"w209718307","tags":{"area":"yes","building":"yes"},"nodes":["n2199127095","n2199127096","n2199127097","n2199127098","n2199127095"]},"w209718305":{"id":"w209718305","tags":{"area":"yes","building":"yes"},"nodes":["n2199127075","n2199127076","n2199127077","n2199127078","n2199127079","n2199127080","n2199127081","n2199127082","n2199127083","n2199127084","n2199127085","n2199127086","n2199127087","n2199127088","n2199127089","n2199127090","n2199127075"]},"n185960199":{"id":"n185960199","loc":[-85.62965,41.95469]},"n185980737":{"id":"n185980737","loc":[-85.629083,41.953725]},"n2114807561":{"id":"n2114807561","loc":[-85.6297681,41.9524688]},"n2114807597":{"id":"n2114807597","loc":[-85.6296517,41.952563]},"n185960197":{"id":"n185960197","loc":[-85.629676,41.9537314]},"n185978791":{"id":"n185978791","loc":[-85.6244542,41.9547066]},"w17967573":{"id":"w17967573","tags":{"highway":"residential","name":"E Wheeler St"},"nodes":["n185960195","n2114807561","n185968102","n185967430","n185986157","n185978392"]},"w17966553":{"id":"w17966553","tags":{"highway":"residential","name":"East Hoffman Street"},"nodes":["n185971631","n185978784","n185967432","n185968106","n185960199","n185978787","n185978790","n185978791"]},"w17966787":{"id":"w17966787","tags":{"highway":"residential","name":"East Cushman Street"},"nodes":["n185980735","n185980737","n185960197","n185968104","n185960792"]},"w17964723":{"id":"w17964723","tags":{"highway":"residential","name":"Cushman Street"},"nodes":["n185960792","n185960794","n185960796"]},"w17964654":{"id":"w17964654","tags":{"highway":"residential","name":"Pine Street"},"nodes":["n185960195","n2114807597","n185960197","n185960199"]},"n1819848862":{"id":"n1819848862","loc":[-85.6346087,41.9545845]},"n1819848935":{"id":"n1819848935","loc":[-85.6345948,41.9537717]},"n1819848973":{"id":"n1819848973","loc":[-85.6334247,41.9537827]},"n1819848997":{"id":"n1819848997","loc":[-85.6334386,41.9545956]},"n2189015861":{"id":"n2189015861","loc":[-85.6375906,41.954836]},"n2189015865":{"id":"n2189015865","loc":[-85.6383307,41.9548291]},"n2189015867":{"id":"n2189015867","loc":[-85.6383337,41.9550072]},"n2189015868":{"id":"n2189015868","loc":[-85.6380986,41.9550094]},"n2189015869":{"id":"n2189015869","loc":[-85.6381005,41.9551226]},"n2199109808":{"id":"n2199109808","loc":[-85.6372702,41.9522894]},"n2199109810":{"id":"n2199109810","loc":[-85.6372677,41.9521583]},"n2199109812":{"id":"n2199109812","loc":[-85.6369505,41.9521617]},"n2199109814":{"id":"n2199109814","loc":[-85.636953,41.9522927]},"n185952156":{"id":"n185952156","loc":[-85.640983,41.9546557]},"n185953423":{"id":"n185953423","loc":[-85.641871,41.954652]},"n185971637":{"id":"n185971637","loc":[-85.641583,41.95465]},"n185971639":{"id":"n185971639","loc":[-85.6421344,41.9546444]},"n185971642":{"id":"n185971642","loc":[-85.6428264,41.9545612]},"n185971648":{"id":"n185971648","loc":[-85.6436023,41.9544262]},"n185975066":{"id":"n185975066","loc":[-85.640532,41.953638]},"n185975067":{"id":"n185975067","loc":[-85.64079,41.953638]},"n185982166":{"id":"n185982166","loc":[-85.6399012,41.9523817]},"n2189015858":{"id":"n2189015858","loc":[-85.6376104,41.9560138]},"n2189015870":{"id":"n2189015870","loc":[-85.6386794,41.9551172]},"n2189015871":{"id":"n2189015871","loc":[-85.6386817,41.955256]},"n2189015873":{"id":"n2189015873","loc":[-85.6385437,41.9552573]},"n2189015876":{"id":"n2189015876","loc":[-85.638555,41.9559278]},"n2189015879":{"id":"n2189015879","loc":[-85.6384954,41.9559283]},"n2189015882":{"id":"n2189015882","loc":[-85.6384965,41.9559935]},"n2189015885":{"id":"n2189015885","loc":[-85.6383533,41.9559949]},"n2189015888":{"id":"n2189015888","loc":[-85.638351,41.9558607]},"n2189015891":{"id":"n2189015891","loc":[-85.6382178,41.9558619]},"n2189015894":{"id":"n2189015894","loc":[-85.6382203,41.956008]},"w208627223":{"id":"w208627223","tags":{"area":"yes","building":"yes"},"nodes":["n2189015858","n2189015861","n2189015865","n2189015867","n2189015868","n2189015869","n2189015870","n2189015871","n2189015873","n2189015876","n2189015879","n2189015882","n2189015885","n2189015888","n2189015891","n2189015894","n2189015858"]},"w170848328":{"id":"w170848328","tags":{"leisure":"park","name":"Bowman Park"},"nodes":["n1819848935","n1819848973","n1819848997","n1819848862","n1819848935"]},"w17965866":{"id":"w17965866","tags":{"highway":"residential","name":"West Hoffman Street"},"nodes":["n185971631","n185971632","n185964359","n185965025","n1475293264","n185952156","n185971637","n185953423","n185971639","n185971642","n185971648"]},"w209717051":{"id":"w209717051","tags":{"amenity":"place_of_worship","area":"yes","building":"yes","denomination":"baptist","name":"Calvary Missionary Baptist Church","religion":"christian"},"nodes":["n2199109808","n2199109810","n2199109812","n2199109814","n2199109808"]},"w17966172":{"id":"w17966172","tags":{"highway":"residential","name":"West Cushman Street"},"nodes":["n185960796","n185975064","n185964358","n185965023","n1475293222","n185975066","n185975067"]},"w17966975":{"id":"w17966975","tags":{"highway":"residential","name":"W Wheeler St"},"nodes":["n185978392","n185982163","n185964357","n185965021","n1475293261","n185982166"]},"n185960684":{"id":"n185960684","loc":[-85.622687,41.951885]},"n185960686":{"id":"n185960686","loc":[-85.622492,41.951901]},"n185978795":{"id":"n185978795","loc":[-85.6240991,41.954708]},"n185978803":{"id":"n185978803","loc":[-85.623348,41.954547]},"n185978806":{"id":"n185978806","loc":[-85.623123,41.954502]},"n185978808":{"id":"n185978808","loc":[-85.622923,41.954469]},"n185978810":{"id":"n185978810","loc":[-85.622787,41.954457]},"n185978811":{"id":"n185978811","loc":[-85.622612,41.954458]},"n185978813":{"id":"n185978813","loc":[-85.622368,41.954472]},"n1819790545":{"id":"n1819790545","loc":[-85.6240295,41.9548949]},"n1819790621":{"id":"n1819790621","loc":[-85.6235789,41.954855]},"n1819790664":{"id":"n1819790664","loc":[-85.6238363,41.9549507]},"n1819790683":{"id":"n1819790683","loc":[-85.6224727,41.9545921]},"n1819790730":{"id":"n1819790730","loc":[-85.6227527,41.9545795]},"n1819790740":{"id":"n1819790740","loc":[-85.6240402,41.9550784]},"n1819790831":{"id":"n1819790831","loc":[-85.624126,41.9549986]},"n1819790861":{"id":"n1819790861","loc":[-85.6231712,41.9546872]},"n1819790887":{"id":"n1819790887","loc":[-85.6242762,41.955206]},"n2168544739":{"id":"n2168544739","loc":[-85.6249102,41.952801]},"n2168544740":{"id":"n2168544740","loc":[-85.6251859,41.9527564]},"n2168544741":{"id":"n2168544741","loc":[-85.6255515,41.9527921]},"n2168544742":{"id":"n2168544742","loc":[-85.626001,41.9529481]},"n2168544743":{"id":"n2168544743","loc":[-85.6265284,41.9529838]},"n2168544744":{"id":"n2168544744","loc":[-85.626942,41.9528857]},"n2168544745":{"id":"n2168544745","loc":[-85.6270918,41.9526851]},"n2168544746":{"id":"n2168544746","loc":[-85.6272117,41.95244]},"n2168544747":{"id":"n2168544747","loc":[-85.6271578,41.952226]},"n2168544748":{"id":"n2168544748","loc":[-85.6270019,41.9519719]},"n2168544749":{"id":"n2168544749","loc":[-85.6268221,41.9518382]},"n2168544750":{"id":"n2168544750","loc":[-85.6265284,41.951807]},"n2168544751":{"id":"n2168544751","loc":[-85.6256534,41.9518516]},"n2168544752":{"id":"n2168544752","loc":[-85.6253477,41.9518338]},"n2168544753":{"id":"n2168544753","loc":[-85.6251139,41.9517669]},"n185955747":{"id":"n185955747","loc":[-85.620674,41.954709]},"n185960688":{"id":"n185960688","loc":[-85.621032,41.951913]},"n185972054":{"id":"n185972054","loc":[-85.6186728,41.9547335]},"n185978814":{"id":"n185978814","loc":[-85.6201708,41.9547403]},"n1819790532":{"id":"n1819790532","loc":[-85.6244908,41.9555731]},"n1819790536":{"id":"n1819790536","loc":[-85.6217925,41.9583135]},"n1819790538":{"id":"n1819790538","loc":[-85.6233954,41.9600014]},"n1819790539":{"id":"n1819790539","loc":[-85.6204611,41.9562117]},"n1819790546":{"id":"n1819790546","loc":[-85.6210898,41.9567657]},"n1819790548":{"id":"n1819790548","loc":[-85.6202465,41.9562237]},"n1819790550":{"id":"n1819790550","loc":[-85.6250165,41.9560677]},"n1819790551":{"id":"n1819790551","loc":[-85.6227946,41.9597023]},"n1819790553":{"id":"n1819790553","loc":[-85.6215726,41.9584571]},"n1819790556":{"id":"n1819790556","loc":[-85.6196306,41.9573002]},"n1819790557":{"id":"n1819790557","loc":[-85.6209503,41.9563109]},"n1819790558":{"id":"n1819790558","loc":[-85.6196939,41.9574085]},"n1819790561":{"id":"n1819790561","loc":[-85.621079,41.957751]},"n1819790562":{"id":"n1819790562","loc":[-85.6224255,41.9611417]},"n1819790565":{"id":"n1819790565","loc":[-85.6232506,41.9604841]},"n1819790566":{"id":"n1819790566","loc":[-85.6190835,41.9562909]},"n1819790567":{"id":"n1819790567","loc":[-85.622227,41.9593028]},"n1819790569":{"id":"n1819790569","loc":[-85.620976,41.9591039]},"n1819790571":{"id":"n1819790571","loc":[-85.6212078,41.9565303]},"n1819790572":{"id":"n1819790572","loc":[-85.6235306,41.9595102]},"n1819790581":{"id":"n1819790581","loc":[-85.6235563,41.9579351]},"n1819790584":{"id":"n1819790584","loc":[-85.6230371,41.9574598]},"n1819790586":{"id":"n1819790586","loc":[-85.6211748,41.9564272]},"n1819790588":{"id":"n1819790588","loc":[-85.6226508,41.9601086]},"n1819790591":{"id":"n1819790591","loc":[-85.6218032,41.9607468]},"n1819790593":{"id":"n1819790593","loc":[-85.6207915,41.9618735]},"n1819790596":{"id":"n1819790596","loc":[-85.6252955,41.9567858]},"n1819790598":{"id":"n1819790598","loc":[-85.6196618,41.9568939]},"n1819790600":{"id":"n1819790600","loc":[-85.6224416,41.9587084]},"n1819790602":{"id":"n1819790602","loc":[-85.6217442,41.9558641]},"n1819790603":{"id":"n1819790603","loc":[-85.6213355,41.9592116]},"n1819790604":{"id":"n1819790604","loc":[-85.622801,41.9573042]},"n1819790608":{"id":"n1819790608","loc":[-85.6199729,41.9574325]},"n1819790610":{"id":"n1819790610","loc":[-85.6195555,41.9557165]},"n1819790611":{"id":"n1819790611","loc":[-85.622978,41.9586007]},"n1819790613":{"id":"n1819790613","loc":[-85.6253963,41.9562636]},"n1819790614":{"id":"n1819790614","loc":[-85.6235252,41.9580342]},"n1819790616":{"id":"n1819790616","loc":[-85.6232988,41.9596305]},"n1819790617":{"id":"n1819790617","loc":[-85.6226776,41.9598732]},"n1819790619":{"id":"n1819790619","loc":[-85.625553,41.9561794]},"n1819790620":{"id":"n1819790620","loc":[-85.6235574,41.959231]},"n1819790624":{"id":"n1819790624","loc":[-85.6228429,41.9573726]},"n1819790626":{"id":"n1819790626","loc":[-85.6193785,41.9556766]},"n1819790628":{"id":"n1819790628","loc":[-85.620092,41.9554253]},"n1819790630":{"id":"n1819790630","loc":[-85.6226658,41.9604402]},"n1819790638":{"id":"n1819790638","loc":[-85.6219964,41.9602561]},"n1819790640":{"id":"n1819790640","loc":[-85.6232731,41.9599969]},"n1819790643":{"id":"n1819790643","loc":[-85.6247698,41.9568895]},"n1819790650":{"id":"n1819790650","loc":[-85.6216412,41.9550149]},"n1819790652":{"id":"n1819790652","loc":[-85.6224952,41.9603918]},"n1819790656":{"id":"n1819790656","loc":[-85.61918,41.9555649]},"n1819790661":{"id":"n1819790661","loc":[-85.6200169,41.955505]},"n1819790662":{"id":"n1819790662","loc":[-85.6217389,41.9563149]},"n1819790666":{"id":"n1819790666","loc":[-85.6229566,41.9598373]},"n1819790667":{"id":"n1819790667","loc":[-85.6209117,41.9609189]},"n1819790669":{"id":"n1819790669","loc":[-85.6252311,41.9562353]},"n1819790670":{"id":"n1819790670","loc":[-85.6209758,41.961868]},"n1819790672":{"id":"n1819790672","loc":[-85.6209557,41.9589078]},"n1819790673":{"id":"n1819790673","loc":[-85.6190352,41.9561393]},"n1819790675":{"id":"n1819790675","loc":[-85.6236432,41.9586685]},"n1819790676":{"id":"n1819790676","loc":[-85.6194901,41.9565389]},"n1819790678":{"id":"n1819790678","loc":[-85.6219266,41.9582417]},"n1819790680":{"id":"n1819790680","loc":[-85.6208258,41.9557211]},"n1819790681":{"id":"n1819790681","loc":[-85.6212024,41.9613212]},"n1819790682":{"id":"n1819790682","loc":[-85.624877,41.9559401]},"n1819790684":{"id":"n1819790684","loc":[-85.6206499,41.9583693]},"n1819790699":{"id":"n1819790699","loc":[-85.6215243,41.956279]},"n1819790701":{"id":"n1819790701","loc":[-85.6246625,41.9559321]},"n1819790703":{"id":"n1819790703","loc":[-85.6230478,41.9585089]},"n1819790708":{"id":"n1819790708","loc":[-85.6211102,41.9575402]},"n1819790710":{"id":"n1819790710","loc":[-85.6215082,41.9548468]},"n1819790711":{"id":"n1819790711","loc":[-85.6206552,41.9586007]},"n1819790713":{"id":"n1819790713","loc":[-85.6215404,41.9549705]},"n1819790715":{"id":"n1819790715","loc":[-85.6216906,41.955521]},"n1819790717":{"id":"n1819790717","loc":[-85.6215404,41.9547391]},"n1819790722":{"id":"n1819790722","loc":[-85.6219964,41.9599131]},"n1819790723":{"id":"n1819790723","loc":[-85.622286,41.9606989]},"n1819790725":{"id":"n1819790725","loc":[-85.6228439,41.9572005]},"n1819790727":{"id":"n1819790727","loc":[-85.6202518,41.9554458]},"n1819790728":{"id":"n1819790728","loc":[-85.623434,41.9575276]},"n1819790729":{"id":"n1819790729","loc":[-85.6234287,41.9568576]},"n1819790732":{"id":"n1819790732","loc":[-85.6229566,41.9571369]},"n1819790733":{"id":"n1819790733","loc":[-85.6225543,41.9590275]},"n1819790734":{"id":"n1819790734","loc":[-85.6232892,41.9583135]},"n1819790736":{"id":"n1819790736","loc":[-85.622977,41.9608551]},"n1819790737":{"id":"n1819790737","loc":[-85.624008,41.9569533]},"n1819790741":{"id":"n1819790741","loc":[-85.6212775,41.9608545]},"n1819790742":{"id":"n1819790742","loc":[-85.6231282,41.9569932]},"n1819790743":{"id":"n1819790743","loc":[-85.6224523,41.9591831]},"n1819790744":{"id":"n1819790744","loc":[-85.6210951,41.9610819]},"n1819790745":{"id":"n1819790745","loc":[-85.6220114,41.960544]},"n1819790755":{"id":"n1819790755","loc":[-85.6216369,41.9553854]},"n1819790757":{"id":"n1819790757","loc":[-85.6209986,41.9592709]},"n1819790758":{"id":"n1819790758","loc":[-85.6200437,41.9563468]},"n1819790764":{"id":"n1819790764","loc":[-85.6219363,41.9596823]},"n1819790765":{"id":"n1819790765","loc":[-85.6237612,41.9568496]},"n1819790769":{"id":"n1819790769","loc":[-85.6212389,41.9593433]},"n1819790771":{"id":"n1819790771","loc":[-85.6210726,41.9560123]},"n1819790772":{"id":"n1819790772","loc":[-85.6212711,41.9561838]},"n1819790776":{"id":"n1819790776","loc":[-85.6234437,41.9577795]},"n1819790777":{"id":"n1819790777","loc":[-85.6212502,41.9618599]},"n1819790783":{"id":"n1819790783","loc":[-85.6216895,41.9610585]},"n1819790784":{"id":"n1819790784","loc":[-85.6200115,41.9556367]},"n1819790785":{"id":"n1819790785","loc":[-85.6210576,41.9573002]},"n1819790786":{"id":"n1819790786","loc":[-85.621138,41.9576632]},"n1819790788":{"id":"n1819790788","loc":[-85.6207733,41.9578946]},"n1819790789":{"id":"n1819790789","loc":[-85.6200705,41.9571566]},"n1819790790":{"id":"n1819790790","loc":[-85.6245337,41.9558443]},"n1819790792":{"id":"n1819790792","loc":[-85.621932,41.9608066]},"n1819790793":{"id":"n1819790793","loc":[-85.6233578,41.9581385]},"n1819790794":{"id":"n1819790794","loc":[-85.6204557,41.9555136]},"n1819790797":{"id":"n1819790797","loc":[-85.6235038,41.9576074]},"n1819790800":{"id":"n1819790800","loc":[-85.6214438,41.9607508]},"n1819790801":{"id":"n1819790801","loc":[-85.623492,41.9602129]},"n1819790802":{"id":"n1819790802","loc":[-85.6216691,41.9546553]},"n1819790803":{"id":"n1819790803","loc":[-85.6231057,41.9586851]},"n1819790804":{"id":"n1819790804","loc":[-85.6209224,41.9578673]},"n1819790813":{"id":"n1819790813","loc":[-85.620092,41.9572962]},"n1819790814":{"id":"n1819790814","loc":[-85.6216691,41.9552218]},"n1819790816":{"id":"n1819790816","loc":[-85.6216144,41.9609668]},"n1819790818":{"id":"n1819790818","loc":[-85.6216906,41.9557324]},"n1819790820":{"id":"n1819790820","loc":[-85.6192069,41.9564186]},"n1819790823":{"id":"n1819790823","loc":[-85.6211155,41.9566027]},"n1819790825":{"id":"n1819790825","loc":[-85.6233106,41.9569294]},"n1819790839":{"id":"n1819790839","loc":[-85.625671,41.9564986]},"n1819790842":{"id":"n1819790842","loc":[-85.6235252,41.9567379]},"n1819790844":{"id":"n1819790844","loc":[-85.6253813,41.9566342]},"n1819790847":{"id":"n1819790847","loc":[-85.6200963,41.9567702]},"n1819790849":{"id":"n1819790849","loc":[-85.6238031,41.9587449]},"n1819790851":{"id":"n1819790851","loc":[-85.6234984,41.9584571]},"n1819790856":{"id":"n1819790856","loc":[-85.6242226,41.9570092]},"n1819790865":{"id":"n1819790865","loc":[-85.6200265,41.9569458]},"n1819790869":{"id":"n1819790869","loc":[-85.6230049,41.9601245]},"n1819790871":{"id":"n1819790871","loc":[-85.6190727,41.9558322]},"n1819790873":{"id":"n1819790873","loc":[-85.6217442,41.9550104]},"n1819790875":{"id":"n1819790875","loc":[-85.6208044,41.9587808]},"n1819790879":{"id":"n1819790879","loc":[-85.6198444,41.9574484]},"n1819790883":{"id":"n1819790883","loc":[-85.623713,41.9588719]},"n1819790885":{"id":"n1819790885","loc":[-85.6223289,41.9605075]},"n1819790889":{"id":"n1819790889","loc":[-85.6208044,41.9562437]},"n1819790893":{"id":"n1819790893","loc":[-85.6218183,41.9559684]},"n1819790906":{"id":"n1819790906","loc":[-85.6214052,41.958697]},"n1819790913":{"id":"n1819790913","loc":[-85.6209981,41.9609957]},"n1819790917":{"id":"n1819790917","loc":[-85.6216208,41.9604436]},"n1819790919":{"id":"n1819790919","loc":[-85.6209406,41.9616373]},"n1819790920":{"id":"n1819790920","loc":[-85.6221948,41.9583334]},"n1819790922":{"id":"n1819790922","loc":[-85.6216681,41.9615292]},"n1819790924":{"id":"n1819790924","loc":[-85.6210147,41.9570489]},"n1819790929":{"id":"n1819790929","loc":[-85.6193678,41.955521]},"w17964707":{"id":"w17964707","tags":{"highway":"residential","name":"11th Ave"},"nodes":["n185960682","n185960684","n185960686","n185960688","n185960690"]},"w201484345":{"id":"w201484345","tags":{"bridge":"yes","highway":"residential","name":"E Hoffman St"},"nodes":["n185978791","n185978795"]},"w201484348":{"id":"w201484348","tags":{"highway":"residential","name":"E Hoffman St"},"nodes":["n185978795","n185978800","n185978803","n185978806","n185978808","n185978810","n185978811","n185978813","n185955747","n185978814","n185972054","n185978817"]},"w170843845":{"id":"w170843845","tags":{"landuse":"reservoir","name":"Hoffman Pond","natural":"water"},"nodes":["n1819790732","n1819790742","n1819790825","n1819790729","n1819790842","n1819790765","n1819790737","n1819790856","n1819790643","n1819790596","n1819790844","n1819790839","n1819849190","n1819790619","n1819790613","n1819790669","n1819790550","n1819790682","n1819790701","n1819790790","n1819790532","n1819790887","n1819790740","n1819790831","n1819790545","n1819790664","n1819790621","n1819790861","n1819790730","n1819790683","n1819790802","n1819790717","n1819790710","n1819790713","n1819790650","n1819790873","n1819790814","n1819790755","n1819790715","n1819790818","n1819790602","n1819790893","n1819790662","n1819790699","n1819790772","n1819790771","n1819790680","n1819790794","n1819790727","n1819790628","n1819790661","n1819790784","n1819790610","n1819790626","n1819790929","n1819790656","n1819790871","n1819790673","n1819790566","n1819790820","n1819790676","n1819790598","n1819790556","n1819790558","n1819790879","n1819790608","n1819790813","n1819790789","n1819790865","n1819790847","n1819790758","n1819790548","n1819790539","n1819790889","n1819790557","n1819790586","n1819790571","n1819790823","n1819790546","n1819790924","n1819790785","n1819790708","n1819790786","n1819790561","n1819790804","n1819790788","n1819790684","n1819790711","n1819790875","n1819790672","n1819790569","n1819790757","n1819790769","n1819790603","n1819790906","n1819790553","n1819790536","n1819790678","n1819790920","n1819790600","n1819790733","n1819790743","n1819790567","n1819790764","n1819790722","n1819790638","n1819790917","n1819790800","n1819790741","n1819790667","n1819790913","n1819790744","n1819790816","n1819790591","n1819790745","n1819790885","n1819790652","n1819790588","n1819790617","n1819790551","n1819790666","n1819790869","n1819790630","n1819790723","n1819790792","n1819790783","n1819790681","n1819790919","n1819790593","n1819790670","n1819790777","n1819790922","n1819790562","n1819790736","n1819790565","n1819790801","n1819790538","n1819790640","n1819790616","n1819790572","n1819790620","n1819790883","n1819790849","n1819790675","n1819790851","n1819790803","n1819790611","n1819790703","n1819790734","n1819790793","n1819790614","n1819790581","n1819790776","n1819790797","n1819790728","n1819790584","n1819790624","n1819790604","n1819790725","n1819790732"]},"w206805240":{"id":"w206805240","tags":{"waterway":"river"},"nodes":["n2168544738","n2168544739","n2168544740","n2168544741","n2168544742","n2168544743","n2168544744","n2168544745","n2168544746","n2168544747","n2168544748","n2168544749","n2168544750","n2168544751","n2168544752","n2168544753","n1819848944"]},"n394490429":{"id":"n394490429","loc":[-85.643883,41.954365]},"n185953421":{"id":"n185953421","loc":[-85.641876,41.954946]},"n185953417":{"id":"n185953417","loc":[-85.6418306,41.9551597]},"n185977233":{"id":"n185977233","loc":[-85.642987,41.95486]},"n185977232":{"id":"n185977232","loc":[-85.642894,41.9547842]},"n1475293244":{"id":"n1475293244","loc":[-85.63974,41.9521543]},"n1819848890":{"id":"n1819848890","loc":[-85.6410004,41.9552822]},"n1819848965":{"id":"n1819848965","loc":[-85.6409795,41.9553892]},"n2189015846":{"id":"n2189015846","loc":[-85.6420457,41.9549528]},"n2189015849":{"id":"n2189015849","loc":[-85.6425867,41.9551392]},"n2189015852":{"id":"n2189015852","loc":[-85.6426877,41.9549771]},"n2199109816":{"id":"n2199109816","loc":[-85.6399215,41.9540925]},"n2199109818":{"id":"n2199109818","loc":[-85.6399182,41.9538236]},"n2199109820":{"id":"n2199109820","loc":[-85.6402201,41.9538216]},"n2199109822":{"id":"n2199109822","loc":[-85.640222,41.9539771]},"n2199109825":{"id":"n2199109825","loc":[-85.6402904,41.9539766]},"n2199109827":{"id":"n2199109827","loc":[-85.6402918,41.95409]},"n2199109829":{"id":"n2199109829","loc":[-85.6395845,41.9544626]},"n2199109831":{"id":"n2199109831","loc":[-85.6395792,41.9540671]},"n2199109833":{"id":"n2199109833","loc":[-85.6397173,41.9540661]},"n2199109835":{"id":"n2199109835","loc":[-85.6397226,41.9544616]},"n2199109837":{"id":"n2199109837","loc":[-85.6399641,41.9545058]},"n2199109839":{"id":"n2199109839","loc":[-85.6399637,41.9541859]},"n2199109841":{"id":"n2199109841","loc":[-85.6401098,41.9541858]},"n2199109843":{"id":"n2199109843","loc":[-85.64011,41.9543272]},"n2199109845":{"id":"n2199109845","loc":[-85.6400783,41.9543273]},"n2199109847":{"id":"n2199109847","loc":[-85.6400785,41.9545058]},"n2199109853":{"id":"n2199109853","loc":[-85.6396184,41.9554049]},"n2199109855":{"id":"n2199109855","loc":[-85.6396825,41.9553713]},"n185949745":{"id":"n185949745","loc":[-85.6442727,41.9553112]},"n185949748":{"id":"n185949748","loc":[-85.6448804,41.9555238]},"n185949755":{"id":"n185949755","loc":[-85.6420011,41.9603536]},"n185949763":{"id":"n185949763","loc":[-85.6408843,41.9555822]},"n185949765":{"id":"n185949765","loc":[-85.6414548,41.9557751]},"n185952158":{"id":"n185952158","loc":[-85.640066,41.956854]},"n185952160":{"id":"n185952160","loc":[-85.639848,41.957229]},"n185952161":{"id":"n185952161","loc":[-85.6396089,41.9576192]},"n185952163":{"id":"n185952163","loc":[-85.63892,41.957957]},"n185953413":{"id":"n185953413","loc":[-85.64162,41.955475]},"n185971651":{"id":"n185971651","loc":[-85.6440766,41.9543462]},"n185977234":{"id":"n185977234","loc":[-85.645044,41.955581]},"n394490395":{"id":"n394490395","loc":[-85.657336,41.936762]},"n394490396":{"id":"n394490396","loc":[-85.653896,41.936978]},"n394490397":{"id":"n394490397","loc":[-85.653732,41.937386]},"n394490398":{"id":"n394490398","loc":[-85.65182,41.937378]},"n394490399":{"id":"n394490399","loc":[-85.651843,41.938445]},"n394490400":{"id":"n394490400","loc":[-85.652536,41.938447]},"n394490401":{"id":"n394490401","loc":[-85.652533,41.938901]},"n394490402":{"id":"n394490402","loc":[-85.652084,41.9389]},"n394490403":{"id":"n394490403","loc":[-85.6521,41.939627]},"n394490404":{"id":"n394490404","loc":[-85.652301,41.939628]},"n394490405":{"id":"n394490405","loc":[-85.652302,41.939755]},"n394490406":{"id":"n394490406","loc":[-85.652783,41.939747]},"n394490407":{"id":"n394490407","loc":[-85.652835,41.94112]},"n394490408":{"id":"n394490408","loc":[-85.651968,41.941123]},"n394490409":{"id":"n394490409","loc":[-85.651983,41.941969]},"n394490410":{"id":"n394490410","loc":[-85.652908,41.941961]},"n394490411":{"id":"n394490411","loc":[-85.65292,41.94278]},"n394490412":{"id":"n394490412","loc":[-85.651698,41.942816]},"n394490413":{"id":"n394490413","loc":[-85.651509,41.942823]},"n394490414":{"id":"n394490414","loc":[-85.651272,41.942837]},"n394490415":{"id":"n394490415","loc":[-85.651272,41.943325]},"n394490416":{"id":"n394490416","loc":[-85.65122,41.944053]},"n394490417":{"id":"n394490417","loc":[-85.651193,41.944449]},"n394490418":{"id":"n394490418","loc":[-85.651088,41.944969]},"n394490419":{"id":"n394490419","loc":[-85.650949,41.945554]},"n394490420":{"id":"n394490420","loc":[-85.650907,41.945719]},"n394490421":{"id":"n394490421","loc":[-85.650808,41.946016]},"n394490422":{"id":"n394490422","loc":[-85.650712,41.946516]},"n394490423":{"id":"n394490423","loc":[-85.650493,41.947166]},"n394490424":{"id":"n394490424","loc":[-85.650626,41.947213]},"n394490425":{"id":"n394490425","loc":[-85.650201,41.948109]},"n394490426":{"id":"n394490426","loc":[-85.649868,41.948797]},"n394490427":{"id":"n394490427","loc":[-85.649669,41.949161]},"n394490428":{"id":"n394490428","loc":[-85.64659,41.954067]},"n394490430":{"id":"n394490430","loc":[-85.644034,41.95444]},"n394490431":{"id":"n394490431","loc":[-85.644248,41.954507]},"n394490432":{"id":"n394490432","loc":[-85.64491,41.954481]},"n394490433":{"id":"n394490433","loc":[-85.645213,41.954433]},"n394490434":{"id":"n394490434","loc":[-85.645426,41.954477]},"n394490435":{"id":"n394490435","loc":[-85.6458,41.954704]},"n394490436":{"id":"n394490436","loc":[-85.64605,41.954804]},"n394490437":{"id":"n394490437","loc":[-85.646125,41.954817]},"n394490438":{"id":"n394490438","loc":[-85.646002,41.954997]},"n394490439":{"id":"n394490439","loc":[-85.645764,41.955366]},"n394490440":{"id":"n394490440","loc":[-85.645525,41.955734]},"n394490441":{"id":"n394490441","loc":[-85.64443,41.957424]},"n394490442":{"id":"n394490442","loc":[-85.641712,41.961723]},"n394490443":{"id":"n394490443","loc":[-85.640747,41.963246]},"n394490444":{"id":"n394490444","loc":[-85.637803,41.967894]},"n394490445":{"id":"n394490445","loc":[-85.637673,41.967861]},"n394490446":{"id":"n394490446","loc":[-85.636637,41.969275]},"n394490447":{"id":"n394490447","loc":[-85.634923,41.969269]},"n394490448":{"id":"n394490448","loc":[-85.634893,41.968537]},"n394490449":{"id":"n394490449","loc":[-85.634544,41.96927]},"n394490450":{"id":"n394490450","loc":[-85.630835,41.969274]},"n394490451":{"id":"n394490451","loc":[-85.630834,41.968348]},"n394490452":{"id":"n394490452","loc":[-85.630857,41.968179]},"n394490453":{"id":"n394490453","loc":[-85.630924,41.968044]},"n394490454":{"id":"n394490454","loc":[-85.631004,41.967925]},"n394490455":{"id":"n394490455","loc":[-85.631143,41.967811]},"n394490456":{"id":"n394490456","loc":[-85.631311,41.967736]},"n394490457":{"id":"n394490457","loc":[-85.631595,41.967693]},"n394490458":{"id":"n394490458","loc":[-85.63325,41.967702]},"n394490459":{"id":"n394490459","loc":[-85.633247,41.967021]},"n394490460":{"id":"n394490460","loc":[-85.634858,41.967021]},"n394490461":{"id":"n394490461","loc":[-85.634865,41.967711]},"n394490462":{"id":"n394490462","loc":[-85.634884,41.968231]},"n394490463":{"id":"n394490463","loc":[-85.636559,41.963867]},"n394490464":{"id":"n394490464","loc":[-85.634832,41.963866]},"n394490465":{"id":"n394490465","loc":[-85.63481,41.961899]},"n394490466":{"id":"n394490466","loc":[-85.637219,41.961842]},"n394490467":{"id":"n394490467","loc":[-85.637837,41.960019]},"n394490468":{"id":"n394490468","loc":[-85.637459,41.960022]},"n394490469":{"id":"n394490469","loc":[-85.635295,41.959987]},"n394490470":{"id":"n394490470","loc":[-85.634783,41.959979]},"n394490471":{"id":"n394490471","loc":[-85.634776,41.959834]},"n394490472":{"id":"n394490472","loc":[-85.634767,41.959009]},"n394490473":{"id":"n394490473","loc":[-85.634763,41.958292]},"n394490474":{"id":"n394490474","loc":[-85.633346,41.958287]},"n394490475":{"id":"n394490475","loc":[-85.632128,41.9583]},"n394490476":{"id":"n394490476","loc":[-85.631414,41.958318]},"n394490477":{"id":"n394490477","loc":[-85.63137,41.959033]},"n394490478":{"id":"n394490478","loc":[-85.631325,41.959753]},"n394490479":{"id":"n394490479","loc":[-85.631494,41.95977]},"n394490480":{"id":"n394490480","loc":[-85.631456,41.960673]},"n394490481":{"id":"n394490481","loc":[-85.631421,41.961494]},"n394490482":{"id":"n394490482","loc":[-85.631404,41.961887]},"n394490483":{"id":"n394490483","loc":[-85.631401,41.961968]},"n394490484":{"id":"n394490484","loc":[-85.630962,41.961967]},"n394490485":{"id":"n394490485","loc":[-85.6299,41.961973]},"n394490486":{"id":"n394490486","loc":[-85.624929,41.962002]},"n394490487":{"id":"n394490487","loc":[-85.623333,41.961987]},"n394490488":{"id":"n394490488","loc":[-85.621894,41.963956]},"n394490489":{"id":"n394490489","loc":[-85.62131,41.963727]},"n394490490":{"id":"n394490490","loc":[-85.621216,41.963868]},"n394490491":{"id":"n394490491","loc":[-85.620356,41.965119]},"n394490492":{"id":"n394490492","loc":[-85.620848,41.965341]},"n394490493":{"id":"n394490493","loc":[-85.620684,41.965558]},"n394490494":{"id":"n394490494","loc":[-85.620621,41.965658]},"n394490495":{"id":"n394490495","loc":[-85.618165,41.965759]},"n394490496":{"id":"n394490496","loc":[-85.618071,41.965759]},"n394490497":{"id":"n394490497","loc":[-85.617986,41.965759]},"n394490498":{"id":"n394490498","loc":[-85.605673,41.965764]},"n394490499":{"id":"n394490499","loc":[-85.605668,41.963548]},"n394490500":{"id":"n394490500","loc":[-85.605664,41.962094]},"n394490501":{"id":"n394490501","loc":[-85.595828,41.962159]},"n394490502":{"id":"n394490502","loc":[-85.587869,41.962169]},"n394490503":{"id":"n394490503","loc":[-85.586289,41.962179]},"n394490504":{"id":"n394490504","loc":[-85.583774,41.962178]},"n394490505":{"id":"n394490505","loc":[-85.583774,41.961789]},"n394490506":{"id":"n394490506","loc":[-85.581303,41.961783]},"n394490507":{"id":"n394490507","loc":[-85.581304,41.961616]},"n394490508":{"id":"n394490508","loc":[-85.581292,41.961616]},"n394490509":{"id":"n394490509","loc":[-85.581247,41.959244]},"n394490510":{"id":"n394490510","loc":[-85.581245,41.958394]},"n394490511":{"id":"n394490511","loc":[-85.581276,41.958372]},"n394490512":{"id":"n394490512","loc":[-85.581302,41.958353]},"n394490513":{"id":"n394490513","loc":[-85.581376,41.9583]},"n394490514":{"id":"n394490514","loc":[-85.582256,41.957663]},"n394490515":{"id":"n394490515","loc":[-85.585299,41.955483]},"n394490516":{"id":"n394490516","loc":[-85.585588,41.955331]},"n394490517":{"id":"n394490517","loc":[-85.586053,41.955163]},"n394490518":{"id":"n394490518","loc":[-85.58632,41.955076]},"n394490519":{"id":"n394490519","loc":[-85.586478,41.955025]},"n394490520":{"id":"n394490520","loc":[-85.58692,41.954947]},"n394490521":{"id":"n394490521","loc":[-85.587327,41.954914]},"n394490522":{"id":"n394490522","loc":[-85.587345,41.954913]},"n394490523":{"id":"n394490523","loc":[-85.587358,41.954913]},"n394490524":{"id":"n394490524","loc":[-85.58963,41.954877]},"n394490525":{"id":"n394490525","loc":[-85.591077,41.954865]},"n394490526":{"id":"n394490526","loc":[-85.594824,41.954843]},"n394490527":{"id":"n394490527","loc":[-85.594804,41.95331]},"n394490528":{"id":"n394490528","loc":[-85.599336,41.95331]},"n394490529":{"id":"n394490529","loc":[-85.599336,41.954825]},"n394490530":{"id":"n394490530","loc":[-85.597828,41.954839]},"n394490531":{"id":"n394490531","loc":[-85.597833,41.95614]},"n394490532":{"id":"n394490532","loc":[-85.596586,41.956151]},"n394490533":{"id":"n394490533","loc":[-85.596586,41.956394]},"n394490534":{"id":"n394490534","loc":[-85.595933,41.956394]},"n394490535":{"id":"n394490535","loc":[-85.595933,41.958176]},"n394490536":{"id":"n394490536","loc":[-85.597635,41.958179]},"n394490537":{"id":"n394490537","loc":[-85.597717,41.958177]},"n394490538":{"id":"n394490538","loc":[-85.601671,41.958194]},"n394490539":{"id":"n394490539","loc":[-85.605619,41.958194]},"n394490540":{"id":"n394490540","loc":[-85.608054,41.958187]},"n394490542":{"id":"n394490542","loc":[-85.6080762,41.9547864]},"n394490545":{"id":"n394490545","loc":[-85.6104354,41.9548263]},"n394490546":{"id":"n394490546","loc":[-85.610274,41.951106]},"n394490547":{"id":"n394490547","loc":[-85.610278,41.950829]},"n394490548":{"id":"n394490548","loc":[-85.610309,41.948377]},"n394490549":{"id":"n394490549","loc":[-85.610314,41.947986]},"n394490550":{"id":"n394490550","loc":[-85.610464,41.947985]},"n394490551":{"id":"n394490551","loc":[-85.610447,41.947468]},"n394490552":{"id":"n394490552","loc":[-85.612469,41.947471]},"n394490553":{"id":"n394490553","loc":[-85.612494,41.945576]},"n394490554":{"id":"n394490554","loc":[-85.610292,41.94558]},"n394490555":{"id":"n394490555","loc":[-85.608412,41.945625]},"n394490556":{"id":"n394490556","loc":[-85.608412,41.943036]},"n394490557":{"id":"n394490557","loc":[-85.608702,41.943087]},"n394490558":{"id":"n394490558","loc":[-85.609196,41.943224]},"n394490559":{"id":"n394490559","loc":[-85.609571,41.943263]},"n394490560":{"id":"n394490560","loc":[-85.610116,41.943295]},"n394490561":{"id":"n394490561","loc":[-85.610273,41.943275]},"n394490562":{"id":"n394490562","loc":[-85.611339,41.943075]},"n394490563":{"id":"n394490563","loc":[-85.611575,41.942997]},"n394490564":{"id":"n394490564","loc":[-85.611847,41.942849]},"n394490565":{"id":"n394490565","loc":[-85.612164,41.942568]},"n394490566":{"id":"n394490566","loc":[-85.612341,41.942529]},"n394490567":{"id":"n394490567","loc":[-85.612562,41.942524]},"n394490568":{"id":"n394490568","loc":[-85.612768,41.942546]},"n394490569":{"id":"n394490569","loc":[-85.612938,41.942633]},"n394490570":{"id":"n394490570","loc":[-85.6131,41.942782]},"n394490571":{"id":"n394490571","loc":[-85.613299,41.942919]},"n394490572":{"id":"n394490572","loc":[-85.613498,41.942996]},"n394490573":{"id":"n394490573","loc":[-85.614698,41.942842]},"n394490574":{"id":"n394490574","loc":[-85.615288,41.942698]},"n394490575":{"id":"n394490575","loc":[-85.616054,41.942693]},"n394490576":{"id":"n394490576","loc":[-85.61603,41.942175]},"n394490577":{"id":"n394490577","loc":[-85.616004,41.941741]},"n394490578":{"id":"n394490578","loc":[-85.615994,41.940156]},"n394490579":{"id":"n394490579","loc":[-85.615144,41.940159]},"n394490580":{"id":"n394490580","loc":[-85.614915,41.940161]},"n394490582":{"id":"n394490582","loc":[-85.614875,41.938532]},"n394490583":{"id":"n394490583","loc":[-85.616167,41.938787]},"n394490585":{"id":"n394490585","loc":[-85.616176,41.938589]},"n394490586":{"id":"n394490586","loc":[-85.614537,41.938282]},"n394490588":{"id":"n394490588","loc":[-85.610141,41.937459]},"n394490589":{"id":"n394490589","loc":[-85.610172,41.937298]},"n394490590":{"id":"n394490590","loc":[-85.609918,41.935495]},"n394490592":{"id":"n394490592","loc":[-85.610092,41.935451]},"n394490594":{"id":"n394490594","loc":[-85.610681,41.935247]},"n394490595":{"id":"n394490595","loc":[-85.611446,41.934955]},"n394490596":{"id":"n394490596","loc":[-85.612057,41.934696]},"n394490598":{"id":"n394490598","loc":[-85.613256,41.934084]},"n394490599":{"id":"n394490599","loc":[-85.613948,41.933682]},"n394490601":{"id":"n394490601","loc":[-85.61436,41.933417]},"n394490602":{"id":"n394490602","loc":[-85.614638,41.933212]},"n394490604":{"id":"n394490604","loc":[-85.615249,41.9332]},"n394490605":{"id":"n394490605","loc":[-85.618218,41.933223]},"n394490607":{"id":"n394490607","loc":[-85.618241,41.933479]},"n394490608":{"id":"n394490608","loc":[-85.618257,41.93365]},"n394490609":{"id":"n394490609","loc":[-85.618298,41.935067]},"n394490611":{"id":"n394490611","loc":[-85.619791,41.935067]},"n394490612":{"id":"n394490612","loc":[-85.619794,41.933301]},"n394490613":{"id":"n394490613","loc":[-85.619795,41.932692]},"n394490614":{"id":"n394490614","loc":[-85.619729,41.929517]},"n394490615":{"id":"n394490615","loc":[-85.619801,41.929305]},"n394490616":{"id":"n394490616","loc":[-85.619809,41.927391]},"n394490617":{"id":"n394490617","loc":[-85.620883,41.927378]},"n394490618":{"id":"n394490618","loc":[-85.620988,41.927368]},"n394490619":{"id":"n394490619","loc":[-85.621076,41.927368]},"n394490620":{"id":"n394490620","loc":[-85.621156,41.927376]},"n394490621":{"id":"n394490621","loc":[-85.621685,41.92737]},"n394490622":{"id":"n394490622","loc":[-85.624716,41.927359]},"n394490623":{"id":"n394490623","loc":[-85.625308,41.92737]},"n394490624":{"id":"n394490624","loc":[-85.625655,41.927377]},"n394490625":{"id":"n394490625","loc":[-85.625093,41.925591]},"n394490626":{"id":"n394490626","loc":[-85.625174,41.92559]},"n394490627":{"id":"n394490627","loc":[-85.625249,41.925597]},"n394490628":{"id":"n394490628","loc":[-85.625532,41.925604]},"n394490629":{"id":"n394490629","loc":[-85.625761,41.925597]},"n394490630":{"id":"n394490630","loc":[-85.625955,41.926153]},"n394490631":{"id":"n394490631","loc":[-85.626209,41.926155]},"n394490632":{"id":"n394490632","loc":[-85.627757,41.926151]},"n394490633":{"id":"n394490633","loc":[-85.627825,41.926298]},"n394490634":{"id":"n394490634","loc":[-85.627994,41.926315]},"n394490635":{"id":"n394490635","loc":[-85.628049,41.927196]},"n394490636":{"id":"n394490636","loc":[-85.62949,41.927221]},"n394490637":{"id":"n394490637","loc":[-85.629602,41.927277]},"n394490638":{"id":"n394490638","loc":[-85.6297102,41.9273279]},"n394490639":{"id":"n394490639","loc":[-85.630958,41.927398]},"n394490699":{"id":"n394490699","loc":[-85.632741,41.927388]},"n394490700":{"id":"n394490700","loc":[-85.632997,41.927391]},"n394490701":{"id":"n394490701","loc":[-85.633149,41.927393]},"n394490702":{"id":"n394490702","loc":[-85.633334,41.927393]},"n394490703":{"id":"n394490703","loc":[-85.633468,41.927561]},"n394490704":{"id":"n394490704","loc":[-85.633563,41.927755]},"n394490705":{"id":"n394490705","loc":[-85.633662,41.928192]},"n394490706":{"id":"n394490706","loc":[-85.633679,41.928807]},"n394490707":{"id":"n394490707","loc":[-85.633687,41.929107]},"n394490708":{"id":"n394490708","loc":[-85.633927,41.929109]},"n394490709":{"id":"n394490709","loc":[-85.634126,41.929111]},"n394490710":{"id":"n394490710","loc":[-85.634207,41.92911]},"n394490711":{"id":"n394490711","loc":[-85.634323,41.929111]},"n394490712":{"id":"n394490712","loc":[-85.636712,41.929128]},"n394490713":{"id":"n394490713","loc":[-85.63808,41.9291]},"n394490714":{"id":"n394490714","loc":[-85.639213,41.929088]},"n394490715":{"id":"n394490715","loc":[-85.639189,41.92852]},"n394490716":{"id":"n394490716","loc":[-85.639204,41.925488]},"n394490717":{"id":"n394490717","loc":[-85.644204,41.925452]},"n394490718":{"id":"n394490718","loc":[-85.651425,41.925406]},"n394490719":{"id":"n394490719","loc":[-85.651449,41.926321]},"n394490720":{"id":"n394490720","loc":[-85.651451,41.926969]},"n394490721":{"id":"n394490721","loc":[-85.651458,41.928052]},"n394490722":{"id":"n394490722","loc":[-85.651446,41.928892]},"n394490723":{"id":"n394490723","loc":[-85.651456,41.929447]},"n394490724":{"id":"n394490724","loc":[-85.651707,41.929454]},"n394490725":{"id":"n394490725","loc":[-85.652369,41.929473]},"n394490726":{"id":"n394490726","loc":[-85.6525,41.929452]},"n394490727":{"id":"n394490727","loc":[-85.654066,41.92946]},"n394490728":{"id":"n394490728","loc":[-85.654816,41.92946]},"n394490729":{"id":"n394490729","loc":[-85.654816,41.930337]},"n394490730":{"id":"n394490730","loc":[-85.654587,41.930337]},"n394490731":{"id":"n394490731","loc":[-85.654548,41.931072]},"n394490732":{"id":"n394490732","loc":[-85.654538,41.931701]},"n394490733":{"id":"n394490733","loc":[-85.654898,41.931689]},"n394490734":{"id":"n394490734","loc":[-85.654898,41.932505]},"n394490735":{"id":"n394490735","loc":[-85.654854,41.932514]},"n394490736":{"id":"n394490736","loc":[-85.655497,41.932499]},"n394490737":{"id":"n394490737","loc":[-85.656405,41.932493]},"n394490738":{"id":"n394490738","loc":[-85.656422,41.933416]},"n394490739":{"id":"n394490739","loc":[-85.657322,41.933438]},"n1475293233":{"id":"n1475293233","loc":[-85.6385522,41.9585167]},"n1475293242":{"id":"n1475293242","loc":[-85.64609,41.9540815]},"n1475293249":{"id":"n1475293249","loc":[-85.6358079,41.9692721]},"n1475293256":{"id":"n1475293256","loc":[-85.6387369,41.9581583]},"n1475293259":{"id":"n1475293259","loc":[-85.6455882,41.9541138]},"n1475293266":{"id":"n1475293266","loc":[-85.6451008,41.9541821]},"n1819800253":{"id":"n1819800253","loc":[-85.6134286,41.9429692]},"n2114807558":{"id":"n2114807558","loc":[-85.6365609,41.963866],"tags":{"railway":"level_crossing"}},"n2189015728":{"id":"n2189015728","loc":[-85.6383956,41.9590576]},"n2189015838":{"id":"n2189015838","loc":[-85.6435144,41.9563705]},"n2189015842":{"id":"n2189015842","loc":[-85.6415782,41.9557035]},"n2189015855":{"id":"n2189015855","loc":[-85.6440829,41.9554577]},"n2199109849":{"id":"n2199109849","loc":[-85.6393434,41.9565591]},"n2199109851":{"id":"n2199109851","loc":[-85.6393208,41.9565002]},"n2199109857":{"id":"n2199109857","loc":[-85.6401986,41.955545]},"n2199109859":{"id":"n2199109859","loc":[-85.6402362,41.955587]},"n2199109861":{"id":"n2199109861","loc":[-85.6395958,41.9565675]},"n2199109863":{"id":"n2199109863","loc":[-85.639528,41.9566011]},"w209717053":{"id":"w209717053","tags":{"area":"yes","building":"yes"},"nodes":["n2199109829","n2199109831","n2199109833","n2199109835","n2199109829"]},"w17966415":{"id":"w17966415","tags":{"access":"private","highway":"service","name":"Manufacturing Way"},"nodes":["n185971642","n185977232","n185977233","n185949745","n185949748","n185977234"]},"w209717054":{"id":"w209717054","tags":{"area":"yes","building":"yes"},"nodes":["n2199109837","n2199109839","n2199109841","n2199109843","n2199109845","n2199109847","n2199109837"]},"w208627214":{"id":"w208627214","tags":{"highway":"service"},"nodes":["n185949755","n2189015728","n1475293233","n1475293256","n185952163","n185952161","n185952160","n185952158","n185949763","n1819848965","n1819848890","n185952156"]},"w17963817":{"id":"w17963817","tags":{"access":"private","highway":"service"},"nodes":["n185949765","n185953413","n185953417","n185953421","n185953423"]},"w34369809":{"id":"w34369809","tags":{"admin_level":"8","boundary":"administrative","landuse":"residential"},"nodes":["n394490395","n394490396","n394490397","n394490398","n394490399","n394490400","n394490401","n394490402","n394490403","n394490404","n394490405","n394490406","n394490407","n394490408","n394490409","n394490410","n394490411","n394490412","n394490413","n394490414","n394490415","n394490416","n394490417","n394490418","n394490419","n394490420","n394490421","n394490422","n394490423","n394490424","n394490425","n394490426","n394490427","n394490428","n1475293242","n1475293259","n1475293266","n394490429","n394490430","n394490431","n394490432","n394490433","n394490434","n394490435","n394490436","n394490437","n394490438","n394490439","n394490440","n394490441","n394490442","n394490443","n394490444","n394490445","n394490446","n1475293249","n394490447","n394490448","n394490449","n394490450","n394490451","n394490452","n394490453","n394490454","n394490455","n394490456","n394490457","n394490458","n394490459","n394490460","n394490461","n394490462","n2114807558","n394490463","n1475293226","n394490464","n394490465","n394490466","n394490467","n394490468","n394490469","n394490470","n394490471","n394490472","n394490473","n394490474","n394490475","n394490476","n394490477","n394490478","n394490479","n394490480","n394490481","n394490482","n394490483","n394490484","n394490485","n394490486","n394490487","n394490488","n394490489","n394490490","n394490491","n394490492","n394490493","n394490494","n394490495","n394490496","n394490497","n394490498","n394490499","n394490500","n394490501","n394490502","n394490503","n394490504","n394490505","n394490506","n394490507","n394490508","n394490509","n394490510","n394490511","n394490512","n394490513","n394490514","n394490515","n394490516","n394490517","n394490518","n394490519","n394490520","n394490521","n394490522","n394490523","n394490524","n394490525","n394490526","n394490527","n394490528","n394490529","n394490530","n394490531","n394490532","n394490533","n394490534","n394490535","n394490536","n394490537","n394490538","n394490539","n394490540","n394490542","n394490545","n394490546","n394490547","n394490548","n394490549","n394490550","n394490551","n394490552","n394490553","n394490554","n394490555","n394490556","n394490557","n394490558","n394490559","n394490560","n394490561","n394490562","n394490563","n394490564","n394490565","n394490566","n394490567","n394490568","n394490569","n394490570","n394490571","n1819800253","n394490572","n394490573","n394490574","n394490575","n394490576","n394490577","n394490578","n394490579","n394490580","n394490582","n394490583","n394490585","n394490586","n394490588","n394490589","n394490590","n394490592","n394490594","n394490595","n394490596","n394490598","n394490599","n394490601","n394490602","n394490604","n394490605","n394490607","n394490608","n394490609","n394490611","n394490612","n394490613","n394490614","n394490615","n394490616","n394490617","n394490618","n394490619","n394490620","n394490621","n394490622","n394490623","n394490624","n394490625","n394490626","n394490627","n394490628","n394490629","n394490630","n394490631","n394490632","n394490633","n394490634","n394490635","n394490636","n394490637","n394490638","n394490639","n394490699","n394490700","n394490701","n394490702","n394490703","n394490704","n394490705","n394490706","n394490707","n394490708","n394490709","n394490710","n394490711","n394490712","n394490713","n394490714","n394490715","n394490716","n394490717","n394490718","n394490719","n394490720","n394490721","n394490722","n394490723","n394490724","n394490725","n394490726","n394490727","n394490728","n394490729","n394490730","n394490731","n394490732","n394490733","n394490734","n394490735","n394490736","n394490737","n394490738","n394490739","n394490395"]},"w208627221":{"id":"w208627221","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189015838","n2189015842","n2189015846","n2189015849","n2189015852","n2189015855","n2189015838"]},"w209717052":{"id":"w209717052","tags":{"area":"yes","building":"yes"},"nodes":["n2199109816","n2199109818","n2199109820","n2199109822","n2199109825","n2199109827","n2199109816"]},"w134151784":{"id":"w134151784","tags":{"bridge":"yes","highway":"residential","name":"W Hoffman St"},"nodes":["n185971648","n185971651"]},"w209717055":{"id":"w209717055","tags":{"area":"yes","landuse":"basin"},"nodes":["n2199109849","n2199109851","n2199109853","n2199109855","n2199109857","n2199109859","n2199109861","n2199109863","n2199109849"]},"w17967763":{"id":"w17967763","tags":{"highway":"residential","name":"Rock River Ave"},"nodes":["n1475293244","n185982166","n185975067","n185971637"]},"r134949":{"id":"r134949","tags":{"admin_level":"8","border_type":"city","boundary":"administrative","name":"Three Rivers","place":"city","type":"boundary"},"members":[{"id":"w34369809","type":"way","role":"outer"},{"id":"w34369821","type":"way","role":"outer"},{"id":"w34369822","type":"way","role":"outer"},{"id":"w34369823","type":"way","role":"outer"},{"id":"w34369824","type":"way","role":"outer"},{"id":"w34369825","type":"way","role":"outer"},{"id":"w34369826","type":"way","role":"outer"},{"id":"w34369810","type":"way","role":"inner"},{"id":"w34369811","type":"way","role":"inner"},{"id":"w34369812","type":"way","role":"inner"},{"id":"w34367079","type":"way","role":"inner"},{"id":"w34369814","type":"way","role":"inner"},{"id":"w34367080","type":"way","role":"inner"},{"id":"w34369815","type":"way","role":"inner"},{"id":"w34369820","type":"way","role":"inner"}]},"n1819848881":{"id":"n1819848881","loc":[-85.638562,41.9569965]},"n1819848947":{"id":"n1819848947","loc":[-85.6384348,41.9576565]},"n1819849044":{"id":"n1819849044","loc":[-85.6385749,41.9573345]},"n2114807547":{"id":"n2114807547","loc":[-85.6384626,41.9583756]},"n2114807564":{"id":"n2114807564","loc":[-85.638535,41.9581283]},"n2189015691":{"id":"n2189015691","loc":[-85.6435584,41.9565243]},"n2189015696":{"id":"n2189015696","loc":[-85.6435805,41.9566049]},"n2189015722":{"id":"n2189015722","loc":[-85.6435035,41.9567438]},"n2189015744":{"id":"n2189015744","loc":[-85.6437991,41.9569582]},"n2189015747":{"id":"n2189015747","loc":[-85.6433042,41.9567742]},"n2189015750":{"id":"n2189015750","loc":[-85.6433827,41.9566844]},"n2189015753":{"id":"n2189015753","loc":[-85.6430447,41.9565588]},"n2189015756":{"id":"n2189015756","loc":[-85.6431111,41.956451]},"n2189015759":{"id":"n2189015759","loc":[-85.6420247,41.956083]},"n2189015760":{"id":"n2189015760","loc":[-85.6419945,41.9561369]},"n2189015764":{"id":"n2189015764","loc":[-85.6413729,41.9558945]},"n2189015766":{"id":"n2189015766","loc":[-85.6412884,41.9560606]},"n2189015770":{"id":"n2189015770","loc":[-85.6411798,41.9560112]},"n2189015771":{"id":"n2189015771","loc":[-85.6410651,41.9562132]},"n2189015774":{"id":"n2189015774","loc":[-85.6409504,41.9561728]},"n2189015778":{"id":"n2189015778","loc":[-85.6407996,41.9564241]},"n2189015781":{"id":"n2189015781","loc":[-85.6406889,41.9563892]},"n2189015785":{"id":"n2189015785","loc":[-85.6404857,41.9567024]},"n2189015789":{"id":"n2189015789","loc":[-85.6406909,41.9567877]},"n2189015793":{"id":"n2189015793","loc":[-85.6405642,41.9570165]},"n2189015796":{"id":"n2189015796","loc":[-85.6415359,41.9573711]},"n2189015800":{"id":"n2189015800","loc":[-85.6411738,41.9579501]},"n2189015804":{"id":"n2189015804","loc":[-85.6411119,41.957921]},"n2189015808":{"id":"n2189015808","loc":[-85.6403186,41.9591751]},"n2189015909":{"id":"n2189015909","loc":[-85.6389293,41.9564636]},"n2189015926":{"id":"n2189015926","loc":[-85.6385431,41.9564617]},"n2189015929":{"id":"n2189015929","loc":[-85.6385457,41.9561823]},"n2189015932":{"id":"n2189015932","loc":[-85.6389319,41.9561843]},"n2199109865":{"id":"n2199109865","loc":[-85.6400768,41.956776]},"n2199109867":{"id":"n2199109867","loc":[-85.639902,41.9567153]},"n2199109869":{"id":"n2199109869","loc":[-85.640004,41.956553]},"n2199109871":{"id":"n2199109871","loc":[-85.6401788,41.9566137]},"n2199109873":{"id":"n2199109873","loc":[-85.6399316,41.9564506],"tags":{"man_made":"water_tower"}},"n2199109876":{"id":"n2199109876","loc":[-85.6397689,41.9572354]},"n2199109878":{"id":"n2199109878","loc":[-85.6399229,41.9569826]},"n2199109880":{"id":"n2199109880","loc":[-85.639706,41.9569095]},"n2199109882":{"id":"n2199109882","loc":[-85.639552,41.9571623]},"n2199109884":{"id":"n2199109884","loc":[-85.6391028,41.9569517]},"n2199109886":{"id":"n2199109886","loc":[-85.6392876,41.956646]},"n2199109888":{"id":"n2199109888","loc":[-85.639484,41.9567117]},"n2199109889":{"id":"n2199109889","loc":[-85.6394322,41.9567973]},"n2199109890":{"id":"n2199109890","loc":[-85.6393718,41.9567771]},"n2199109891":{"id":"n2199109891","loc":[-85.6392387,41.9569972]},"n1819848900":{"id":"n1819848900","loc":[-85.638281,41.9576578]},"n1819848978":{"id":"n1819848978","loc":[-85.6377186,41.9580867]},"n1819849039":{"id":"n1819849039","loc":[-85.6384217,41.9573405]},"n1819849050":{"id":"n1819849050","loc":[-85.6377011,41.9570042]},"n1819849088":{"id":"n1819849088","loc":[-85.6382879,41.9580817]},"n2114807549":{"id":"n2114807549","loc":[-85.6362551,41.96473]},"n2114807587":{"id":"n2114807587","loc":[-85.6368694,41.9629829]},"n2189015725":{"id":"n2189015725","loc":[-85.644156,41.9569753]},"n2189015741":{"id":"n2189015741","loc":[-85.6419825,41.9597632]},"w208627217":{"id":"w208627217","tags":{"area":"yes","building":"yes"},"nodes":["n2189015741","n2189015744","n2189015747","n2189015750","n2189015753","n2189015756","n2189015759","n2189015760","n2189015764","n2189015766","n2189015770","n2189015771","n2189015774","n2189015778","n2189015781","n2189015785","n2189015789","n2189015793","n2189015796","n2189015800","n2189015804","n2189015808","n2189015741"]},"w208627212":{"id":"w208627212","tags":{"highway":"service"},"nodes":["n2189015691","n2189015696","n2189015722","n2189015725"]},"w209717057":{"id":"w209717057","tags":{"area":"yes","building":"yes"},"nodes":["n2199109876","n2199109878","n2199109880","n2199109882","n2199109876"]},"w209717056":{"id":"w209717056","tags":{"area":"yes","building":"yes"},"nodes":["n2199109865","n2199109867","n2199109869","n2199109871","n2199109865"]},"w208627231":{"id":"w208627231","tags":{"area":"yes","building":"yes"},"nodes":["n2189015909","n2189015926","n2189015929","n2189015932","n2189015909"]},"w170848326":{"id":"w170848326","tags":{"building":"yes"},"nodes":["n1819848881","n1819849050","n1819848978","n1819849088","n1819848900","n1819848947","n1819849039","n1819849044","n1819848881"]},"w17963182":{"id":"w17963182","tags":{"highway":"service"},"nodes":["n185949763","n185949765","n2189015691","n185949745"]},"w201484340":{"id":"w201484340","tags":{"railway":"rail","service":"siding"},"nodes":["n2114807565","n2114807564","n2114807547","n2114807587","n2114807558","n2114807549","n2114807593"]},"w209717058":{"id":"w209717058","tags":{"area":"yes","building":"yes"},"nodes":["n2199109884","n2199109886","n2199109888","n2199109889","n2199109890","n2199109891","n2199109884"]},"n185954650":{"id":"n185954650","loc":[-85.627331,41.957439]},"n185966949":{"id":"n185966949","loc":[-85.626868,41.957314]},"n185989335":{"id":"n185989335","loc":[-85.62529,41.958568]},"n185989337":{"id":"n185989337","loc":[-85.624962,41.958453]},"n185989339":{"id":"n185989339","loc":[-85.624832,41.958399]},"n185989340":{"id":"n185989340","loc":[-85.624707,41.958325]},"n185989342":{"id":"n185989342","loc":[-85.624636,41.958251]},"n185989345":{"id":"n185989345","loc":[-85.624578,41.95818]},"n185989347":{"id":"n185989347","loc":[-85.624533,41.958099]},"n185989349":{"id":"n185989349","loc":[-85.624507,41.957985]},"n185989351":{"id":"n185989351","loc":[-85.624495,41.957807]},"n185989353":{"id":"n185989353","loc":[-85.624514,41.957663]},"n185989354":{"id":"n185989354","loc":[-85.624577,41.957593]},"n185989356":{"id":"n185989356","loc":[-85.624685,41.95754]},"n185989357":{"id":"n185989357","loc":[-85.624802,41.957523]},"n185989359":{"id":"n185989359","loc":[-85.624996,41.957524]},"n185989361":{"id":"n185989361","loc":[-85.625409,41.957515]},"n185989364":{"id":"n185989364","loc":[-85.625634,41.957496]},"n185989367":{"id":"n185989367","loc":[-85.625832,41.957453]},"n185989368":{"id":"n185989368","loc":[-85.626044,41.957394]},"n354031352":{"id":"n354031352","loc":[-85.6252778,41.9586111],"tags":{"amenity":"place_of_worship","denomination":"baptist","name":"First Baptist Church","religion":"christian"}},"n2199109892":{"id":"n2199109892","loc":[-85.6261578,41.9589963]},"n2199109893":{"id":"n2199109893","loc":[-85.6263191,41.9586865]},"n2199109894":{"id":"n2199109894","loc":[-85.6261186,41.9586288]},"n2199109895":{"id":"n2199109895","loc":[-85.6260644,41.9587329]},"n2199109896":{"id":"n2199109896","loc":[-85.6261547,41.9587589]},"n2199109898":{"id":"n2199109898","loc":[-85.6260476,41.9589646]},"n185966951":{"id":"n185966951","loc":[-85.628404,41.957438]},"w17965351":{"id":"w17965351","tags":{"highway":"residential","name":"Flower Street"},"nodes":["n185966948","n185966949","n185954650","n185966951","n185966953","n185966955","n185966957"]},"w17967809":{"id":"w17967809","tags":{"highway":"residential","name":"Azaleamum Drive"},"nodes":["n185982197","n185989335","n185989337","n185989339","n185989340","n185989342","n185989345","n185989347","n185989349","n185989351","n185989353","n185989354","n185989356","n185989357","n185989359","n185989361","n185989364","n185989367","n185989368","n185982196"]},"w209717059":{"id":"w209717059","tags":{"area":"yes","building":"yes"},"nodes":["n2199109892","n2199109893","n2199109894","n2199109895","n2199109896","n2199109898","n2199109892"]},"n185961390":{"id":"n185961390","loc":[-85.63137,41.959033]},"n185961393":{"id":"n185961393","loc":[-85.634315,41.959017]},"w17966214":{"id":"w17966214","tags":{"highway":"residential","name":"East Adams Street"},"nodes":["n185975351","n185967434","n185968108"]},"w17964793":{"id":"w17964793","tags":{"highway":"residential","name":"Morris Ave"},"nodes":["n185961389","n185961390","n185961391","n185961393","n185961396"]},"n185952166":{"id":"n185952166","loc":[-85.638174,41.95831]},"n2114807552":{"id":"n2114807552","loc":[-85.6383526,41.9593788]},"n2114807591":{"id":"n2114807591","loc":[-85.6383741,41.9593968]},"n2189015731":{"id":"n2189015731","loc":[-85.6368404,41.9592785]},"n2189015734":{"id":"n2189015734","loc":[-85.6368404,41.9585918]},"n2189015737":{"id":"n2189015737","loc":[-85.6376009,41.9585918]},"n2189015738":{"id":"n2189015738","loc":[-85.6376009,41.9592785]},"n2189015897":{"id":"n2189015897","loc":[-85.6376839,41.9566137]},"n2189015900":{"id":"n2189015900","loc":[-85.6376831,41.9564865]},"n2189015903":{"id":"n2189015903","loc":[-85.6381161,41.9564851]},"n2189015906":{"id":"n2189015906","loc":[-85.6381168,41.9566122]},"n2189015937":{"id":"n2189015937","loc":[-85.6364789,41.9590634]},"n2189015940":{"id":"n2189015940","loc":[-85.6361137,41.9590672]},"n2189015943":{"id":"n2189015943","loc":[-85.6361169,41.9594033]},"n2189015945":{"id":"n2189015945","loc":[-85.6363456,41.9594021]},"n2189015952":{"id":"n2189015952","loc":[-85.636112,41.958892]},"n2189015955":{"id":"n2189015955","loc":[-85.6364757,41.9588894]},"n2189015957":{"id":"n2189015957","loc":[-85.6364729,41.9586747]},"n2189015958":{"id":"n2189015958","loc":[-85.6361103,41.9586765]},"n2189015959":{"id":"n2189015959","loc":[-85.6364719,41.9585562]},"n2189015960":{"id":"n2189015960","loc":[-85.6361093,41.958558]},"n2189015961":{"id":"n2189015961","loc":[-85.6355494,41.9586403]},"n2189015962":{"id":"n2189015962","loc":[-85.635549,41.9584711]},"n2189015963":{"id":"n2189015963","loc":[-85.6351831,41.9584715]},"n2189015964":{"id":"n2189015964","loc":[-85.6351834,41.9586408]},"n2189015966":{"id":"n2189015966","loc":[-85.6359579,41.9586359]},"n2189015968":{"id":"n2189015968","loc":[-85.6359561,41.9585465]},"n2189015971":{"id":"n2189015971","loc":[-85.6355476,41.9585509]},"n2189015974":{"id":"n2189015974","loc":[-85.6359516,41.9592934]},"n2189015977":{"id":"n2189015977","loc":[-85.635949,41.9586697]},"n2189015980":{"id":"n2189015980","loc":[-85.6351329,41.9586716]},"n2189015983":{"id":"n2189015983","loc":[-85.6351318,41.9583949]},"n2189015986":{"id":"n2189015986","loc":[-85.6349148,41.9583954]},"n2189015989":{"id":"n2189015989","loc":[-85.6349186,41.9592958]},"n2189015995":{"id":"n2189015995","loc":[-85.6360173,41.9593286]},"n2189015998":{"id":"n2189015998","loc":[-85.6360278,41.9583079]},"n2114807550":{"id":"n2114807550","loc":[-85.6383392,41.9595404]},"n2114807551":{"id":"n2114807551","loc":[-85.6375855,41.9616107]},"n2114807559":{"id":"n2114807559","loc":[-85.6373978,41.9621273]},"n2114807562":{"id":"n2114807562","loc":[-85.6373361,41.9622609]},"n2114807563":{"id":"n2114807563","loc":[-85.6376472,41.9613953]},"n2114807574":{"id":"n2114807574","loc":[-85.636974,41.9627695]},"n2114807589":{"id":"n2114807589","loc":[-85.6383017,41.9595005]},"n2114807592":{"id":"n2114807592","loc":[-85.6377169,41.9613494]},"n2114807595":{"id":"n2114807595","loc":[-85.6371081,41.962574]},"n2189015934":{"id":"n2189015934","loc":[-85.6364855,41.9595098]},"n2189015949":{"id":"n2189015949","loc":[-85.6363466,41.9595105]},"w208627244":{"id":"w208627244","tags":{"highway":"service"},"nodes":["n2189015992","n2189015995","n2189015998"]},"w208627240":{"id":"w208627240","tags":{"area":"yes","building":"yes"},"nodes":["n2189015961","n2189015971","n2189015962","n2189015963","n2189015964","n2189015961"]},"w17967437":{"id":"w17967437","tags":{"highway":"residential","name":"Lyman St"},"nodes":["n185964361","n185984024"]},"w208627237":{"id":"w208627237","tags":{"area":"yes","building":"yes"},"nodes":["n2189015955","n2189015957","n2189015958","n2189015952","n2189015955"]},"w17967465":{"id":"w17967465","tags":{"highway":"residential","name":"W Adams St"},"nodes":["n185978394","n185984022","n185964360"]},"w208627228":{"id":"w208627228","tags":{"area":"yes","building":"yes"},"nodes":["n2189015897","n2189015900","n2189015903","n2189015906","n2189015897"]},"w201484351":{"id":"w201484351","tags":{"railway":"rail","service":"siding"},"nodes":["n2114807587","n2114807574","n2114807595","n2114807562","n2114807559","n2114807551","n2114807563","n2114807589","n2114807552"]},"w208627239":{"id":"w208627239","tags":{"area":"yes","building":"yes"},"nodes":["n2189015957","n2189015959","n2189015960","n2189015958","n2189015957"]},"w208627233":{"id":"w208627233","tags":{"area":"yes","building":"yes"},"nodes":["n2189015934","n2189015937","n2189015940","n2189015943","n2189015945","n2189015949","n2189015934"]},"w208627241":{"id":"w208627241","tags":{"area":"yes","building":"yes"},"nodes":["n2189015961","n2189015966","n2189015968","n2189015971","n2189015961"]},"w17967970":{"id":"w17967970","tags":{"highway":"residential","name":"Adams St"},"nodes":["n185975351","n185978394"]},"w208627235":{"id":"w208627235","tags":{"area":"yes","building":"yes"},"nodes":["n2189015940","n2189015952","n2189015955","n2189015937","n2189015940"]},"w17965468":{"id":"w17965468","tags":{"highway":"residential","name":"Armstrong Blvd"},"nodes":["n185967917","n2189015998","n185967918","n185964362","n185952166"]},"w201484346":{"id":"w201484346","tags":{"railway":"rail","service":"siding"},"nodes":["n2114807551","n2114807592","n2114807550","n2114807591"]},"w208627242":{"id":"w208627242","tags":{"amenity":"parking","area":"yes"},"nodes":["n2189015974","n2189015977","n2189015980","n2189015983","n2189015986","n2189015989","n2189015974"]},"w208627216":{"id":"w208627216","tags":{"area":"yes","building":"yes"},"nodes":["n2189015731","n2189015734","n2189015737","n2189015738","n2189015731"]},"n185984309":{"id":"n185984309","loc":[-85.631421,41.961494]},"n185987987":{"id":"n185987987","loc":[-85.631456,41.960673]},"n185965397":{"id":"n185965397","loc":[-85.634603,41.959838]},"w17965196":{"id":"w17965196","tags":{"highway":"residential","name":"Burke Ave"},"nodes":["n185965395","n185965397","n185965399"]},"w17967215":{"id":"w17967215","tags":{"highway":"residential","name":"Kellogg Ave"},"nodes":["n185968114","n185984309","n185967440","n185978402"]},"w17967597":{"id":"w17967597","tags":{"highway":"residential","name":"Barnard Ave"},"nodes":["n185968112","n185987987","n185967438","n185978399"]},"n394490857":{"id":"n394490857","loc":[-85.633952,41.960664]},"n394490858":{"id":"n394490858","loc":[-85.633938,41.960227]},"n394490859":{"id":"n394490859","loc":[-85.634794,41.960212]},"n394490860":{"id":"n394490860","loc":[-85.634815,41.960662]},"n394490861":{"id":"n394490861","loc":[-85.634103,41.961268]},"n394490862":{"id":"n394490862","loc":[-85.634103,41.961001]},"n394490863":{"id":"n394490863","loc":[-85.634504,41.961003]},"n394490864":{"id":"n394490864","loc":[-85.634561,41.961269]},"n1057629869":{"id":"n1057629869","loc":[-85.6382599,41.9612134]},"n1057629937":{"id":"n1057629937","loc":[-85.6380035,41.9616137]},"n2189016014":{"id":"n2189016014","loc":[-85.6360365,41.9626496]},"n2189016017":{"id":"n2189016017","loc":[-85.6360374,41.9623228]},"n2189016020":{"id":"n2189016020","loc":[-85.6367557,41.9623239]},"n2189016022":{"id":"n2189016022","loc":[-85.6367566,41.9619919]},"n2189016025":{"id":"n2189016025","loc":[-85.6351794,41.9619893]},"n2189016028":{"id":"n2189016028","loc":[-85.6351788,41.9622011]},"n2189016031":{"id":"n2189016031","loc":[-85.6350855,41.9622009]},"n2189016034":{"id":"n2189016034","loc":[-85.6350845,41.962527]},"n2189016037":{"id":"n2189016037","loc":[-85.6352732,41.9625273]},"n2189016039":{"id":"n2189016039","loc":[-85.6352738,41.9623178]},"n2189016042":{"id":"n2189016042","loc":[-85.6357712,41.9623186]},"n2189016044":{"id":"n2189016044","loc":[-85.6357702,41.9626492]},"n1057629880":{"id":"n1057629880","loc":[-85.638817,41.9619017]},"n1057629923":{"id":"n1057629923","loc":[-85.6390733,41.9615014]},"w91092312":{"id":"w91092312","tags":{"power":"station"},"nodes":["n1057629923","n1057629869","n1057629937","n1057629880","n1057629923"]},"w34369826":{"id":"w34369826","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490861","n394490862","n394490863","n394490864","n394490861"]},"w34369825":{"id":"w34369825","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490857","n394490858","n394490859","n394490860","n394490857"]},"w208627248":{"id":"w208627248","tags":{"area":"yes","building":"yes"},"nodes":["n2189016014","n2189016017","n2189016020","n2189016022","n2189016025","n2189016028","n2189016031","n2189016034","n2189016037","n2189016039","n2189016042","n2189016044","n2189016014"]},"n394490766":{"id":"n394490766","loc":[-85.616777,41.955642]},"n394490768":{"id":"n394490768","loc":[-85.617239,41.955644]},"n394490792":{"id":"n394490792","loc":[-85.619034,41.95543]},"n185972055":{"id":"n185972055","loc":[-85.6185905,41.9568211]},"n185972057":{"id":"n185972057","loc":[-85.6186688,41.9570086]},"n185972059":{"id":"n185972059","loc":[-85.6186924,41.9581453]},"n185972060":{"id":"n185972060","loc":[-85.6187082,41.9588211],"tags":{"highway":"turning_circle"}},"n1819790724":{"id":"n1819790724","loc":[-85.6182155,41.9555703]},"n1819790735":{"id":"n1819790735","loc":[-85.6184059,41.9566188]},"n1819790799":{"id":"n1819790799","loc":[-85.6182372,41.9563771]},"n1819790896":{"id":"n1819790896","loc":[-85.6181431,41.9557227]},"n185971405":{"id":"n185971405","loc":[-85.6186766,41.9577468]},"n185971565":{"id":"n185971565","loc":[-85.6181613,41.9560879]},"n185967985":{"id":"n185967985","loc":[-85.6186798,41.9585791]},"n185955753":{"id":"n185955753","loc":[-85.620773,41.9555854]},"n185955755":{"id":"n185955755","loc":[-85.6212652,41.9559891]},"n185955748":{"id":"n185955748","loc":[-85.620722,41.954858]},"n185955751":{"id":"n185955751","loc":[-85.6206912,41.955367]},"n185967987":{"id":"n185967987","loc":[-85.6159351,41.9585809]},"n185971407":{"id":"n185971407","loc":[-85.6159142,41.9577578]},"n185971570":{"id":"n185971570","loc":[-85.6162248,41.95603]},"n185971572":{"id":"n185971572","loc":[-85.6160402,41.9560749]},"n185971574":{"id":"n185971574","loc":[-85.61593,41.956201]},"n185981301":{"id":"n185981301","loc":[-85.6158973,41.9581601]},"n394490762":{"id":"n394490762","loc":[-85.617193,41.954706]},"n394490764":{"id":"n394490764","loc":[-85.616773,41.954737]},"n394490787":{"id":"n394490787","loc":[-85.618972,41.954737]},"n394490790":{"id":"n394490790","loc":[-85.619046,41.954929]},"n394490794":{"id":"n394490794","loc":[-85.619922,41.955296]},"n394490796":{"id":"n394490796","loc":[-85.61991,41.95501]},"n394490798":{"id":"n394490798","loc":[-85.619974,41.954751]},"n1819790677":{"id":"n1819790677","loc":[-85.6187031,41.9550522]},"n1819790787":{"id":"n1819790787","loc":[-85.6186436,41.9552022]},"n1819790828":{"id":"n1819790828","loc":[-85.6185127,41.9553393]},"w17966857":{"id":"w17966857","tags":{"access":"private","highway":"service","name":"Sable River Rd"},"nodes":["n185972059","n185981301"]},"w34369814":{"id":"w34369814","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490787","n394490790","n394490792","n394490794","n394490796","n394490798","n394490787"]},"w17964176":{"id":"w17964176","tags":{"highway":"residential"},"nodes":["n185955747","n185955748","n185955751","n185955753","n185955755"]},"w17965838":{"id":"w17965838","tags":{"access":"private","highway":"service","name":"Pine River Rd"},"nodes":["n185971405","n185971407"]},"w17965476":{"id":"w17965476","tags":{"access":"private","highway":"service","name":"Raisin River Rd"},"nodes":["n185967985","n185967987"]},"w17965913":{"id":"w17965913","tags":{"access":"private","highway":"service","name":"Shiawassee River Rd"},"nodes":["n185972054","n1819790677","n1819790787","n1819790828","n1819790724","n1819790896","n185971565","n1819790799","n1819790735","n185972055","n185972057","n185971405","n185972059","n185967985","n185972060"]},"w34369811":{"id":"w34369811","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490762","n394490764","n394490766","n394490768","n394490762"]},"w17965854":{"id":"w17965854","tags":{"access":"private","highway":"service","name":"Sturgeon River Rd"},"nodes":["n185971565","n185971570","n185971572","n185971574"]},"n2139795769":{"id":"n2139795769","loc":[-85.6250804,41.9608796]},"n2139795770":{"id":"n2139795770","loc":[-85.6250315,41.9613684]},"n2139795771":{"id":"n2139795771","loc":[-85.6249671,41.9614362]},"n2139795772":{"id":"n2139795772","loc":[-85.6249698,41.961522]},"n2139795773":{"id":"n2139795773","loc":[-85.6250798,41.9615838]},"n2139795774":{"id":"n2139795774","loc":[-85.6252273,41.9615639]},"n2139795775":{"id":"n2139795775","loc":[-85.6252863,41.9614622]},"n2139795776":{"id":"n2139795776","loc":[-85.6252273,41.9613764]},"n2139795777":{"id":"n2139795777","loc":[-85.6251227,41.9613525]},"n2139795778":{"id":"n2139795778","loc":[-85.6249564,41.9612527]},"n2139795779":{"id":"n2139795779","loc":[-85.6249846,41.9610254]},"n2139795780":{"id":"n2139795780","loc":[-85.6266725,41.9599647]},"n2139795781":{"id":"n2139795781","loc":[-85.6259162,41.9599711]},"n2139795782":{"id":"n2139795782","loc":[-85.6257185,41.960019]},"n2139795783":{"id":"n2139795783","loc":[-85.6255509,41.9601213]},"n185963539":{"id":"n185963539","loc":[-85.615718,41.983893]},"n185964418":{"id":"n185964418","loc":[-85.616626,42.049512]},"n185966614":{"id":"n185966614","loc":[-85.615514,41.976603]},"n185966635":{"id":"n185966635","loc":[-85.616118,42.013017]},"n185969040":{"id":"n185969040","loc":[-85.615632,41.972357]},"n185969070":{"id":"n185969070","loc":[-85.619145,41.967648]},"n185972156":{"id":"n185972156","loc":[-85.621894,41.963956]},"n185972157":{"id":"n185972157","loc":[-85.621806,41.964077]},"n185972158":{"id":"n185972158","loc":[-85.620848,41.965341]},"n185972159":{"id":"n185972159","loc":[-85.620684,41.965558]},"n185972160":{"id":"n185972160","loc":[-85.620621,41.965658]},"n185972161":{"id":"n185972161","loc":[-85.617844,41.969359]},"n185972162":{"id":"n185972162","loc":[-85.616843,41.97068]},"n185972164":{"id":"n185972164","loc":[-85.616714,41.970839]},"n185972166":{"id":"n185972166","loc":[-85.615879,41.971969]},"n185972168":{"id":"n185972168","loc":[-85.615748,41.972159]},"n185972170":{"id":"n185972170","loc":[-85.615589,41.972502]},"n185972172":{"id":"n185972172","loc":[-85.615542,41.972733]},"n185972175":{"id":"n185972175","loc":[-85.615524,41.972947]},"n185972177":{"id":"n185972177","loc":[-85.615512,41.973715]},"n185972179":{"id":"n185972179","loc":[-85.615513,41.976496]},"n185972180":{"id":"n185972180","loc":[-85.615538,41.977246]},"n185972181":{"id":"n185972181","loc":[-85.61558,41.982139]},"n185972184":{"id":"n185972184","loc":[-85.61557,41.983317]},"n185972186":{"id":"n185972186","loc":[-85.615591,41.983463]},"n185972188":{"id":"n185972188","loc":[-85.615763,41.984146]},"n185972190":{"id":"n185972190","loc":[-85.615814,41.98435]},"n185972192":{"id":"n185972192","loc":[-85.615965,41.998453]},"n185972194":{"id":"n185972194","loc":[-85.615982,42.001237]},"n185972195":{"id":"n185972195","loc":[-85.616055,42.00555]},"n185972197":{"id":"n185972197","loc":[-85.616134,42.014887]},"n185972199":{"id":"n185972199","loc":[-85.616177,42.018465]},"n185972201":{"id":"n185972201","loc":[-85.616298,42.027627]},"n185972203":{"id":"n185972203","loc":[-85.616513,42.042212]},"w203968015":{"id":"w203968015","tags":{"highway":"residential"},"nodes":["n2139795768","n2139795769"]},"w17965932":{"id":"w17965932","tags":{"highway":"residential","name":"Buckhorn Road","name_1":"County Highway 122"},"nodes":["n185972155","n185972156","n185972157","n185972158","n185972159","n185972160","n185969070","n185972161","n185972162","n185972164","n185972166","n185972168","n185969040","n185972170","n185972172","n185972175","n185972177","n185972179","n185966614","n185972180","n185972181","n185972184","n185972186","n185963539","n185972188","n185972190","n185972192","n185972194","n185972195","n185966635","n185972197","n185972199","n185972201","n185972203","n185964418"]},"w203968016":{"id":"w203968016","tags":{"highway":"residential","name":"New Jersey Court"},"nodes":["n2139795770","n2139795771","n2139795772","n2139795773","n2139795774","n2139795775","n2139795776","n2139795777","n2139795770","n2139795778","n2139795779","n2139795769"]},"w203968017":{"id":"w203968017","tags":{"highway":"residential","name":"Oklahoma Drive"},"nodes":["n2139795780","n2139795781","n2139795782","n2139795783","n2139795769"]},"n1819790528":{"id":"n1819790528","loc":[-85.6184827,41.960025]},"n1819790530":{"id":"n1819790530","loc":[-85.6168626,41.9605834]},"n1819790534":{"id":"n1819790534","loc":[-85.6197379,41.9617163]},"n1819790541":{"id":"n1819790541","loc":[-85.6198881,41.9620833]},"n1819790543":{"id":"n1819790543","loc":[-85.619695,41.9619397]},"n1819790547":{"id":"n1819790547","loc":[-85.6190298,41.9609504]},"n1819790555":{"id":"n1819790555","loc":[-85.6180471,41.9609788]},"n1819790559":{"id":"n1819790559","loc":[-85.6203817,41.9605436]},"n1819790583":{"id":"n1819790583","loc":[-85.6201564,41.9603282]},"n1819790590":{"id":"n1819790590","loc":[-85.617045,41.9598894]},"n1819790609":{"id":"n1819790609","loc":[-85.6177638,41.9598495]},"n1819790618":{"id":"n1819790618","loc":[-85.6195234,41.9610143]},"n1819790642":{"id":"n1819790642","loc":[-85.6181179,41.9627933]},"n1819790659":{"id":"n1819790659","loc":[-85.6174634,41.962897]},"n1819790665":{"id":"n1819790665","loc":[-85.6170343,41.9630885]},"n1819790674":{"id":"n1819790674","loc":[-85.6194697,41.9601925]},"n1819790685":{"id":"n1819790685","loc":[-85.6207722,41.9610665]},"n1819790687":{"id":"n1819790687","loc":[-85.6202315,41.9622109]},"n1819790697":{"id":"n1819790697","loc":[-85.6184505,41.9624662]},"n1819790726":{"id":"n1819790726","loc":[-85.6178926,41.9628492]},"n1819790738":{"id":"n1819790738","loc":[-85.6173347,41.9598016]},"n1819790762":{"id":"n1819790762","loc":[-85.6186221,41.9609105]},"n1819790774":{"id":"n1819790774","loc":[-85.6175922,41.9608308]},"n1819790781":{"id":"n1819790781","loc":[-85.6167768,41.9633198]},"n1819790796":{"id":"n1819790796","loc":[-85.619856,41.961461]},"n1819790811":{"id":"n1819790811","loc":[-85.6208215,41.9620195]},"n1819790833":{"id":"n1819790833","loc":[-85.618311,41.9612536]},"n1819790854":{"id":"n1819790854","loc":[-85.6183646,41.9626417]},"n1819790863":{"id":"n1819790863","loc":[-85.6204997,41.9608547]},"n1819790867":{"id":"n1819790867","loc":[-85.6184934,41.9621391]},"n1819790877":{"id":"n1819790877","loc":[-85.6206928,41.9621152]},"n1819790881":{"id":"n1819790881","loc":[-85.6170879,41.960735]},"n1819790891":{"id":"n1819790891","loc":[-85.6168304,41.9601207]},"n1819790898":{"id":"n1819790898","loc":[-85.619813,41.9612297]},"n1819790909":{"id":"n1819790909","loc":[-85.6167982,41.960376]},"n1819790912":{"id":"n1819790912","loc":[-85.6205855,41.9610462]},"n1819790544":{"id":"n1819790544","loc":[-85.612968,41.9707781]},"n1819790549":{"id":"n1819790549","loc":[-85.614395,41.9697172]},"n1819790552":{"id":"n1819790552","loc":[-85.6180535,41.9655536]},"n1819790554":{"id":"n1819790554","loc":[-85.6111227,41.9703713]},"n1819790560":{"id":"n1819790560","loc":[-85.6112729,41.9701958]},"n1819790563":{"id":"n1819790563","loc":[-85.6137512,41.9689917]},"n1819790564":{"id":"n1819790564","loc":[-85.6181072,41.9659205]},"n1819790595":{"id":"n1819790595","loc":[-85.6170021,41.9666863]},"n1819790605":{"id":"n1819790605","loc":[-85.6168948,41.9644527]},"n1819790606":{"id":"n1819790606","loc":[-85.6128071,41.9701081]},"n1819790607":{"id":"n1819790607","loc":[-85.6129251,41.9704032]},"n1819790612":{"id":"n1819790612","loc":[-85.6177638,41.9663912]},"n1819790615":{"id":"n1819790615","loc":[-85.6152533,41.9670373]},"n1819790622":{"id":"n1819790622","loc":[-85.6146739,41.9673804]},"n1819790623":{"id":"n1819790623","loc":[-85.6180428,41.9661838]},"n1819790625":{"id":"n1819790625","loc":[-85.6172918,41.9646202]},"n1819790645":{"id":"n1819790645","loc":[-85.6178067,41.965043]},"n1819790647":{"id":"n1819790647","loc":[-85.6143306,41.9712488]},"n1819790649":{"id":"n1819790649","loc":[-85.6147383,41.9707702]},"n1819790654":{"id":"n1819790654","loc":[-85.6157361,41.9668459]},"n1819790657":{"id":"n1819790657","loc":[-85.6145666,41.9710733]},"n1819790668":{"id":"n1819790668","loc":[-85.6166909,41.9642692]},"n1819790671":{"id":"n1819790671","loc":[-85.6141482,41.9696538]},"n1819790679":{"id":"n1819790679","loc":[-85.6148349,41.9705388]},"n1819790686":{"id":"n1819790686","loc":[-85.6139551,41.9695501]},"n1819790696":{"id":"n1819790696","loc":[-85.6119703,41.9699087]},"n1819790704":{"id":"n1819790704","loc":[-85.6140731,41.9684174]},"n1819790706":{"id":"n1819790706","loc":[-85.6124745,41.9699246]},"n1819790718":{"id":"n1819790718","loc":[-85.6165407,41.9636868]},"n1819790720":{"id":"n1819790720","loc":[-85.61388,41.9687365]},"n1819790731":{"id":"n1819790731","loc":[-85.6165193,41.9639421]},"n1819790739":{"id":"n1819790739","loc":[-85.6146739,41.9699964]},"n1819790753":{"id":"n1819790753","loc":[-85.6173883,41.9665747]},"n1819790760":{"id":"n1819790760","loc":[-85.6133221,41.9712089]},"n1819790767":{"id":"n1819790767","loc":[-85.6116698,41.9699246]},"n1819790779":{"id":"n1819790779","loc":[-85.6130753,41.9710573]},"n1819790791":{"id":"n1819790791","loc":[-85.6137083,41.9692869]},"n1819790795":{"id":"n1819790795","loc":[-85.6141482,41.9679627]},"n1819790798":{"id":"n1819790798","loc":[-85.6137727,41.9694305]},"n1819790836":{"id":"n1819790836","loc":[-85.6143842,41.9676037]},"n1819790915":{"id":"n1819790915","loc":[-85.6148456,41.9702756]},"n1819790926":{"id":"n1819790926","loc":[-85.6138371,41.9713525]},"n1819790927":{"id":"n1819790927","loc":[-85.6141053,41.9713525]},"n1819790931":{"id":"n1819790931","loc":[-85.6162832,41.966814]},"n1821014625":{"id":"n1821014625","loc":[-85.5960611,41.9808498]},"n1821014627":{"id":"n1821014627","loc":[-85.5565843,42.010982]},"n1821014629":{"id":"n1821014629","loc":[-85.5971541,41.9805808]},"n1821014632":{"id":"n1821014632","loc":[-85.6061837,41.9725907]},"n1821014633":{"id":"n1821014633","loc":[-85.5247773,42.025766]},"n1821014635":{"id":"n1821014635","loc":[-85.5908938,41.9902384]},"n1821014636":{"id":"n1821014636","loc":[-85.5917682,41.9860637]},"n1821014637":{"id":"n1821014637","loc":[-85.5456556,42.0166797]},"n1821014638":{"id":"n1821014638","loc":[-85.5795749,42.0032352]},"n1821014639":{"id":"n1821014639","loc":[-85.6103988,41.9723456]},"n1821014642":{"id":"n1821014642","loc":[-85.5818816,42.0022466]},"n1821014643":{"id":"n1821014643","loc":[-85.5570604,42.0091586]},"n1821014644":{"id":"n1821014644","loc":[-85.5952886,41.9803792]},"n1821014645":{"id":"n1821014645","loc":[-85.5780366,42.0040343]},"n1821014646":{"id":"n1821014646","loc":[-85.6050505,41.9751971]},"n1821014647":{"id":"n1821014647","loc":[-85.5854435,41.9946162]},"n1821014648":{"id":"n1821014648","loc":[-85.5452278,42.0168768]},"n1821014649":{"id":"n1821014649","loc":[-85.6023254,41.9780166]},"n1821014651":{"id":"n1821014651","loc":[-85.5761899,42.0046783]},"n1821014653":{"id":"n1821014653","loc":[-85.5897351,41.9876707]},"n1821014657":{"id":"n1821014657","loc":[-85.5963601,41.9808998]},"n1821014658":{"id":"n1821014658","loc":[-85.5892952,41.9951983]},"n1821014660":{"id":"n1821014660","loc":[-85.5778328,42.0037194]},"n1821014661":{"id":"n1821014661","loc":[-85.5541475,42.0125705]},"n1821014663":{"id":"n1821014663","loc":[-85.5914047,41.9856469]},"n1821014664":{"id":"n1821014664","loc":[-85.6101681,41.9727723]},"n1821014665":{"id":"n1821014665","loc":[-85.5910172,41.9854696]},"n1821014666":{"id":"n1821014666","loc":[-85.5398688,42.0187699]},"n1821014667":{"id":"n1821014667","loc":[-85.5218752,42.0282884]},"n1821014668":{"id":"n1821014668","loc":[-85.5159582,42.0329384]},"n1821014669":{"id":"n1821014669","loc":[-85.5898102,41.9847319]},"n1821014670":{"id":"n1821014670","loc":[-85.5734809,42.0066235]},"n1821014671":{"id":"n1821014671","loc":[-85.5922939,41.980852]},"n1821014672":{"id":"n1821014672","loc":[-85.6023629,41.9781163]},"n1821014674":{"id":"n1821014674","loc":[-85.5409953,42.0191724]},"n1821014676":{"id":"n1821014676","loc":[-85.584435,41.9949909]},"n1821014677":{"id":"n1821014677","loc":[-85.5972399,41.9783835]},"n1821014678":{"id":"n1821014678","loc":[-85.5616738,42.0071337]},"n1821014681":{"id":"n1821014681","loc":[-85.5202994,42.0310755]},"n1821014682":{"id":"n1821014682","loc":[-85.5915912,41.9857767]},"n1821014684":{"id":"n1821014684","loc":[-85.6022288,41.977897]},"n1821014687":{"id":"n1821014687","loc":[-85.5933024,41.9846362]},"n1821014688":{"id":"n1821014688","loc":[-85.5846871,41.9956169]},"n1821014689":{"id":"n1821014689","loc":[-85.5898209,41.99037]},"n1821014691":{"id":"n1821014691","loc":[-85.5448939,42.0149261]},"n1821014692":{"id":"n1821014692","loc":[-85.5977763,41.9786348]},"n1821014694":{"id":"n1821014694","loc":[-85.5767706,42.0034523]},"n1821014695":{"id":"n1821014695","loc":[-85.6103559,41.9726766]},"n1821014697":{"id":"n1821014697","loc":[-85.5922134,41.9809876]},"n1821014698":{"id":"n1821014698","loc":[-85.5935277,41.9831728]},"n1821014700":{"id":"n1821014700","loc":[-85.5674674,42.0078273]},"n1821014703":{"id":"n1821014703","loc":[-85.6021,41.9778053]},"n1821014704":{"id":"n1821014704","loc":[-85.5756763,42.0053737]},"n1821014705":{"id":"n1821014705","loc":[-85.5887695,41.9895207]},"n1821014707":{"id":"n1821014707","loc":[-85.6061073,41.9746866]},"n1821014708":{"id":"n1821014708","loc":[-85.6033446,41.9751692]},"n1821014710":{"id":"n1821014710","loc":[-85.5180986,42.0322332]},"n1821014711":{"id":"n1821014711","loc":[-85.543365,42.0163569]},"n1821014712":{"id":"n1821014712","loc":[-85.6030656,41.9753646]},"n1821014713":{"id":"n1821014713","loc":[-85.6104417,41.9704792]},"n1821014714":{"id":"n1821014714","loc":[-85.5205716,42.030998]},"n1821014716":{"id":"n1821014716","loc":[-85.516382,42.032536]},"n1821014717":{"id":"n1821014717","loc":[-85.5932863,41.9820882]},"n1821014718":{"id":"n1821014718","loc":[-85.5361928,42.0194974]},"n1821014720":{"id":"n1821014720","loc":[-85.6011613,41.9773586]},"n1821014721":{"id":"n1821014721","loc":[-85.554287,42.0109124]},"n1821014722":{"id":"n1821014722","loc":[-85.5577524,42.0103425]},"n1821014725":{"id":"n1821014725","loc":[-85.5867256,41.9921004]},"n1821014726":{"id":"n1821014726","loc":[-85.5856045,41.9968807]},"n1821014727":{"id":"n1821014727","loc":[-85.5545445,42.0106454]},"n1821014728":{"id":"n1821014728","loc":[-85.5923797,41.9842534]},"n1821014729":{"id":"n1821014729","loc":[-85.5696346,42.0081462]},"n1821014730":{"id":"n1821014730","loc":[-85.5998322,41.9786884]},"n1821014735":{"id":"n1821014735","loc":[-85.5337426,42.0218266]},"n1821014736":{"id":"n1821014736","loc":[-85.5847944,41.994672]},"n1821014740":{"id":"n1821014740","loc":[-85.5315271,42.0238669]},"n1821014741":{"id":"n1821014741","loc":[-85.5248846,42.027085]},"n1821014742":{"id":"n1821014742","loc":[-85.5853376,41.997018]},"n1821014743":{"id":"n1821014743","loc":[-85.5894883,41.988811]},"n1821014745":{"id":"n1821014745","loc":[-85.6095311,41.9726226]},"n1821014746":{"id":"n1821014746","loc":[-85.5531511,42.0133416]},"n1821014747":{"id":"n1821014747","loc":[-85.5735882,42.007058]},"n1821014749":{"id":"n1821014749","loc":[-85.5428554,42.0164366]},"n1821014751":{"id":"n1821014751","loc":[-85.5395255,42.0186304]},"n1821014752":{"id":"n1821014752","loc":[-85.571378,42.0083176]},"n1821014754":{"id":"n1821014754","loc":[-85.5541918,42.0113925]},"n1821014755":{"id":"n1821014755","loc":[-85.5278029,42.0250806]},"n1821014756":{"id":"n1821014756","loc":[-85.5936725,41.9827102]},"n1821014757":{"id":"n1821014757","loc":[-85.5176266,42.0346677]},"n1821014758":{"id":"n1821014758","loc":[-85.6096692,41.9714245]},"n1821014759":{"id":"n1821014759","loc":[-85.5770321,42.0034266]},"n1821014761":{"id":"n1821014761","loc":[-85.5988921,41.9779369]},"n1821014762":{"id":"n1821014762","loc":[-85.5811788,42.0024499]},"n1821014763":{"id":"n1821014763","loc":[-85.5154003,42.0381101]},"n1821014764":{"id":"n1821014764","loc":[-85.5155827,42.0374089]},"n1821014765":{"id":"n1821014765","loc":[-85.5891249,41.9884978]},"n1821014766":{"id":"n1821014766","loc":[-85.5313863,42.0238293]},"n1821014768":{"id":"n1821014768","loc":[-85.593297,41.9833363]},"n1821014769":{"id":"n1821014769","loc":[-85.5849446,41.9957245]},"n1821014770":{"id":"n1821014770","loc":[-85.5537774,42.0130847]},"n1821014771":{"id":"n1821014771","loc":[-85.6111766,41.9706069]},"n1821014772":{"id":"n1821014772","loc":[-85.5585477,42.008989]},"n1821014774":{"id":"n1821014774","loc":[-85.5928142,41.9852623]},"n1821014777":{"id":"n1821014777","loc":[-85.5891933,41.9882608]},"n1821014778":{"id":"n1821014778","loc":[-85.5926909,41.9817532]},"n1821014779":{"id":"n1821014779","loc":[-85.5260272,42.0252201]},"n1821014781":{"id":"n1821014781","loc":[-85.5894615,41.9950468]},"n1821014782":{"id":"n1821014782","loc":[-85.5461063,42.0143242]},"n1821014783":{"id":"n1821014783","loc":[-85.5711527,42.0085886]},"n1821014784":{"id":"n1821014784","loc":[-85.5329379,42.0218624]},"n1821014786":{"id":"n1821014786","loc":[-85.583047,42.0020252]},"n1821014787":{"id":"n1821014787","loc":[-85.5758962,42.0054095]},"n1821014788":{"id":"n1821014788","loc":[-85.5626354,42.0077733]},"n1821014789":{"id":"n1821014789","loc":[-85.6029852,41.9755999]},"n1821014790":{"id":"n1821014790","loc":[-85.5892362,41.9886755]},"n1821014791":{"id":"n1821014791","loc":[-85.5157597,42.0372017]},"n1821014793":{"id":"n1821014793","loc":[-85.6054582,41.9751094]},"n1821014794":{"id":"n1821014794","loc":[-85.5986936,41.9778412]},"n1821014795":{"id":"n1821014795","loc":[-85.5880775,41.98976]},"n1821014796":{"id":"n1821014796","loc":[-85.5858727,41.9963624]},"n1821014798":{"id":"n1821014798","loc":[-85.5792543,42.0035958]},"n1821014799":{"id":"n1821014799","loc":[-85.5921665,41.9838326]},"n1821014801":{"id":"n1821014801","loc":[-85.599214,41.9782599]},"n1821014802":{"id":"n1821014802","loc":[-85.5571905,42.0090967]},"n1821014803":{"id":"n1821014803","loc":[-85.5426891,42.0173612]},"n1821014804":{"id":"n1821014804","loc":[-85.5889626,41.9896404]},"n1821014805":{"id":"n1821014805","loc":[-85.5491264,42.0141648]},"n1821014806":{"id":"n1821014806","loc":[-85.5618897,42.0072631]},"n1821014808":{"id":"n1821014808","loc":[-85.5573501,42.0109802]},"n1821014809":{"id":"n1821014809","loc":[-85.5983463,41.9778031]},"n1821014810":{"id":"n1821014810","loc":[-85.5885173,41.9895128]},"n1821014811":{"id":"n1821014811","loc":[-85.6084998,41.9721143]},"n1821014812":{"id":"n1821014812","loc":[-85.5737598,42.0056389]},"n1821014814":{"id":"n1821014814","loc":[-85.5542173,42.0118132]},"n1821014816":{"id":"n1821014816","loc":[-85.5277868,42.024451]},"n1821014817":{"id":"n1821014817","loc":[-85.5403999,42.0191724]},"n1821014819":{"id":"n1821014819","loc":[-85.5983879,41.9791452]},"n1821014820":{"id":"n1821014820","loc":[-85.5891302,41.9897578]},"n1821014822":{"id":"n1821014822","loc":[-85.5930731,41.9805108]},"n1821014824":{"id":"n1821014824","loc":[-85.515395,42.0378471]},"n1821014825":{"id":"n1821014825","loc":[-85.5352755,42.0205136]},"n1821014826":{"id":"n1821014826","loc":[-85.5502744,42.0133398]},"n1821014828":{"id":"n1821014828","loc":[-85.5701295,42.0088256]},"n1821014830":{"id":"n1821014830","loc":[-85.5888929,41.9953099]},"n1821014832":{"id":"n1821014832","loc":[-85.5880077,41.9901547]},"n1821014833":{"id":"n1821014833","loc":[-85.5451192,42.0157072]},"n1821014834":{"id":"n1821014834","loc":[-85.6096478,41.9711932]},"n1821014835":{"id":"n1821014835","loc":[-85.5806424,42.0026532]},"n1821014836":{"id":"n1821014836","loc":[-85.5911674,41.9868732]},"n1821014838":{"id":"n1821014838","loc":[-85.5930302,41.9836571]},"n1821014839":{"id":"n1821014839","loc":[-85.588925,41.9938148]},"n1821014840":{"id":"n1821014840","loc":[-85.6111874,41.9705311]},"n1821014841":{"id":"n1821014841","loc":[-85.5680843,42.0075842]},"n1821014842":{"id":"n1821014842","loc":[-85.6012793,41.9775062]},"n1821014843":{"id":"n1821014843","loc":[-85.5855562,41.9989777]},"n1821014844":{"id":"n1821014844","loc":[-85.5506137,42.0131662]},"n1821014845":{"id":"n1821014845","loc":[-85.5270049,42.025457]},"n1821014846":{"id":"n1821014846","loc":[-85.5257054,42.025244]},"n1821014847":{"id":"n1821014847","loc":[-85.6011184,41.9771832]},"n1821014848":{"id":"n1821014848","loc":[-85.515534,42.0389234]},"n1821014850":{"id":"n1821014850","loc":[-85.5847032,42.0010347]},"n1821014853":{"id":"n1821014853","loc":[-85.5361499,42.019063]},"n1821014854":{"id":"n1821014854","loc":[-85.5439176,42.0165721]},"n1821014855":{"id":"n1821014855","loc":[-85.5838825,42.0017284]},"n1821014857":{"id":"n1821014857","loc":[-85.5542173,42.0122317]},"n1821014859":{"id":"n1821014859","loc":[-85.5708201,42.0089195]},"n1821014860":{"id":"n1821014860","loc":[-85.5844833,41.9954415]},"n1821014862":{"id":"n1821014862","loc":[-85.5223204,42.0295396]},"n1821014863":{"id":"n1821014863","loc":[-85.5777898,42.0035918]},"n1821014864":{"id":"n1821014864","loc":[-85.591044,41.9898078]},"n1821014865":{"id":"n1821014865","loc":[-85.5973204,41.980182]},"n1821014866":{"id":"n1821014866","loc":[-85.5699578,42.0085825]},"n1821014867":{"id":"n1821014867","loc":[-85.5210598,42.0305278]},"n1821014868":{"id":"n1821014868","loc":[-85.5929108,41.9819008]},"n1821014869":{"id":"n1821014869","loc":[-85.5279799,42.0242995]},"n1821014870":{"id":"n1821014870","loc":[-85.5196114,42.0320539]},"n1821014871":{"id":"n1821014871","loc":[-85.5785449,42.0040883]},"n1821014872":{"id":"n1821014872","loc":[-85.588292,41.9895766]},"n1821014873":{"id":"n1821014873","loc":[-85.5160172,42.0331775]},"n1821014874":{"id":"n1821014874","loc":[-85.5688849,42.0077016]},"n1821014876":{"id":"n1821014876","loc":[-85.5857976,41.9996036]},"n1821014879":{"id":"n1821014879","loc":[-85.5990906,41.9780765]},"n1821014881":{"id":"n1821014881","loc":[-85.5483647,42.0144279]},"n1821014883":{"id":"n1821014883","loc":[-85.5691209,42.0077972]},"n1821014885":{"id":"n1821014885","loc":[-85.6076844,41.9721103]},"n1821014886":{"id":"n1821014886","loc":[-85.6015489,41.9766147]},"n1821014887":{"id":"n1821014887","loc":[-85.574822,42.0052802]},"n1821014888":{"id":"n1821014888","loc":[-85.5880024,41.9899593]},"n1821014890":{"id":"n1821014890","loc":[-85.5909421,41.9893772]},"n1821014892":{"id":"n1821014892","loc":[-85.5497326,42.0138141]},"n1821014893":{"id":"n1821014893","loc":[-85.5167106,42.0357811]},"n1821014895":{"id":"n1821014895","loc":[-85.5844404,41.9952501]},"n1821014896":{"id":"n1821014896","loc":[-85.5362465,42.0192662]},"n1821014898":{"id":"n1821014898","loc":[-85.5906095,41.9889147]},"n1821014899":{"id":"n1821014899","loc":[-85.5590667,42.0089354]},"n1821014900":{"id":"n1821014900","loc":[-85.5921598,41.9844209]},"n1821014902":{"id":"n1821014902","loc":[-85.5778971,42.0039266]},"n1821014903":{"id":"n1821014903","loc":[-85.603012,41.9761981]},"n1821014904":{"id":"n1821014904","loc":[-85.6108977,41.9706787]},"n1821014905":{"id":"n1821014905","loc":[-85.5685738,42.0076139]},"n1821014906":{"id":"n1821014906","loc":[-85.5392787,42.0186304]},"n1821014907":{"id":"n1821014907","loc":[-85.5227885,42.0274972]},"n1821014908":{"id":"n1821014908","loc":[-85.5857547,41.9961431]},"n1821014910":{"id":"n1821014910","loc":[-85.5610354,42.0072812]},"n1821014911":{"id":"n1821014911","loc":[-85.5209632,42.0308705]},"n1821014912":{"id":"n1821014912","loc":[-85.5709757,42.0087959]},"n1821014913":{"id":"n1821014913","loc":[-85.59231,41.9839344]},"n1821014914":{"id":"n1821014914","loc":[-85.5375245,42.0185865]},"n1821014916":{"id":"n1821014916","loc":[-85.5901548,41.9839841]},"n1821014917":{"id":"n1821014917","loc":[-85.5611213,42.0086405]},"n1821014918":{"id":"n1821014918","loc":[-85.5360426,42.0198122]},"n1821014919":{"id":"n1821014919","loc":[-85.5862817,41.9948691]},"n1821014921":{"id":"n1821014921","loc":[-85.5469807,42.0144438]},"n1821014922":{"id":"n1821014922","loc":[-85.5761309,42.0053838]},"n1821014924":{"id":"n1821014924","loc":[-85.516264,42.0332971]},"n1821014925":{"id":"n1821014925","loc":[-85.5277224,42.0246661]},"n1821014926":{"id":"n1821014926","loc":[-85.5980016,41.9798231]},"n1821014928":{"id":"n1821014928","loc":[-85.5924548,41.9806965]},"n1821014930":{"id":"n1821014930","loc":[-85.5899121,41.985023]},"n1821014931":{"id":"n1821014931","loc":[-85.5706015,42.0089492]},"n1821014932":{"id":"n1821014932","loc":[-85.515926,42.033046]},"n1821014933":{"id":"n1821014933","loc":[-85.5982377,41.9796796]},"n1821014936":{"id":"n1821014936","loc":[-85.5475721,42.0145253]},"n1821014938":{"id":"n1821014938","loc":[-85.5895701,41.9902323]},"n1821014939":{"id":"n1821014939","loc":[-85.6030495,41.9759947]},"n1821014942":{"id":"n1821014942","loc":[-85.6094721,41.9724989]},"n1821014944":{"id":"n1821014944","loc":[-85.5921973,41.9811112]},"n1821014945":{"id":"n1821014945","loc":[-85.5223526,42.0291332]},"n1821014946":{"id":"n1821014946","loc":[-85.5965103,41.9808998]},"n1821014948":{"id":"n1821014948","loc":[-85.517766,42.0349227]},"n1821014950":{"id":"n1821014950","loc":[-85.5889894,41.990996]},"n1821014951":{"id":"n1821014951","loc":[-85.5601932,42.0092902]},"n1821014954":{"id":"n1821014954","loc":[-85.6028135,41.9764055]},"n1821014955":{"id":"n1821014955","loc":[-85.5520621,42.0130666]},"n1821014956":{"id":"n1821014956","loc":[-85.593002,41.9839344]},"n1821014957":{"id":"n1821014957","loc":[-85.515926,42.0369666]},"n1821014960":{"id":"n1821014960","loc":[-85.5761255,42.003877]},"n1821014961":{"id":"n1821014961","loc":[-85.5716355,42.007911]},"n1821014962":{"id":"n1821014962","loc":[-85.5575378,42.0109045]},"n1821014963":{"id":"n1821014963","loc":[-85.5735667,42.0068188]},"n1821014964":{"id":"n1821014964","loc":[-85.5915214,41.9865861]},"n1821014965":{"id":"n1821014965","loc":[-85.5866344,41.9923157]},"n1821014967":{"id":"n1821014967","loc":[-85.5283138,42.0242256]},"n1821014968":{"id":"n1821014968","loc":[-85.5177875,42.0355801]},"n1821014969":{"id":"n1821014969","loc":[-85.548071,42.0144934]},"n1821014972":{"id":"n1821014972","loc":[-85.5611159,42.0088557]},"n1821014973":{"id":"n1821014973","loc":[-85.541686,42.0188757]},"n1821014974":{"id":"n1821014974","loc":[-85.5917628,41.9862631]},"n1821014975":{"id":"n1821014975","loc":[-85.5854864,41.9959478]},"n1821014977":{"id":"n1821014977","loc":[-85.609102,41.9722317]},"n1821014980":{"id":"n1821014980","loc":[-85.5761202,42.0042438]},"n1821014982":{"id":"n1821014982","loc":[-85.5465944,42.0143601]},"n1821014983":{"id":"n1821014983","loc":[-85.5173261,42.0342732]},"n1821014984":{"id":"n1821014984","loc":[-85.5897297,41.9888509]},"n1821014985":{"id":"n1821014985","loc":[-85.5856688,41.999181]},"n1821014986":{"id":"n1821014986","loc":[-85.5344011,42.0217251]},"n1821014987":{"id":"n1821014987","loc":[-85.601467,41.9768203]},"n1821014988":{"id":"n1821014988","loc":[-85.5457254,42.0165123]},"n1821014989":{"id":"n1821014989","loc":[-85.6023482,41.9784332]},"n1821014991":{"id":"n1821014991","loc":[-85.5361606,42.01823]},"n1821014992":{"id":"n1821014992","loc":[-85.5178465,42.0351139]},"n1821014995":{"id":"n1821014995","loc":[-85.5634293,42.0078092]},"n1821014996":{"id":"n1821014996","loc":[-85.573497,42.0072015]},"n1821014997":{"id":"n1821014997","loc":[-85.5976328,41.9799725]},"n1821014998":{"id":"n1821014998","loc":[-85.5210651,42.0303166]},"n1821015003":{"id":"n1821015003","loc":[-85.5222131,42.0288064]},"n1821015004":{"id":"n1821015004","loc":[-85.5897941,41.984405]},"n1821015005":{"id":"n1821015005","loc":[-85.5975725,41.9776099]},"n1821015006":{"id":"n1821015006","loc":[-85.5765708,42.0034903]},"n1821015007":{"id":"n1821015007","loc":[-85.5250187,42.026559]},"n1821015009":{"id":"n1821015009","loc":[-85.5426998,42.0166279]},"n1821015010":{"id":"n1821015010","loc":[-85.5957606,41.9806584]},"n1821015011":{"id":"n1821015011","loc":[-85.5262753,42.0252497]},"n1821015012":{"id":"n1821015012","loc":[-85.5266455,42.0253374]},"n1821015014":{"id":"n1821015014","loc":[-85.5515632,42.0130187]},"n1821015015":{"id":"n1821015015","loc":[-85.6024058,41.9765212]},"n1821015017":{"id":"n1821015017","loc":[-85.5175032,42.0357156]},"n1821015018":{"id":"n1821015018","loc":[-85.5302718,42.0236039]},"n1821015019":{"id":"n1821015019","loc":[-85.6024005,41.9782759]},"n1821015020":{"id":"n1821015020","loc":[-85.5907758,41.9890821]},"n1821015021":{"id":"n1821015021","loc":[-85.6019445,41.9777215]},"n1821015022":{"id":"n1821015022","loc":[-85.5942854,41.9800881]},"n1821015024":{"id":"n1821015024","loc":[-85.5325826,42.0222711]},"n1821015029":{"id":"n1821015029","loc":[-85.555093,42.0105316]},"n1821015033":{"id":"n1821015033","loc":[-85.5249704,42.0270372]},"n1821015034":{"id":"n1821015034","loc":[-85.5243965,42.0272205]},"n1821015038":{"id":"n1821015038","loc":[-85.5413426,42.0190749]},"n1821015039":{"id":"n1821015039","loc":[-85.5920431,41.9848175]},"n1821015041":{"id":"n1821015041","loc":[-85.5577685,42.0106015]},"n1821015042":{"id":"n1821015042","loc":[-85.5453606,42.0158866]},"n1821015045":{"id":"n1821015045","loc":[-85.5333228,42.0217889]},"n1821015046":{"id":"n1821015046","loc":[-85.5426891,42.0175924]},"n1821015048":{"id":"n1821015048","loc":[-85.5886836,41.9936474]},"n1821015050":{"id":"n1821015050","loc":[-85.6001152,41.9786467]},"n1821015051":{"id":"n1821015051","loc":[-85.6094064,41.9723655]},"n1821015053":{"id":"n1821015053","loc":[-85.605721,41.9749738]},"n1821015055":{"id":"n1821015055","loc":[-85.6106791,41.9705048]},"n1821015057":{"id":"n1821015057","loc":[-85.5210437,42.0307071]},"n1821015059":{"id":"n1821015059","loc":[-85.5995694,41.9786725]},"n1821015060":{"id":"n1821015060","loc":[-85.5371638,42.0182938]},"n1821015062":{"id":"n1821015062","loc":[-85.6111766,41.9704593]},"n1821015065":{"id":"n1821015065","loc":[-85.577704,42.0034921]},"n1821015067":{"id":"n1821015067","loc":[-85.5570067,42.0093699]},"n1821015068":{"id":"n1821015068","loc":[-85.5920364,41.9845525]},"n1821015069":{"id":"n1821015069","loc":[-85.5252065,42.0253954]},"n1821015072":{"id":"n1821015072","loc":[-85.5664159,42.0088517]},"n1821015073":{"id":"n1821015073","loc":[-85.5880399,41.991905]},"n1821015075":{"id":"n1821015075","loc":[-85.6099871,41.9727861]},"n1821015076":{"id":"n1821015076","loc":[-85.5319603,42.0231478]},"n1821015078":{"id":"n1821015078","loc":[-85.6036088,41.9751112]},"n1821015080":{"id":"n1821015080","loc":[-85.5983128,41.9789179]},"n1821015082":{"id":"n1821015082","loc":[-85.5614069,42.0071395]},"n1821015083":{"id":"n1821015083","loc":[-85.60968,41.9709738]},"n1821015086":{"id":"n1821015086","loc":[-85.5914195,41.9837351]},"n1821015087":{"id":"n1821015087","loc":[-85.5895473,41.9948036]},"n1821015090":{"id":"n1821015090","loc":[-85.5929913,41.9851905]},"n1821015093":{"id":"n1821015093","loc":[-85.5907396,41.9838485]},"n1821015095":{"id":"n1821015095","loc":[-85.5893864,41.9880176]},"n1821015096":{"id":"n1821015096","loc":[-85.5788024,42.0039807]},"n1821015097":{"id":"n1821015097","loc":[-85.5630592,42.0078411]},"n1821015098":{"id":"n1821015098","loc":[-85.5350609,42.0211274]},"n1821015099":{"id":"n1821015099","loc":[-85.5967195,41.9808679]},"n1821015100":{"id":"n1821015100","loc":[-85.5666734,42.0088119]},"n1821015101":{"id":"n1821015101","loc":[-85.564694,42.0077675]},"n1821015103":{"id":"n1821015103","loc":[-85.6066544,41.9726527]},"n1821015104":{"id":"n1821015104","loc":[-85.6011827,41.9769838]},"n1821015105":{"id":"n1821015105","loc":[-85.5972131,41.9776697]},"n1821015106":{"id":"n1821015106","loc":[-85.5880828,41.9903341]},"n1821015107":{"id":"n1821015107","loc":[-85.5510268,42.0130626]},"n1821015108":{"id":"n1821015108","loc":[-85.6102164,41.970543]},"n1821015109":{"id":"n1821015109","loc":[-85.5905344,41.9853899]},"n1821015111":{"id":"n1821015111","loc":[-85.5888821,41.9913429]},"n1821015112":{"id":"n1821015112","loc":[-85.606295,41.9741921]},"n1821015114":{"id":"n1821015114","loc":[-85.5969556,41.9807443]},"n1821015115":{"id":"n1821015115","loc":[-85.5882223,41.9934081]},"n1821015116":{"id":"n1821015116","loc":[-85.6104471,41.9724971]},"n1821015118":{"id":"n1821015118","loc":[-85.5406091,42.0192162]},"n1821015120":{"id":"n1821015120","loc":[-85.589955,41.9888429]},"n1821015121":{"id":"n1821015121","loc":[-85.5598821,42.0092304]},"n1821015122":{"id":"n1821015122","loc":[-85.545598,42.0144097]},"n1821015123":{"id":"n1821015123","loc":[-85.5649528,42.0079965]},"n1821015125":{"id":"n1821015125","loc":[-85.5883993,41.9917814]},"n1821015126":{"id":"n1821015126","loc":[-85.5295785,42.0239967]},"n1821015129":{"id":"n1821015129","loc":[-85.5648723,42.0078809]},"n1821015132":{"id":"n1821015132","loc":[-85.564989,42.0081103]},"n1821015133":{"id":"n1821015133","loc":[-85.5946127,41.9800841]},"n1821015134":{"id":"n1821015134","loc":[-85.583448,42.0019078]},"n1821015135":{"id":"n1821015135","loc":[-85.5905934,41.9871842]},"n1821015137":{"id":"n1821015137","loc":[-85.610608,41.9704752]},"n1821015138":{"id":"n1821015138","loc":[-85.5752257,42.0052939]},"n1821015139":{"id":"n1821015139","loc":[-85.5893864,41.9943491]},"n1821015140":{"id":"n1821015140","loc":[-85.5426247,42.0169866]},"n1821015141":{"id":"n1821015141","loc":[-85.562001,42.0074526]},"n1821015142":{"id":"n1821015142","loc":[-85.5212046,42.0301094]},"n1821015143":{"id":"n1821015143","loc":[-85.602214,41.9784531]},"n1821015144":{"id":"n1821015144","loc":[-85.5858687,41.9948293]},"n1821015145":{"id":"n1821015145","loc":[-85.5608477,42.0074805]},"n1821015146":{"id":"n1821015146","loc":[-85.5651607,42.0083614]},"n1821015147":{"id":"n1821015147","loc":[-85.5288288,42.0242495]},"n1821015149":{"id":"n1821015149","loc":[-85.5450334,42.0146989]},"n1821015151":{"id":"n1821015151","loc":[-85.5578275,42.0092304]},"n1821015154":{"id":"n1821015154","loc":[-85.6056634,41.9724511]},"n1821015155":{"id":"n1821015155","loc":[-85.5902179,41.9852742]},"n1821015156":{"id":"n1821015156","loc":[-85.5156256,42.0387157]},"n1821015157":{"id":"n1821015157","loc":[-85.5734433,42.0059459]},"n1821015158":{"id":"n1821015158","loc":[-85.6050773,41.9731273]},"n1821015160":{"id":"n1821015160","loc":[-85.5223419,42.0275233]},"n1821015163":{"id":"n1821015163","loc":[-85.6053562,41.972525]},"n1821015164":{"id":"n1821015164","loc":[-85.5850412,41.9946082]},"n1821015165":{"id":"n1821015165","loc":[-85.5359031,42.0186326]},"n1821015166":{"id":"n1821015166","loc":[-85.5608745,42.0077635]},"n1821015169":{"id":"n1821015169","loc":[-85.572876,42.0073189]},"n1821015171":{"id":"n1821015171","loc":[-85.5875424,41.9919188]},"n1821015172":{"id":"n1821015172","loc":[-85.5240116,42.0272581]},"n1821015173":{"id":"n1821015173","loc":[-85.5318369,42.0236818]},"n1821015174":{"id":"n1821015174","loc":[-85.566888,42.0086923]},"n1821015175":{"id":"n1821015175","loc":[-85.5931522,41.9850669]},"n1821015176":{"id":"n1821015176","loc":[-85.5604842,42.0093199]},"n1821015177":{"id":"n1821015177","loc":[-85.5868168,41.9927543]},"n1821015178":{"id":"n1821015178","loc":[-85.6052275,41.9732549]},"n1821015179":{"id":"n1821015179","loc":[-85.5910118,41.9900431]},"n1821015182":{"id":"n1821015182","loc":[-85.5610032,42.0082897]},"n1821015183":{"id":"n1821015183","loc":[-85.5425443,42.0179431]},"n1821015184":{"id":"n1821015184","loc":[-85.5843277,42.0014055]},"n1821015186":{"id":"n1821015186","loc":[-85.5733307,42.0063564]},"n1821015188":{"id":"n1821015188","loc":[-85.5277385,42.0248694]},"n1821015189":{"id":"n1821015189","loc":[-85.5558427,42.0108168]},"n1821015190":{"id":"n1821015190","loc":[-85.5650587,42.0082618]},"n1821015191":{"id":"n1821015191","loc":[-85.5660351,42.0088278]},"n1821015192":{"id":"n1821015192","loc":[-85.5849768,41.9980049]},"n1821015194":{"id":"n1821015194","loc":[-85.5359139,42.0188199]},"n1821015195":{"id":"n1821015195","loc":[-85.593238,41.9849194]},"n1821015197":{"id":"n1821015197","loc":[-85.5850841,41.9983239]},"n1821015199":{"id":"n1821015199","loc":[-85.5983396,41.9794283]},"n1821015204":{"id":"n1821015204","loc":[-85.5452801,42.0145355]},"n1821015205":{"id":"n1821015205","loc":[-85.5340685,42.0218407]},"n1821015207":{"id":"n1821015207","loc":[-85.5773272,42.0034186]},"n1821015209":{"id":"n1821015209","loc":[-85.5535212,42.0132419]},"n1821015211":{"id":"n1821015211","loc":[-85.6107703,41.9706045]},"n1821015212":{"id":"n1821015212","loc":[-85.6030066,41.9758193]},"n1821015213":{"id":"n1821015213","loc":[-85.5359943,42.0184213]},"n1821015214":{"id":"n1821015214","loc":[-85.5922993,41.9813305]},"n1821015215":{"id":"n1821015215","loc":[-85.5672689,42.0080465]},"n1821015217":{"id":"n1821015217","loc":[-85.5160494,42.0365682]},"n1821015218":{"id":"n1821015218","loc":[-85.5401142,42.0190351]},"n1821015219":{"id":"n1821015219","loc":[-85.5607632,42.0092282]},"n1821015220":{"id":"n1821015220","loc":[-85.5866197,41.9947894]},"n1821015221":{"id":"n1821015221","loc":[-85.6017889,41.9765132]},"n1821015222":{"id":"n1821015222","loc":[-85.5595978,42.009059]},"n1821015226":{"id":"n1821015226","loc":[-85.5871494,41.9929018]},"n1821015227":{"id":"n1821015227","loc":[-85.5857708,41.9998866]},"n1821015228":{"id":"n1821015228","loc":[-85.5317135,42.0238094]},"n1821015231":{"id":"n1821015231","loc":[-85.5733521,42.0061372]},"n1821015233":{"id":"n1821015233","loc":[-85.5855991,42.0001936]},"n1821015234":{"id":"n1821015234","loc":[-85.5213924,42.029962]},"n1821015235":{"id":"n1821015235","loc":[-85.6052221,41.9726567]},"n1821015236":{"id":"n1821015236","loc":[-85.5763723,42.0035422]},"n1821015237":{"id":"n1821015237","loc":[-85.5858512,41.9966215]},"n1821015238":{"id":"n1821015238","loc":[-85.567061,42.008439]},"n1821015239":{"id":"n1821015239","loc":[-85.5250563,42.0269057]},"n1821015240":{"id":"n1821015240","loc":[-85.5347551,42.0214263]},"n1821015241":{"id":"n1821015241","loc":[-85.6098463,41.9707066]},"n1821015242":{"id":"n1821015242","loc":[-85.5676927,42.0076519]},"n1821015243":{"id":"n1821015243","loc":[-85.516775,42.0322669]},"n1821015244":{"id":"n1821015244","loc":[-85.5762275,42.0036538]},"n1821015245":{"id":"n1821015245","loc":[-85.5583639,42.0090949]},"n1821015246":{"id":"n1821015246","loc":[-85.5554041,42.0106432]},"n1821015247":{"id":"n1821015247","loc":[-85.5973364,41.9776099]},"n1821015248":{"id":"n1821015248","loc":[-85.6098945,41.9717513]},"n1821015249":{"id":"n1821015249","loc":[-85.6045315,41.9751511]},"n1821015250":{"id":"n1821015250","loc":[-85.5579938,42.0092264]},"n1821015253":{"id":"n1821015253","loc":[-85.6058873,41.9724652]},"n1821015254":{"id":"n1821015254","loc":[-85.5869456,41.9947517]},"n1821015255":{"id":"n1821015255","loc":[-85.5936565,41.9823713]},"n1821015256":{"id":"n1821015256","loc":[-85.5218269,42.0278102]},"n1821015258":{"id":"n1821015258","loc":[-85.5887802,41.9905534]},"n1821015259":{"id":"n1821015259","loc":[-85.5901924,41.9904515]},"n1821015263":{"id":"n1821015263","loc":[-85.5249222,42.0255787]},"n1821015265":{"id":"n1821015265","loc":[-85.5175206,42.0321672]},"n1821015266":{"id":"n1821015266","loc":[-85.5275722,42.0254034]},"n1821015267":{"id":"n1821015267","loc":[-85.6016226,41.9765451]},"n1821015269":{"id":"n1821015269","loc":[-85.5569316,42.011032]},"n1821015271":{"id":"n1821015271","loc":[-85.6010714,41.9785209]},"n1821015272":{"id":"n1821015272","loc":[-85.6050666,41.9729917]},"n1821015273":{"id":"n1821015273","loc":[-85.5891235,41.99529]},"n1821015274":{"id":"n1821015274","loc":[-85.515454,42.0376439]},"n1821015276":{"id":"n1821015276","loc":[-85.5776021,42.0034443]},"n1821015277":{"id":"n1821015277","loc":[-85.6041707,41.9751453]},"n1821015278":{"id":"n1821015278","loc":[-85.5444701,42.0167435]},"n1821015280":{"id":"n1821015280","loc":[-85.5923274,41.9852202]},"n1821015283":{"id":"n1821015283","loc":[-85.5893649,41.9900271]},"n1821015284":{"id":"n1821015284","loc":[-85.5933453,41.9804412]},"n1821015285":{"id":"n1821015285","loc":[-85.5247237,42.026017]},"n1821015286":{"id":"n1821015286","loc":[-85.5286182,42.0242477]},"n1821015287":{"id":"n1821015287","loc":[-85.5904003,41.9888549]},"n1821015288":{"id":"n1821015288","loc":[-85.6062146,41.9739369]},"n1821015290":{"id":"n1821015290","loc":[-85.5762596,42.0052602]},"n1821015292":{"id":"n1821015292","loc":[-85.5849715,41.9975465]},"n1821015293":{"id":"n1821015293","loc":[-85.585229,42.0006241]},"n1821015294":{"id":"n1821015294","loc":[-85.5926922,41.9805946]},"n1821015295":{"id":"n1821015295","loc":[-85.5703387,42.0089133]},"n1821015299":{"id":"n1821015299","loc":[-85.5789955,42.0038611]},"n1821015301":{"id":"n1821015301","loc":[-85.6072888,41.9721918]},"n1821015302":{"id":"n1821015302","loc":[-85.5356349,42.0200992]},"n1821015304":{"id":"n1821015304","loc":[-85.5891772,41.994066]},"n1821015306":{"id":"n1821015306","loc":[-85.606295,41.9744952]},"n1821015307":{"id":"n1821015307","loc":[-85.538871,42.0186583]},"n1821015308":{"id":"n1821015308","loc":[-85.587997,41.994971]},"n1821015311":{"id":"n1821015311","loc":[-85.606869,41.9725809]},"n1821015312":{"id":"n1821015312","loc":[-85.5171974,42.0339943]},"n1821015314":{"id":"n1821015314","loc":[-85.5327435,42.0220479]},"n1821015315":{"id":"n1821015315","loc":[-85.5383439,42.0187282]},"n1821015316":{"id":"n1821015316","loc":[-85.5248095,42.0263119]},"n1821015318":{"id":"n1821015318","loc":[-85.5732502,42.0073051]},"n1821015319":{"id":"n1821015319","loc":[-85.5924226,41.9852663]},"n1821015321":{"id":"n1821015321","loc":[-85.5179001,42.0353052]},"n1821015322":{"id":"n1821015322","loc":[-85.5456771,42.0162413]},"n1821015323":{"id":"n1821015323","loc":[-85.5936618,41.9829096]},"n1821015325":{"id":"n1821015325","loc":[-85.5656931,42.0086582]},"n1821015326":{"id":"n1821015326","loc":[-85.5448456,42.0150975]},"n1821015327":{"id":"n1821015327","loc":[-85.5220039,42.027615]},"n1821015329":{"id":"n1821015329","loc":[-85.517884,42.0354885]},"n1821015330":{"id":"n1821015330","loc":[-85.5576666,42.0101671]},"n1821015332":{"id":"n1821015332","loc":[-85.5368754,42.0181402]},"n1821015333":{"id":"n1821015333","loc":[-85.5367078,42.0181145]},"n1821015334":{"id":"n1821015334","loc":[-85.5903909,41.9904316]},"n1821015335":{"id":"n1821015335","loc":[-85.5430767,42.0163587]},"n1821015336":{"id":"n1821015336","loc":[-85.5277492,42.0252878]},"n1821015337":{"id":"n1821015337","loc":[-85.5312146,42.0236898]},"n1821015338":{"id":"n1821015338","loc":[-85.5886568,41.991614]},"n1821015339":{"id":"n1821015339","loc":[-85.5782498,42.0040883]},"n1821015341":{"id":"n1821015341","loc":[-85.562233,42.0076457]},"n1821015342":{"id":"n1821015342","loc":[-85.588626,41.9952479]},"n1821015343":{"id":"n1821015343","loc":[-85.5762865,42.005033]},"n1821015344":{"id":"n1821015344","loc":[-85.5850841,41.9971478]},"n1821015346":{"id":"n1821015346","loc":[-85.5643144,42.0076936]},"n1821015347":{"id":"n1821015347","loc":[-85.5164893,42.0359467]},"n1821015348":{"id":"n1821015348","loc":[-85.5906846,41.9903541]},"n1821015349":{"id":"n1821015349","loc":[-85.557688,42.0107769]},"n1821015350":{"id":"n1821015350","loc":[-85.5363698,42.0181424]},"n1821015351":{"id":"n1821015351","loc":[-85.5939636,41.9801918]},"n1821015352":{"id":"n1821015352","loc":[-85.5524041,42.0131644]},"n1821015354":{"id":"n1821015354","loc":[-85.5308606,42.0236221]},"n1821015355":{"id":"n1821015355","loc":[-85.5877449,41.9932367]},"n1821015356":{"id":"n1821015356","loc":[-85.519885,42.0318586]},"n1821015357":{"id":"n1821015357","loc":[-85.5454035,42.0168431]},"n1821015358":{"id":"n1821015358","loc":[-85.5970629,41.9781881]},"n1821015359":{"id":"n1821015359","loc":[-85.5932541,41.9844767]},"n1821015360":{"id":"n1821015360","loc":[-85.5970736,41.9778252]},"n1821015361":{"id":"n1821015361","loc":[-85.537031,42.0181601]},"n1821015362":{"id":"n1821015362","loc":[-85.5548355,42.0105156]},"n1821015363":{"id":"n1821015363","loc":[-85.5168648,42.0336158]},"n1821015365":{"id":"n1821015365","loc":[-85.5870435,41.9919507]},"n1821015366":{"id":"n1821015366","loc":[-85.5719681,42.0075443]},"n1821015367":{"id":"n1821015367","loc":[-85.5969985,41.9780446]},"n1821015368":{"id":"n1821015368","loc":[-85.5926761,41.98528]},"n1821015369":{"id":"n1821015369","loc":[-85.5224009,42.0293444]},"n1821015371":{"id":"n1821015371","loc":[-85.518737,42.0322651]},"n1821015372":{"id":"n1821015372","loc":[-85.6064573,41.9726465]},"n1821015373":{"id":"n1821015373","loc":[-85.5201103,42.0313088]},"n1821015375":{"id":"n1821015375","loc":[-85.5378182,42.0186844]},"n1821015376":{"id":"n1821015376","loc":[-85.6109741,41.9706882]},"n1821015377":{"id":"n1821015377","loc":[-85.5993333,41.9785488]},"n1821015378":{"id":"n1821015378","loc":[-85.5889787,41.9907368]},"n1821015380":{"id":"n1821015380","loc":[-85.6060161,41.9737375]},"n1821015381":{"id":"n1821015381","loc":[-85.5743016,42.0053679]},"n1821015382":{"id":"n1821015382","loc":[-85.6014724,41.9776099]},"n1821015383":{"id":"n1821015383","loc":[-85.5574426,42.0091644]},"n1821015385":{"id":"n1821015385","loc":[-85.5208613,42.0309302]},"n1821015386":{"id":"n1821015386","loc":[-85.5919023,41.9837789]},"n1821015387":{"id":"n1821015387","loc":[-85.5455484,42.0160221]},"n1821015392":{"id":"n1821015392","loc":[-85.5801757,42.0028964]},"n1821015395":{"id":"n1821015395","loc":[-85.5493785,42.0139974]},"n1821015396":{"id":"n1821015396","loc":[-85.5449475,42.015488]},"n1821015398":{"id":"n1821015398","loc":[-85.611123,41.9706627]},"n1821015400":{"id":"n1821015400","loc":[-85.5935706,41.9822477]},"n1821015401":{"id":"n1821015401","loc":[-85.5724254,42.0073508]},"n1821015403":{"id":"n1821015403","loc":[-85.5486812,42.0143442]},"n1821015404":{"id":"n1821015404","loc":[-85.5161835,42.0327711]},"n1821015406":{"id":"n1821015406","loc":[-85.5921705,41.9851107]},"n1821015407":{"id":"n1821015407","loc":[-85.531912,42.0234069]},"n1821015410":{"id":"n1821015410","loc":[-85.5292566,42.024176]},"n1821015411":{"id":"n1821015411","loc":[-85.5845316,41.9948315]},"n1821015413":{"id":"n1821015413","loc":[-85.5217947,42.0280413]},"n1821015414":{"id":"n1821015414","loc":[-85.5527367,42.013272]},"n1821015415":{"id":"n1821015415","loc":[-85.5191179,42.0321973]},"n1821015416":{"id":"n1821015416","loc":[-85.5540241,42.0128655]},"n1821015418":{"id":"n1821015418","loc":[-85.5272892,42.0254849]},"n1821015419":{"id":"n1821015419","loc":[-85.5449744,42.016867]},"n1821015420":{"id":"n1821015420","loc":[-85.5852665,41.9986787]},"n1821015421":{"id":"n1821015421","loc":[-85.6102701,41.972186]},"n1821015423":{"id":"n1821015423","loc":[-85.6026365,41.9764972]},"n1821015427":{"id":"n1821015427","loc":[-85.5898692,41.9841498]},"n1821015429":{"id":"n1821015429","loc":[-85.5422546,42.0183855]},"n1821015430":{"id":"n1821015430","loc":[-85.5866505,41.9925549]},"n1821015431":{"id":"n1821015431","loc":[-85.5234376,42.0273577]},"n1821015432":{"id":"n1821015432","loc":[-85.6096746,41.9727284]},"n1821015433":{"id":"n1821015433","loc":[-85.5824891,42.0021567]},"n1821015434":{"id":"n1821015434","loc":[-85.5923905,41.9841139]},"n1821015435":{"id":"n1821015435","loc":[-85.5874565,41.9948014]},"n1821015437":{"id":"n1821015437","loc":[-85.6055279,41.9734423]},"n1821015438":{"id":"n1821015438","loc":[-85.5299379,42.0237376]},"n1821015439":{"id":"n1821015439","loc":[-85.5155022,42.0383651]},"n1821015442":{"id":"n1821015442","loc":[-85.527422,42.0254711]},"n1821015443":{"id":"n1821015443","loc":[-85.5920699,41.9849291]},"n1821015444":{"id":"n1821015444","loc":[-85.5639711,42.0077494]},"n1821015445":{"id":"n1821015445","loc":[-85.5162586,42.0361777]},"n1821015446":{"id":"n1821015446","loc":[-85.5220039,42.029695]},"n1821015448":{"id":"n1821015448","loc":[-85.5176641,42.0356956]},"n1821015449":{"id":"n1821015449","loc":[-85.5930556,41.9841577]},"n1821015451":{"id":"n1821015451","loc":[-85.5320783,42.0228848]},"n1821015452":{"id":"n1821015452","loc":[-85.5170096,42.0357235]},"n1821015453":{"id":"n1821015453","loc":[-85.5571355,42.009613]},"n1821015454":{"id":"n1821015454","loc":[-85.5609979,42.009059]},"n1821015455":{"id":"n1821015455","loc":[-85.6097336,41.9708342]},"n1821015456":{"id":"n1821015456","loc":[-85.5884476,41.9904218]},"w170843846":{"id":"w170843846","tags":{"waterway":"river"},"nodes":["n1819790555","n1819790762","n1819790547","n1819790618","n1819790898","n1819790796","n1819790534","n1819790543","n1819790541","n1819790687","n1819790877","n1819790811","n1819790670"]},"w209083541":{"id":"w209083541","tags":{"name":"Portage River","waterway":"river"},"nodes":["n1821014848","n1821015156","n1821015439","n1821014763","n1821014824","n1821015274","n1821014764","n1821014791","n1821014957","n1821015217","n1821015445","n1821015347","n1821014893","n1821015452","n1821015017","n1821015448","n1821014968","n1821015329","n1821015321","n1821014992","n1821014948","n1821014757","n1821014983","n1821015312","n1821015363","n1821014924","n1821014873","n1821014932","n1821014668","n1821015404","n1821014716","n1821015243","n1821015265","n1821014710","n1821015371","n1821015415","n1821014870","n1821015356","n1821015373","n1821014681","n1821014714","n1821015385","n1821014911","n1821015057","n1821014867","n1821014998","n1821015142","n1821015234","n1821015446","n1821014862","n1821015369","n1821014945","n1821015003","n1821014667","n1821015413","n1821015256","n1821015327","n1821015160","n1821014907","n1821015431","n1821015172","n1821015034","n1821014741","n1821015033","n1821015239","n1821015007","n1821015316","n1821015285","n1821014633","n1821015263","n1821015069","n1821014846","n1821014779","n1821015011","n1821015012","n1821014845","n1821015418","n1821015442","n1821015266","n1821015336","n1821014755","n1821015188","n1821014925","n1821014816","n1821014869","n1821014967","n1821015286","n1821015147","n1821015410","n1821015126","n1821015438","n1821015018","n1821015354","n1821015337","n1821014766","n1821014740","n1821015228","n1821015173","n1821015407","n1821015076","n1821015451","n1821015024","n1821015314","n1821014784","n1821015045","n1821014735","n1821015205","n1821014986","n1821015240","n1821015098","n1821014825","n1821015302","n1821014918","n1821014718","n1821014896","n1821014853","n1821015194","n1821015165","n1821015213","n1821014991","n1821015350","n1821015333","n1821015332","n1821015361","n1821015060","n1821014914","n1821015375","n1821015315","n1821015307","n1821014906","n1821014751","n1821014666","n1821015218","n1821014817","n1821015118","n1821014674","n1821015038","n1821014973","n1821015429","n1821015183","n1821015046","n1821014803","n1821015140","n1821015009","n1821014749","n1821015335","n1821014711","n1821014854","n1821015278","n1821015419","n1821014648","n1821015357","n1821014637","n1821014988","n1821015322","n1821015387","n1821015042","n1821014833","n1821015396","n1821015326","n1821014691","n1821015149","n1821015204","n1821015122","n1821014782","n1821014982","n1821014921","n1821014936","n1821014969","n1821014881","n1821015403","n1821014805","n1821015395","n1821014892","n1821014826","n1821014844","n1821015107","n1821015014","n1821014955","n1821015352","n1821015414","n1821014746","n1821015209","n1821014770","n1821015416","n1821014661","n1821014857","n1821014814","n1821014754","n1821014721","n1821014727","n1821015362","n1821015029","n1821015246","n1821015189","n1821014627","n1821015269","n1821014808","n1821014962","n1821015349","n1821015041","n1821014722","n1821015330","n1821015453","n1821015067","n1821014643","n1821014802","n1821015383","n1821015151","n1821015250","n1821015245","n1821014772","n1821014899","n1821015222","n1821015121","n1821014951","n1821015176","n1821015219","n1821015454","n1821014972","n1821014917","n1821015182","n1821015166","n1821015145","n1821014910","n1821015082","n1821014678","n1821014806","n1821015141","n1821015341","n1821014788","n1821015097","n1821014995","n1821015444","n1821015346","n1821015101","n1821015129","n1821015123","n1821015132","n1821015190","n1821015146","n1821015325","n1821015191","n1821015072","n1821015100","n1821015174","n1821015238","n1821015215","n1821014700","n1821015242","n1821014841","n1821014905","n1821014874","n1821014883","n1821014729","n1821014866","n1821014828","n1821015295","n1821014931","n1821014859","n1821014912","n1821014783","n1821014752","n1821014961","n1821015366","n1821015401","n1821015169","n1821015318","n1821014996","n1821014747","n1821014963","n1821014670","n1821015186","n1821015231","n1821015157","n1821014812","n1821015381","n1821014887","n1821015138","n1821014704","n1821014787","n1821014922","n1821015290","n1821015343","n1821014651","n1821014980","n1821014960","n1821015244","n1821015236","n1821015006","n1821014694","n1821014759","n1821015207","n1821015276","n1821015065","n1821014863","n1821014660","n1821014902","n1821014645","n1821015339","n1821014871","n1821015096","n1821015299","n1821014798","n1821014638","n1821015392","n1821014835","n1821014762","n1821014642","n1821015433","n1821014786","n1821015134","n1821014855","n1821015184","n1821014850","n1821015293","n1821015233","n1821015227","n1821014876","n1821014985","n1821014843","n1821015420","n1821015197","n1821015192","n1821015292","n1821015344","n1821014742","n1821014726","n1821015237","n1821014796","n1821014908","n1821014975","n1821014769","n1821014688","n1821014860","n1821014895","n1821014676","n1821015411","n1821014736","n1821015164","n1821014647","n1821015144","n1821014919","n1821015220","n1821015254","n1821015435","n1821015308","n1821015342","n1821014830","n1821015273","n1821014658","n1821014781","n1821015087","n1821015139","n1821015304","n1821014839","n1821015048","n1821015115","n1821015355","n1821015226","n1821015177","n1821015430","n1821014965","n1821014725","n1821015365","n1821015171","n1821015073","n1821015125","n1821015338","n1821015111","n1821014950","n1821015378","n1821015258","n1821015456","n1821015106","n1821014832","n1821014888","n1821014795","n1821014872","n1821014810","n1821014705","n1821014804","n1821014820","n1821015283","n1821014938","n1821014689","n1821015259","n1821015334","n1821015348","n1821014635","n1821015179","n1821014864","n1821014890","n1821015020","n1821014898","n1821015287","n1821015120","n1821014984","n1821014743","n1821014790","n1821014765","n1821014777","n1821015095","n1821014653","n1821015135","n1821014836","n1821014964","n1821014974","n1821014636","n1821014682","n1821014663","n1821014665","n1821015109","n1821015155","n1821014930","n1821014669","n1821015004","n1821015427","n1821014916","n1821015093","n1821015086","n1821015386","n1821014799","n1821014913","n1821015434","n1821014728","n1821014900","n1821015068","n1821015039","n1821015443","n1821015406","n1821015280","n1821015319","n1821015368","n1821014774","n1821015090","n1821015175","n1821015195","n1821014687","n1821015359","n1821015449","n1821014956","n1821014838","n1821014768","n1821014698","n1821015323","n1821014756","n1821015255","n1821015400","n1821014717","n1821014868","n1821014778","n1821015214","n1821014944","n1821014697","n1821014671","n1821014928","n1821015294","n1821014822","n1821015284","n1821015351","n1821015022","n1821015133","n1821014644","n1821015010","n1821014625","n1821014657","n1821014946","n1821015099","n1821015114","n1821014629","n1821014865","n1821014997","n1821014926","n1821014933","n1821015199","n1821014819","n1821015080","n1821014692","n1821014677","n1821015358","n1821015367","n1821015360","n1821015105","n1821015247","n1821015005","n1821014809","n1821014794","n1821014761","n1821014879","n1821014801","n1821015377","n1821015059","n1821014730","n1821015050","n1821015271","n1821015143","n1821014989","n1821015019","n1821014672","n1821014649","n1821014684","n1821014703","n1821015021","n1821015382","n1821014842","n1821014720","n1821014847","n1821015104","n1821014987","n1821014886","n1821015267","n1821015221","n1821015015","n1821015423","n1821014954","n1821014903","n1821014939","n1821015212","n1821014789","n1821014712","n1821014708","n1821015078","n1821015277","n1821015249","n1821014646","n1821014793","n1821015053","n1821014707","n1821015306","n1821015112","n1821015288","n1821015380","n1821015437","n1821015178","n1821015158","n1821015272","n1821015235","n1821015163","n1821015154","n1821015253","n1821014632","n1821015372","n1821015103","n1821015311","n1821015301","n1821014885","n1821014811","n1821014977","n1821015051","n1821014942","n1821014745","n1821015432","n1821015075","n1821014664","n1821014695","n1821015116","n1821014639","n1821015421","n1821015248","n1821014758","n1821014834","n1821015083","n1821015455","n1821015241","n1821015108","n1821014713","n1821015137","n1821015055","n1821015211","n1821014904","n1821015376","n1821015398","n1821014771","n1821014840","n1821015062","n1819790554","n1819790560","n1819790767","n1819790696","n1819790706","n1819790606","n1819790607","n1819790544","n1819790779","n1819790760","n1819790926","n1819790927","n1819790647","n1819790657","n1819790649","n1819790679","n1819790915","n1819790739","n1819790549","n1819790671","n1819790686","n1819790798","n1819790791","n1819790563","n1819790720","n1819790704","n1819790795","n1819790836","n1819790622","n1819790615","n1819790654","n1819790931","n1819790595","n1819790753","n1819790612","n1819790623","n1819790564","n1819790552","n1819790645","n1819790625","n1819790605","n1819790668","n1819790731","n1819790718","n1819790781","n1819790665","n1819790659","n1819790726","n1819790642","n1819790854","n1819790697","n1819790867","n1819790833","n1819790555","n1819790774","n1819790881","n1819790530","n1819790909","n1819790891","n1819790590","n1819790738","n1819790609","n1819790528","n1819790674","n1819790583","n1819790559","n1819790863","n1819790912","n1819790685","n1819790913"]},"n185955128":{"id":"n185955128","loc":[-85.6189367,41.9519432]},"n185948818":{"id":"n185948818","loc":[-85.616755,41.952231]},"n185978819":{"id":"n185978819","loc":[-85.616773,41.954737]},"n185978821":{"id":"n185978821","loc":[-85.616699,41.954742]},"n2138420714":{"id":"n2138420714","loc":[-85.6176304,41.9515154]},"n2138420715":{"id":"n2138420715","loc":[-85.6177355,41.9515717]},"n2138420716":{"id":"n2138420716","loc":[-85.6192901,41.951573]},"n2138420718":{"id":"n2138420718","loc":[-85.6171481,41.9513579]},"n2138420719":{"id":"n2138420719","loc":[-85.6165981,41.9519199]},"n2138420720":{"id":"n2138420720","loc":[-85.6165719,41.9519922]},"n2138420721":{"id":"n2138420721","loc":[-85.6165832,41.9520757]},"n2138420722":{"id":"n2138420722","loc":[-85.6166355,41.9521453]},"n2138420723":{"id":"n2138420723","loc":[-85.6169161,41.9522788]},"n2138420724":{"id":"n2138420724","loc":[-85.6170882,41.9522538]},"n2138420725":{"id":"n2138420725","loc":[-85.6189204,41.9514674]},"n2138420726":{"id":"n2138420726","loc":[-85.6180346,41.9514735]},"n2138420727":{"id":"n2138420727","loc":[-85.6180362,41.9515719]},"n2138420728":{"id":"n2138420728","loc":[-85.6189204,41.9515727]},"n2138420744":{"id":"n2138420744","loc":[-85.618919,41.9519571]},"n2138420745":{"id":"n2138420745","loc":[-85.6194575,41.9522374]},"n2138420746":{"id":"n2138420746","loc":[-85.6181777,41.9536179]},"n2138420747":{"id":"n2138420747","loc":[-85.6176582,41.9533658]},"n2138420748":{"id":"n2138420748","loc":[-85.6179871,41.9530242]},"n2138420749":{"id":"n2138420749","loc":[-85.618429,41.9532476]},"n2138420750":{"id":"n2138420750","loc":[-85.6185538,41.9531194]},"n2138420751":{"id":"n2138420751","loc":[-85.6180765,41.9528677]},"n2138420752":{"id":"n2138420752","loc":[-85.6180394,41.9528855]},"n2138420753":{"id":"n2138420753","loc":[-85.6193752,41.9521695]},"n2138420754":{"id":"n2138420754","loc":[-85.6181374,41.9535376]},"n2138420755":{"id":"n2138420755","loc":[-85.6179898,41.9535545]},"n2138420756":{"id":"n2138420756","loc":[-85.6177286,41.9534228]},"n2138420757":{"id":"n2138420757","loc":[-85.6181011,41.9530292]},"n2138420759":{"id":"n2138420759","loc":[-85.6185158,41.9531194]},"n2138420760":{"id":"n2138420760","loc":[-85.6191318,41.9520425]},"n2138420761":{"id":"n2138420761","loc":[-85.6182348,41.9529815]},"n2138420762":{"id":"n2138420762","loc":[-85.6184853,41.9524248]},"n2138420763":{"id":"n2138420763","loc":[-85.6186764,41.9525193]},"n2138420764":{"id":"n2138420764","loc":[-85.6189421,41.9526483]},"n2138420765":{"id":"n2138420765","loc":[-85.6182875,41.9531222]},"n2138420766":{"id":"n2138420766","loc":[-85.6179141,41.9535163]},"n2138420767":{"id":"n2138420767","loc":[-85.6178363,41.9535735]},"n185948824":{"id":"n185948824","loc":[-85.6165667,41.9529715]},"n2138420758":{"id":"n2138420758","loc":[-85.6184408,41.953201]},"n2138422349":{"id":"n2138422349","loc":[-85.6175136,41.9533346]},"n2138422350":{"id":"n2138422350","loc":[-85.6171867,41.9531679]},"n2138422351":{"id":"n2138422351","loc":[-85.61722,41.9531305]},"n2138422352":{"id":"n2138422352","loc":[-85.6171889,41.9531158]},"n2138422353":{"id":"n2138422353","loc":[-85.6171733,41.9531284]},"n2138422354":{"id":"n2138422354","loc":[-85.616765,41.9529207]},"n2138422355":{"id":"n2138422355","loc":[-85.6167565,41.9529355]},"n2138422356":{"id":"n2138422356","loc":[-85.6164772,41.9527911]},"n2138422357":{"id":"n2138422357","loc":[-85.6168227,41.9524261]},"n2138422358":{"id":"n2138422358","loc":[-85.6171913,41.9526158]},"n2138422359":{"id":"n2138422359","loc":[-85.6172403,41.9525589]},"n2138422360":{"id":"n2138422360","loc":[-85.6172097,41.952542]},"n2138422361":{"id":"n2138422361","loc":[-85.6173948,41.9523512]},"n2138422362":{"id":"n2138422362","loc":[-85.6174256,41.9523678]},"n2138422363":{"id":"n2138422363","loc":[-85.6174831,41.9523086]},"n2138422364":{"id":"n2138422364","loc":[-85.6173316,41.9522289]},"n2138422365":{"id":"n2138422365","loc":[-85.6174507,41.9521024]},"n2138422366":{"id":"n2138422366","loc":[-85.6174773,41.9521155]},"n2138422367":{"id":"n2138422367","loc":[-85.6176577,41.9519232]},"n2138422368":{"id":"n2138422368","loc":[-85.6176336,41.9519105]},"n2138422369":{"id":"n2138422369","loc":[-85.617747,41.9517861]},"n2138422370":{"id":"n2138422370","loc":[-85.6182675,41.9520559]},"n2138422371":{"id":"n2138422371","loc":[-85.6182105,41.9521219]},"n2138422372":{"id":"n2138422372","loc":[-85.6183863,41.9522203]},"n2138422373":{"id":"n2138422373","loc":[-85.6180984,41.9525266]},"n2138422374":{"id":"n2138422374","loc":[-85.6179159,41.9524295]},"n2138422375":{"id":"n2138422375","loc":[-85.617854,41.9524979]},"n2138422376":{"id":"n2138422376","loc":[-85.6177686,41.9524531]},"n2138422377":{"id":"n2138422377","loc":[-85.6174716,41.9527765]},"n2138422378":{"id":"n2138422378","loc":[-85.6178545,41.9529756]},"n2138425424":{"id":"n2138425424","loc":[-85.6171736,41.9536385]},"n2138425425":{"id":"n2138425425","loc":[-85.6180159,41.9535782]},"n2138425426":{"id":"n2138425426","loc":[-85.6181068,41.9536282]},"n2138425427":{"id":"n2138425427","loc":[-85.6180673,41.9542678]},"n2138425428":{"id":"n2138425428","loc":[-85.6178636,41.9542634]},"n2138425429":{"id":"n2138425429","loc":[-85.6176204,41.9542046]},"n2138425430":{"id":"n2138425430","loc":[-85.6174366,41.9541031]},"n2138425431":{"id":"n2138425431","loc":[-85.6172942,41.9539781]},"n2138425432":{"id":"n2138425432","loc":[-85.6172171,41.9538399]},"n2138425433":{"id":"n2138425433","loc":[-85.6168138,41.9543266]},"n2138425434":{"id":"n2138425434","loc":[-85.6167779,41.9538098]},"n2138425435":{"id":"n2138425435","loc":[-85.6165849,41.9537073]},"n2138425441":{"id":"n2138425441","loc":[-85.616458,41.9543184]},"n2138425442":{"id":"n2138425442","loc":[-85.6166428,41.954345]},"n2138425445":{"id":"n2138425445","loc":[-85.6181332,41.9514117]},"n2138425446":{"id":"n2138425446","loc":[-85.6183263,41.9514111]},"n2138425447":{"id":"n2138425447","loc":[-85.6185033,41.9514102]},"n2138425449":{"id":"n2138425449","loc":[-85.6186809,41.9514093]},"n2138425451":{"id":"n2138425451","loc":[-85.6188681,41.9514082]},"n2138436008":{"id":"n2138436008","loc":[-85.6170474,41.9513604]},"n2138436009":{"id":"n2138436009","loc":[-85.6164937,41.9519586]},"n2138436010":{"id":"n2138436010","loc":[-85.616497,41.9520725]},"n2138436011":{"id":"n2138436011","loc":[-85.6165654,41.9521645]},"n2138436012":{"id":"n2138436012","loc":[-85.6166631,41.9522178]},"n2138436013":{"id":"n2138436013","loc":[-85.6167327,41.9522554]},"n2138436014":{"id":"n2138436014","loc":[-85.6172383,41.9525125]},"n2138439319":{"id":"n2138439319","loc":[-85.6170432,41.9524057]},"n2138439320":{"id":"n2138439320","loc":[-85.617691,41.9517107]},"n2138439321":{"id":"n2138439321","loc":[-85.6177727,41.9516794]},"n2138439322":{"id":"n2138439322","loc":[-85.619085,41.9516811]},"n2138439323":{"id":"n2138439323","loc":[-85.6179432,41.952895]},"n2138439324":{"id":"n2138439324","loc":[-85.6180389,41.9529384]},"n2138439325":{"id":"n2138439325","loc":[-85.6176303,41.9533604]},"n2138439326":{"id":"n2138439326","loc":[-85.6175538,41.9534396]},"n2138439327":{"id":"n2138439327","loc":[-85.6173806,41.9523658]},"n2138439328":{"id":"n2138439328","loc":[-85.6171841,41.9522542]},"n2138439329":{"id":"n2138439329","loc":[-85.6172077,41.9524958]},"n2138439330":{"id":"n2138439330","loc":[-85.6171235,41.9525809]},"n2138439331":{"id":"n2138439331","loc":[-85.6180938,41.9527349]},"n2138439332":{"id":"n2138439332","loc":[-85.6177023,41.9525253]},"n2138439333":{"id":"n2138439333","loc":[-85.6175543,41.9526865]},"n2138439334":{"id":"n2138439334","loc":[-85.6179589,41.9528783]},"n185948820":{"id":"n185948820","loc":[-85.6163249,41.952701]},"n185948822":{"id":"n185948822","loc":[-85.6163757,41.952855]},"n185955123":{"id":"n185955123","loc":[-85.6198103,41.9510408]},"n185958839":{"id":"n185958839","loc":[-85.611651,41.954761]},"n185965033":{"id":"n185965033","loc":[-85.614195,41.954754]},"n185976502":{"id":"n185976502","loc":[-85.617375,41.947559]},"n185976504":{"id":"n185976504","loc":[-85.6174164,41.9510804]},"n185978828":{"id":"n185978828","loc":[-85.613542,41.954756]},"n185978830":{"id":"n185978830","loc":[-85.610373,41.954774]},"n2138420713":{"id":"n2138420713","loc":[-85.6174641,41.9506942]},"n2138420717":{"id":"n2138420717","loc":[-85.6173027,41.9512895]},"n2138420768":{"id":"n2138420768","loc":[-85.61745,41.9501974]},"n2138420773":{"id":"n2138420773","loc":[-85.6174135,41.9489136]},"n2138425436":{"id":"n2138425436","loc":[-85.6159148,41.9538036]},"n2138425437":{"id":"n2138425437","loc":[-85.6159534,41.9539677]},"n2138425438":{"id":"n2138425438","loc":[-85.6160306,41.9540846]},"n2138425439":{"id":"n2138425439","loc":[-85.6161354,41.954181]},"n2138425440":{"id":"n2138425440","loc":[-85.6162733,41.954263]},"n2138425443":{"id":"n2138425443","loc":[-85.6183273,41.9510826]},"n2138425444":{"id":"n2138425444","loc":[-85.6181354,41.9510835]},"n2138425448":{"id":"n2138425448","loc":[-85.6185033,41.9510816]},"n2138425450":{"id":"n2138425450","loc":[-85.6186816,41.9510808]},"n2138425452":{"id":"n2138425452","loc":[-85.6188641,41.9510818]},"n2138435984":{"id":"n2138435984","loc":[-85.6167607,41.9501009]},"n2138436000":{"id":"n2138436000","loc":[-85.6173169,41.947558]},"n2138436001":{"id":"n2138436001","loc":[-85.6173362,41.948883]},"n2138436002":{"id":"n2138436002","loc":[-85.6167791,41.9492952]},"n2138436003":{"id":"n2138436003","loc":[-85.6167543,41.949349]},"n2138436004":{"id":"n2138436004","loc":[-85.6167648,41.9509125]},"n2138436005":{"id":"n2138436005","loc":[-85.6168832,41.9510412]},"n2138436006":{"id":"n2138436006","loc":[-85.6170045,41.9511417]},"n2138436007":{"id":"n2138436007","loc":[-85.6170624,41.9512483]},"n2138436017":{"id":"n2138436017","loc":[-85.6168094,41.9492729]},"n2138436021":{"id":"n2138436021","loc":[-85.6167553,41.9494886]},"n2138436023":{"id":"n2138436023","loc":[-85.6167585,41.9499707]},"n2138436025":{"id":"n2138436025","loc":[-85.6167567,41.9497018]},"w203838284":{"id":"w203838284","tags":{"area":"yes","leisure":"pitch","sport":"baseball"},"nodes":["n2138425424","n2138425425","n2138425426","n2138425427","n2138425428","n2138425429","n2138425430","n2138425431","n2138425432","n2138425424"]},"w203837928":{"id":"w203837928","tags":{"highway":"service"},"nodes":["n2138420717","n2138420718","n2138420719","n2138420720","n2138420721","n2138420722","n185948818","n2138420723","n2138420724","n2138420715"]},"w203839364":{"id":"w203839364","tags":{"highway":"footway"},"nodes":["n2138439331","n2138439332"]},"w203837932":{"id":"w203837932","tags":{"amenity":"parking","area":"yes"},"nodes":["n2138420744","n2138420745","n2138420746","n2138420747","n2138420748","n2138420749","n2138420750","n2138420751","n2138420744"]},"w203839362":{"id":"w203839362","tags":{"highway":"footway"},"nodes":["n2138439327","n2138439328"]},"w203839363":{"id":"w203839363","tags":{"highway":"footway"},"nodes":["n2138439329","n2138439330"]},"w203837933":{"id":"w203837933","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n185955128","n2138420760","n2138420753","n2138420764","n2138420759","n2138420758","n2138420754","n2138420755","n2138420766","n2138420756"]},"w203837936":{"id":"w203837936","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420765","n2138420766"]},"w17966364":{"id":"w17966364","tags":{"access":"private","highway":"service","name":"Collins Dr"},"nodes":["n185961362","n185976502","n2138420773","n2138420768","n2138420713","n185976504","n2138420717","n2138420714","n2138420715","n2138420727","n2138420728","n2138420716"]},"w203838040":{"id":"w203838040","tags":{"amenity":"school","area":"yes","building":"yes","name":"Three Rivers Middle School"},"nodes":["n2138422349","n2138422350","n2138422351","n2138422352","n2138422353","n2138422354","n2138422355","n2138422356","n2138422357","n2138439330","n2138422358","n2138422359","n2138422360","n2138436014","n2138439327","n2138422361","n2138422362","n2138422363","n2138422364","n2138422365","n2138422366","n2138422367","n2138422368","n2138422369","n2138422370","n2138422371","n2138422372","n2138422373","n2138422374","n2138422375","n2138422376","n2138439332","n2138439333","n2138422377","n2138422378","n2138422349"]},"w17964049":{"id":"w17964049","tags":{"highway":"service"},"nodes":["n185955120","n185955123","n2138420716","n185955128","n2138420762","n2138420752","n2138420761","n2138420759"]},"w41074899":{"id":"w41074899","tags":{"highway":"secondary","name":"E Hoffman St","ref":"M 60"},"nodes":["n185978817","n185978819","n185978821","n185965033","n185978828","n185958839","n185978830"]},"w203839365":{"id":"w203839365","tags":{"highway":"footway"},"nodes":["n2138439333","n2138439334"]},"w203837935":{"id":"w203837935","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420762","n2138420763","n2138420764"]},"w203838287":{"id":"w203838287","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425446","n2138425447","n2138425448","n2138425443","n2138425446"]},"w203837934":{"id":"w203837934","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420760","n2138420763","n2138420761"]},"w203838289":{"id":"w203838289","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425449","n2138425451","n2138425452","n2138425450","n2138425449"]},"w17963047":{"id":"w17963047","tags":{"highway":"service"},"nodes":["n185948818","n2138436013","n185948820","n185948822","n185948824","n2138439326","n2138420767","n2138420766"]},"w203839091":{"id":"w203839091","tags":{"highway":"footway"},"nodes":["n185976502","n2138436000","n2138436001","n2138436017","n2138436002","n2138436003","n2138436021","n2138436025","n2138436023","n2138435984","n2138436004","n2138436005","n2138436006","n2138436007","n2138436008","n2138436009","n2138436010","n2138436011","n2138436012","n2138436013","n2138439319","n2138439329","n2138436014"]},"w204830797":{"id":"w204830797","tags":{"highway":"service","service":"parking_aisle"},"nodes":["n2138420756","n2138420757","n2138420765","n2138420758"]},"w203838288":{"id":"w203838288","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425447","n2138425449","n2138425450","n2138425448","n2138425447"]},"w203838285":{"id":"w203838285","tags":{"area":"yes","leisure":"pitch","sport":"baseball"},"nodes":["n2138425433","n2138425434","n2138425435","n2138425436","n2138425437","n2138425438","n2138425439","n2138425440","n2138425441","n2138425442","n2138425433"]},"w203838286":{"id":"w203838286","tags":{"area":"yes","leisure":"pitch","sport":"tennis"},"nodes":["n2138425443","n2138425444","n2138425445","n2138425446","n2138425443"]},"w203837929":{"id":"w203837929","tags":{"amenity":"parking","area":"yes"},"nodes":["n2138420725","n2138420726","n2138420727","n2138420728","n2138420725"]},"w203839361":{"id":"w203839361","tags":{"highway":"footway"},"nodes":["n2138439319","n2138439328","n2138439320","n2138439321","n2138439322","n2138439331","n2138439334","n2138439323","n2138439324","n2138439325","n2138439326"]},"n394381698":{"id":"n394381698","loc":[-85.614471,41.954755]},"n394381699":{"id":"n394381699","loc":[-85.6152,41.954744]},"n394381700":{"id":"n394381700","loc":[-85.615201,41.954081]},"n394381701":{"id":"n394381701","loc":[-85.614426,41.954042]},"n394381702":{"id":"n394381702","loc":[-85.616319,41.954749]},"n394381704":{"id":"n394381704","loc":[-85.616152,41.954752]},"n394381706":{"id":"n394381706","loc":[-85.615201,41.95483]},"n394490775":{"id":"n394490775","loc":[-85.613971,41.954839]},"n394490782":{"id":"n394490782","loc":[-85.614372,41.954841]},"n185958835":{"id":"n185958835","loc":[-85.611615,41.953704]},"n185958837":{"id":"n185958837","loc":[-85.611636,41.953938]},"n185958842":{"id":"n185958842","loc":[-85.611187,41.951686]},"n185958844":{"id":"n185958844","loc":[-85.611087,41.951741]},"n185958845":{"id":"n185958845","loc":[-85.611034,41.951852]},"n185958847":{"id":"n185958847","loc":[-85.611016,41.95196]},"n185958849":{"id":"n185958849","loc":[-85.610989,41.95328]},"n185958851":{"id":"n185958851","loc":[-85.611021,41.953484]},"n185958852":{"id":"n185958852","loc":[-85.611091,41.953603]},"n185958853":{"id":"n185958853","loc":[-85.6112,41.953661]},"n185958855":{"id":"n185958855","loc":[-85.611364,41.953686]},"n185965031":{"id":"n185965031","loc":[-85.614204,41.953696]},"n185965032":{"id":"n185965032","loc":[-85.6142,41.953978]},"n185965062":{"id":"n185965062","loc":[-85.614617,41.951639]},"n185965064":{"id":"n185965064","loc":[-85.61463,41.951852]},"n185965066":{"id":"n185965066","loc":[-85.614642,41.953436]},"n185965068":{"id":"n185965068","loc":[-85.6146,41.953551]},"n185965071":{"id":"n185965071","loc":[-85.614487,41.95363]},"n185965073":{"id":"n185965073","loc":[-85.614354,41.953672]},"n185966288":{"id":"n185966288","loc":[-85.61179,41.953695]},"n185966290":{"id":"n185966290","loc":[-85.612232,41.953685]},"n185966293":{"id":"n185966293","loc":[-85.613438,41.953677]},"n185966349":{"id":"n185966349","loc":[-85.611323,41.951653]},"n185966351":{"id":"n185966351","loc":[-85.611892,41.951642]},"n185966352":{"id":"n185966352","loc":[-85.612216,41.951641]},"n185966353":{"id":"n185966353","loc":[-85.613111,41.951639]},"n185966354":{"id":"n185966354","loc":[-85.613396,41.95164]},"n185966355":{"id":"n185966355","loc":[-85.614221,41.95164]},"n185973839":{"id":"n185973839","loc":[-85.61341,41.951919]},"n185973840":{"id":"n185973840","loc":[-85.613438,41.953308]},"n185980222":{"id":"n185980222","loc":[-85.613781,41.955164]},"n185980223":{"id":"n185980223","loc":[-85.613815,41.955237]},"n185980225":{"id":"n185980225","loc":[-85.613837,41.955316]},"n185990345":{"id":"n185990345","loc":[-85.612211,41.951977]},"n185955743":{"id":"n185955743","loc":[-85.613873,41.95635]},"n185980227":{"id":"n185980227","loc":[-85.613851,41.955415]},"n185980229":{"id":"n185980229","loc":[-85.613918,41.957134]},"n394381703":{"id":"n394381703","loc":[-85.616287,41.955674]},"n394381705":{"id":"n394381705","loc":[-85.615164,41.955676]},"n394490777":{"id":"n394490777","loc":[-85.613973,41.955979]},"n394490780":{"id":"n394490780","loc":[-85.614364,41.955987]},"w17965307":{"id":"w17965307","tags":{"highway":"residential","name":"Bates Ave"},"nodes":["n185958842","n185966349","n185966351","n185966352","n185966353","n185966354","n185966355","n185965062"]},"w17967957":{"id":"w17967957","tags":{"highway":"residential","name":"Krum Ave"},"nodes":["n185966352","n185990345","n185966290"]},"w17964508":{"id":"w17964508","tags":{"highway":"residential","name":"Blossom Dr"},"nodes":["n185958842","n185958844","n185958845","n185958847","n185958849","n185958851","n185958852","n185958853","n185958855","n185958835"]},"w17964507":{"id":"w17964507","tags":{"highway":"residential","name":"Blossom Dr"},"nodes":["n185958835","n185958837","n185958839"]},"w34367080":{"id":"w34367080","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394381699","n394381706","n394381705","n394381703","n394381702","n394381704","n394381699"]},"w17965302":{"id":"w17965302","tags":{"highway":"residential","name":"Clausen Ave"},"nodes":["n185958835","n185966288","n185966290","n185966293","n185965031"]},"w17965156":{"id":"w17965156","tags":{"highway":"residential","name":"Orchard Dr"},"nodes":["n185965062","n185965064","n185965066","n185965068","n185965071","n185965073","n185965031"]},"w34369812":{"id":"w34369812","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394490775","n394490777","n394490780","n394490782","n394490775"]},"w17965151":{"id":"w17965151","tags":{"highway":"residential","name":"Orchard Dr"},"nodes":["n185965031","n185965032","n185965033"]},"w17966756":{"id":"w17966756","tags":{"access":"private","highway":"service","name":"Lockport Dr"},"nodes":["n185978828","n185980222","n185980223","n185980225","n185980227","n185955743","n185980229"]},"w17966056":{"id":"w17966056","tags":{"highway":"residential","name":"Angell Ave"},"nodes":["n185966354","n185973839","n185973840","n185966293"]},"w34367079":{"id":"w34367079","tags":{"admin_level":"8","boundary":"administrative"},"nodes":["n394381700","n394381701","n394381698","n394381699","n394381700"]},"n185955744":{"id":"n185955744","loc":[-85.611753,41.956208]},"n185988932":{"id":"n185988932","loc":[-85.6159,41.956336]},"n185988934":{"id":"n185988934","loc":[-85.6159158,41.9590646]},"n185988935":{"id":"n185988935","loc":[-85.6157358,41.959364],"tags":{"highway":"turning_circle"}},"n2138447007":{"id":"n2138447007","loc":[-85.6130784,41.9590689]},"n2138447008":{"id":"n2138447008","loc":[-85.6133328,41.9593805]},"n2138447003":{"id":"n2138447003","loc":[-85.610238,41.9547745]},"n2138447004":{"id":"n2138447004","loc":[-85.6102652,41.9566041]},"n2138447005":{"id":"n2138447005","loc":[-85.610325,41.9568823]},"n2138447006":{"id":"n2138447006","loc":[-85.6105644,41.9571383]},"n2138447009":{"id":"n2138447009","loc":[-85.6135946,41.959948]},"n2138447010":{"id":"n2138447010","loc":[-85.6136071,41.9629372]},"n2138447011":{"id":"n2138447011","loc":[-85.6134392,41.9633182]},"n2138447012":{"id":"n2138447012","loc":[-85.6130151,41.9636073]},"n2138447013":{"id":"n2138447013","loc":[-85.6122729,41.9637125]},"n2138447014":{"id":"n2138447014","loc":[-85.6056682,41.963752]},"w17964174":{"id":"w17964174","tags":{"access":"private","highway":"service"},"nodes":["n185955743","n185955744"]},"w17967743":{"id":"w17967743","tags":{"access":"private","highway":"service","name":"Manistee River Rd"},"nodes":["n185971574","n185988932","n185971407","n185981301","n185967987","n185988934","n185988935"]},"w203839666":{"id":"w203839666","tags":{"highway":"residential","name":"Hov Aire Drive"},"nodes":["n2138447003","n2138447004","n2138447005","n2138447006","n2138447007","n2138447008","n2138447009","n2138447010","n2138447011","n2138447012","n2138447013","n2138447014"]}};
56929 function pointBox(point, context) {
56930 var rect = context.surfaceRect();
56931 point = context.projection(point);
56933 left: point[0] + rect.left - 30,
56934 top: point[1] + rect.top - 50,
56941 function pad$1(box, padding, context) {
56942 if (box instanceof Array) {
56943 var rect = context.surfaceRect();
56944 box = context.projection(box);
56946 left: box[0] + rect.left,
56947 top: box[1] + rect.top
56951 left: box.left - padding,
56952 top: box.top - padding,
56953 width: (box.width || 0) + 2 * padding,
56954 height: (box.width || 0) + 2 * padding
56959 function icon(name, svgklass) {
56960 return '<svg class="icon ' + (svgklass || '') + '">' +
56961 '<use xlink:href="' + name + '"></use></svg>';
56964 function uiIntroNavigation(context, reveal) {
56965 var dispatch$$1 = dispatch('done'),
56969 title: 'intro.navigation.title'
56973 function set$$1(f, t$$1) {
56974 timeouts.push(window.setTimeout(f, t$$1));
56978 function eventCancel() {
56979 event.stopPropagation();
56980 event.preventDefault();
56984 step.enter = function() {
56985 var rect = context.surfaceRect(),
56987 left: rect.left + 10,
56988 top: rect.top + 70,
56989 width: rect.width - 70,
56990 height: rect.height - 170
56993 context.map().centerZoom([-85.63591, 41.94285], 19);
56995 reveal(map$$1, t('intro.navigation.drag'));
56997 context.map().on('move.intro', lodash.debounce(function() {
56998 context.map().on('move.intro', null);
57000 context.on('enter.intro', inspectTownHall);
57004 function townhall() {
57005 var hall = [-85.63645945147184, 41.942986488012565];
57006 var point = context.projection(hall);
57008 if (point[0] < 0 || point[0] > rect.width ||
57009 point[1] < 0 || point[1] > rect.height) {
57010 context.map().center(hall);
57013 var box = pointBox(hall, context);
57014 reveal(box, t('intro.navigation.select'));
57016 context.map().on('move.intro', function() {
57017 var box = pointBox(hall, context);
57018 reveal(box, t('intro.navigation.select'), {duration: 0});
57023 function inspectTownHall(mode) {
57024 if (mode.id !== 'select') return;
57025 context.on('enter.intro', null);
57026 context.map().on('move.intro', null);
57027 set$$1(function() {
57028 reveal('.entity-editor-pane',
57029 t('intro.navigation.pane', { button: icon('#icon-close', 'pre-text') }));
57030 context.on('exit.intro', streetSearch);
57035 function streetSearch() {
57036 context.on('exit.intro', null);
57037 reveal('.search-header input',
57038 t('intro.navigation.search', { name: t('intro.graph.spring_st') }));
57039 select('.search-header input')
57040 .on('keyup.intro', searchResult);
57044 function searchResult() {
57045 var first = select('.feature-list-item:nth-child(0n+2)'), // skip No Results item
57046 firstName = first.select('.entity-name'),
57047 name = t('intro.graph.spring_st');
57049 if (!firstName.empty() && firstName.text() === name) {
57050 reveal(first.node(), t('intro.navigation.choose', { name: name }));
57051 context.on('exit.intro', selectedStreet);
57052 select('.search-header input')
57053 .on('keydown.intro', eventCancel, true)
57054 .on('keyup.intro', null);
57059 function selectedStreet() {
57060 var springSt = [-85.63585099140167, 41.942506848938926];
57061 context.map().center(springSt);
57062 context.on('exit.intro', function() {
57063 dispatch$$1.call('done');
57066 set$$1(function() {
57067 reveal('.entity-editor-pane',
57068 t('intro.navigation.chosen', {
57069 name: t('intro.graph.spring_st'),
57070 button: icon('#icon-close', 'pre-text')
57077 step.exit = function() {
57078 timeouts.forEach(window.clearTimeout);
57079 context.map().on('move.intro', null);
57080 context.on('enter.intro', null);
57081 context.on('exit.intro', null);
57082 select('.search-header input')
57083 .on('keydown.intro', null)
57084 .on('keyup.intro', null);
57088 return utilRebind(step, dispatch$$1, 'on');
57091 function uiIntroPoint(context, reveal) {
57092 var dispatch$$1 = dispatch('done'),
57096 title: 'intro.points.title'
57100 function setTimeout(f, t$$1) {
57101 timeouts.push(window.setTimeout(f, t$$1));
57105 function eventCancel() {
57106 event.stopPropagation();
57107 event.preventDefault();
57111 step.enter = function() {
57112 context.map().centerZoom([-85.63279, 41.94394], 19);
57113 reveal('button.add-point',
57114 t('intro.points.add', { button: icon('#icon-point', 'pre-text') }),
57115 { tooltipClass: 'intro-points-add' });
57117 var corner = [-85.632481,41.944094];
57119 context.on('enter.intro', addPoint);
57122 function addPoint(mode) {
57123 if (mode.id !== 'add-point') return;
57124 context.on('enter.intro', enterSelect);
57126 var pointBox$$1 = pad$1(corner, 150, context);
57127 reveal(pointBox$$1, t('intro.points.place'));
57129 context.map().on('move.intro', function() {
57130 pointBox$$1 = pad$1(corner, 150, context);
57131 reveal(pointBox$$1, t('intro.points.place'), {duration: 0});
57136 function enterSelect(mode) {
57137 if (mode.id !== 'select') return;
57138 context.map().on('move.intro', null);
57139 context.on('enter.intro', null);
57141 setTimeout(function() {
57142 reveal('.preset-search-input',
57143 t('intro.points.search', {name: context.presets().item('amenity/cafe').name()}));
57144 select('.preset-search-input').on('keyup.intro', keySearch);
57149 function keySearch() {
57150 var first = select('.preset-list-item:first-child');
57151 if (first.classed('preset-amenity-cafe')) {
57152 reveal(first.select('.preset-list-button').node(), t('intro.points.choose'));
57153 utilBindOnce(context.history(), 'change.intro', selectedPreset);
57154 select('.preset-search-input')
57155 .on('keydown.intro', eventCancel, true)
57156 .on('keyup.intro', null);
57161 function selectedPreset() {
57162 setTimeout(function() {
57163 reveal('.entity-editor-pane', t('intro.points.describe'), {tooltipClass: 'intro-points-describe'});
57164 context.history().on('change.intro', closeEditor);
57165 context.on('exit.intro', selectPoint);
57170 function closeEditor() {
57171 select('.preset-search-input').on('keydown.intro', null);
57172 context.history().on('change.intro', null);
57173 reveal('.entity-editor-pane',
57174 t('intro.points.close', { button: icon('#icon-apply', 'pre-text') }));
57178 function selectPoint() {
57179 context.on('exit.intro', null);
57180 context.history().on('change.intro', null);
57181 context.on('enter.intro', enterReselect);
57183 var pointBox$$1 = pad$1(corner, 150, context);
57184 reveal(pointBox$$1, t('intro.points.reselect'));
57186 context.map().on('move.intro', function() {
57187 pointBox$$1 = pad$1(corner, 150, context);
57188 reveal(pointBox$$1, t('intro.points.reselect'), {duration: 0});
57193 function enterReselect(mode) {
57194 if (mode.id !== 'select') return;
57195 context.map().on('move.intro', null);
57196 context.on('enter.intro', null);
57198 setTimeout(function() {
57199 reveal('.entity-editor-pane',
57200 t('intro.points.fixname', { button: icon('#icon-apply', 'pre-text') }));
57201 context.on('exit.intro', deletePoint);
57206 function deletePoint() {
57207 context.on('exit.intro', null);
57208 context.on('enter.intro', enterDelete);
57210 var pointBox$$1 = pad$1(corner, 150, context);
57211 reveal(pointBox$$1, t('intro.points.reselect_delete'));
57213 context.map().on('move.intro', function() {
57214 pointBox$$1 = pad$1(corner, 150, context);
57215 reveal(pointBox$$1, t('intro.points.reselect_delete'), {duration: 0});
57220 function enterDelete(mode) {
57221 if (mode.id !== 'select') return;
57222 context.map().on('move.intro', null);
57223 context.on('enter.intro', null);
57224 context.on('exit.intro', deletePoint);
57225 context.map().on('move.intro', deletePoint);
57226 context.history().on('change.intro', deleted);
57228 setTimeout(function() {
57229 var node = select('.radial-menu-item-delete').node();
57230 var pointBox$$1 = pad$1(node.getBoundingClientRect(), 50, context);
57231 reveal(pointBox$$1,
57232 t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }));
57237 function deleted(changed) {
57238 if (changed.deleted().length) {
57239 dispatch$$1.call('done');
57246 step.exit = function() {
57247 timeouts.forEach(window.clearTimeout);
57248 context.on('exit.intro', null);
57249 context.on('enter.intro', null);
57250 context.map().on('move.intro', null);
57251 context.history().on('change.intro', null);
57252 select('.preset-search-input')
57253 .on('keyup.intro', null)
57254 .on('keydown.intro', null);
57257 return utilRebind(step, dispatch$$1, 'on');
57260 function uiIntroArea(context, reveal) {
57261 var dispatch$$1 = dispatch('done'),
57265 title: 'intro.areas.title'
57269 step.enter = function() {
57270 var playground = [-85.63552, 41.94159],
57271 corner = [-85.63565411045074, 41.9417715536927];
57272 context.map().centerZoom(playground, 19);
57273 reveal('button.add-area',
57274 t('intro.areas.add', { button: icon('#icon-area', 'pre-text') }),
57275 { tooltipClass: 'intro-areas-add' });
57277 context.on('enter.intro', addArea);
57280 function addArea(mode) {
57281 if (mode.id !== 'add-area') return;
57282 context.on('enter.intro', drawArea);
57284 var padding = 120 * Math.pow(2, context.map().zoom() - 19);
57285 var pointBox$$1 = pad$1(corner, padding, context);
57286 reveal(pointBox$$1, t('intro.areas.corner'));
57288 context.map().on('move.intro', function() {
57289 padding = 120 * Math.pow(2, context.map().zoom() - 19);
57290 pointBox$$1 = pad$1(corner, padding, context);
57291 reveal(pointBox$$1, t('intro.areas.corner'), {duration: 0});
57296 function drawArea(mode) {
57297 if (mode.id !== 'draw-area') return;
57298 context.on('enter.intro', enterSelect);
57300 var padding = 150 * Math.pow(2, context.map().zoom() - 19);
57301 var pointBox$$1 = pad$1(playground, padding, context);
57302 reveal(pointBox$$1, t('intro.areas.place'));
57304 context.map().on('move.intro', function() {
57305 padding = 150 * Math.pow(2, context.map().zoom() - 19);
57306 pointBox$$1 = pad$1(playground, padding, context);
57307 reveal(pointBox$$1, t('intro.areas.place'), {duration: 0});
57312 function enterSelect(mode) {
57313 if (mode.id !== 'select') return;
57314 context.map().on('move.intro', null);
57315 context.on('enter.intro', null);
57317 timeout$$1 = setTimeout(function() {
57318 reveal('.preset-search-input',
57319 t('intro.areas.search',
57320 { name: context.presets().item('leisure/playground').name() }));
57321 select('.preset-search-input').on('keyup.intro', keySearch);
57326 function keySearch() {
57327 var first = select('.preset-list-item:first-child');
57328 if (first.classed('preset-leisure-playground')) {
57329 reveal(first.select('.preset-list-button').node(), t('intro.areas.choose'));
57330 utilBindOnce(context.history(), 'change.intro', selectedPreset);
57331 select('.preset-search-input').on('keyup.intro', null);
57336 function selectedPreset() {
57338 t('intro.areas.describe', { button: icon('#icon-apply', 'pre-text') }));
57339 context.on('exit.intro', function() {
57340 dispatch$$1.call('done');
57346 step.exit = function() {
57347 window.clearTimeout(timeout$$1);
57348 context.on('enter.intro', null);
57349 context.on('exit.intro', null);
57350 context.history().on('change.intro', null);
57351 context.map().on('move.intro', null);
57352 select('.preset-search-input').on('keyup.intro', null);
57356 return utilRebind(step, dispatch$$1, 'on');
57359 function uiIntroLine(context, reveal) {
57360 var dispatch$$1 = dispatch('done'),
57364 title: 'intro.lines.title'
57368 function timeout$$1(f, t$$1) {
57369 timeouts.push(window.setTimeout(f, t$$1));
57373 function eventCancel() {
57374 event.stopPropagation();
57375 event.preventDefault();
57379 step.enter = function() {
57380 var centroid = [-85.62830, 41.95699];
57381 var midpoint = [-85.62975395449628, 41.95787501510204];
57382 var start = [-85.6297754121684, 41.95805253325314];
57383 var intersection = [-85.62974496187628, 41.95742515554585];
57385 context.map().centerZoom(start, 18);
57386 reveal('button.add-line',
57387 t('intro.lines.add', { button: icon('#icon-line', 'pre-text') }),
57388 { tooltipClass: 'intro-lines-add' });
57390 context.on('enter.intro', addLine);
57393 function addLine(mode) {
57394 if (mode.id !== 'add-line') return;
57395 context.on('enter.intro', drawLine);
57397 var padding = 150 * Math.pow(2, context.map().zoom() - 18);
57398 var pointBox$$1 = pad$1(start, padding, context);
57399 reveal(pointBox$$1, t('intro.lines.start'));
57401 context.map().on('move.intro', function() {
57402 padding = 150 * Math.pow(2, context.map().zoom() - 18);
57403 pointBox$$1 = pad$1(start, padding, context);
57404 reveal(pointBox$$1, t('intro.lines.start'), {duration: 0});
57409 function drawLine(mode) {
57410 if (mode.id !== 'draw-line') return;
57411 context.history().on('change.intro', addIntersection);
57412 context.on('enter.intro', retry);
57414 var padding = 300 * Math.pow(2, context.map().zoom() - 19);
57415 var pointBox$$1 = pad$1(midpoint, padding, context);
57416 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}));
57418 context.map().on('move.intro', function() {
57419 padding = 300 * Math.pow(2, context.map().zoom() - 19);
57420 pointBox$$1 = pad$1(midpoint, padding, context);
57421 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}), {duration: 0});
57426 // ended line before creating intersection
57427 function retry(mode) {
57428 if (mode.id !== 'select') return;
57429 var pointBox$$1 = pad$1(intersection, 30, context),
57430 ids = mode.selectedIDs();
57431 reveal(pointBox$$1, t('intro.lines.restart', {name: t('intro.graph.flower_st')}));
57432 select(window).on('mousedown.intro', eventCancel, true);
57434 timeout$$1(function() {
57435 context.replace(actionDeleteMultiple(ids));
57442 function addIntersection(changes) {
57443 if ( lodash.some(changes.created(), function(d) {
57444 return d.type === 'node' && context.graph().parentWays(d).length > 1;
57446 context.history().on('change.intro', null);
57447 context.on('enter.intro', enterSelect);
57449 var padding = 900 * Math.pow(2, context.map().zoom() - 19);
57450 var pointBox$$1 = pad$1(centroid, padding, context);
57451 reveal(pointBox$$1, t('intro.lines.finish'));
57453 context.map().on('move.intro', function() {
57454 padding = 900 * Math.pow(2, context.map().zoom() - 19);
57455 pointBox$$1 = pad$1(centroid, padding, context);
57456 reveal(pointBox$$1, t('intro.lines.finish'), {duration: 0});
57462 function enterSelect(mode) {
57463 if (mode.id !== 'select') return;
57464 context.map().on('move.intro', null);
57465 context.on('enter.intro', null);
57466 select('#curtain').style('pointer-events', 'all');
57472 function presetCategory() {
57473 timeout$$1(function() {
57474 select('#curtain').style('pointer-events', 'none');
57475 var road = select('.preset-category-road .preset-list-button');
57476 reveal(road.node(), t('intro.lines.road'));
57477 utilBindOnce(road, 'click.intro', roadCategory);
57482 function roadCategory() {
57483 timeout$$1(function() {
57484 var grid = select('.subgrid');
57485 reveal(grid.node(), t('intro.lines.residential'));
57486 utilBindOnce(grid.selectAll(':not(.preset-highway-residential) .preset-list-button'),
57487 'click.intro', retryPreset);
57488 utilBindOnce(grid.selectAll('.preset-highway-residential .preset-list-button'),
57489 'click.intro', roadDetails);
57494 // selected wrong road type
57495 function retryPreset() {
57496 timeout$$1(function() {
57497 var preset = select('.entity-editor-pane .preset-list-button');
57498 reveal(preset.node(), t('intro.lines.wrong_preset'));
57499 utilBindOnce(preset, 'click.intro', presetCategory);
57504 function roadDetails() {
57506 t('intro.lines.describe', { button: icon('#icon-apply', 'pre-text') }));
57507 context.on('exit.intro', function() {
57508 dispatch$$1.call('done');
57514 step.exit = function() {
57515 select(window).on('mousedown.intro', null, true);
57516 select('#curtain').style('pointer-events', 'none');
57517 timeouts.forEach(window.clearTimeout);
57518 context.on('enter.intro', null);
57519 context.on('exit.intro', null);
57520 context.map().on('move.intro', null);
57521 context.history().on('change.intro', null);
57524 return utilRebind(step, dispatch$$1, 'on');
57527 function uiIntroStartEditing(context, reveal) {
57528 var dispatch$$1 = dispatch('done', 'startEditing'),
57533 title: 'intro.startediting.title'
57537 function timeout$$1(f, t$$1) {
57538 timeouts.push(window.setTimeout(f, t$$1));
57542 step.enter = function() {
57543 reveal('.map-control.help-control',
57544 t('intro.startediting.help', { button: icon('#icon-help', 'pre-text') }));
57546 timeout$$1(function() {
57547 reveal('#bar button.save', t('intro.startediting.save'));
57550 timeout$$1(function() {
57551 reveal('#surface');
57554 timeout$$1(function() {
57555 modalSelection = uiModal(context.container());
57557 modalSelection.select('.modal')
57558 .attr('class', 'modal-splash modal col6');
57560 modalSelection.selectAll('.close').remove();
57562 var startbutton = modalSelection.select('.content')
57563 .attr('class', 'fillL')
57565 .attr('class', 'modal-section huge-modal-button')
57566 .on('click', function() {
57567 modalSelection.remove();
57572 .attr('class','illustration');
57576 .text(t('intro.startediting.start'));
57578 dispatch$$1.call('startEditing');
57583 step.exit = function() {
57584 if (modalSelection) { modalSelection.remove(); }
57585 timeouts.forEach(window.clearTimeout);
57589 return utilRebind(step, dispatch$$1, 'on');
57592 var sampleIntros = {
57593 navigation: uiIntroNavigation,
57594 point: uiIntroPoint,
57597 startEditing: uiIntroStartEditing
57601 function uiIntro(context) {
57604 function localizedName(id) {
57606 n2140018997: 'city_hall',
57607 n367813436: 'fire_department',
57608 w203988286: 'memory_isle_park',
57609 w203972937: 'riverwalk_trail',
57610 w203972938: 'riverwalk_trail',
57611 w203972940: 'riverwalk_trail',
57612 w41785752: 'w_michigan_ave',
57613 w134150789: 'w_michigan_ave',
57614 w134150795: 'w_michigan_ave',
57615 w134150800: 'w_michigan_ave',
57616 w134150811: 'w_michigan_ave',
57617 w134150802: 'e_michigan_ave',
57618 w134150836: 'e_michigan_ave',
57619 w41074896: 'e_michigan_ave',
57620 w17965834: 'spring_st',
57621 w203986457: 'scidmore_park',
57622 w203049587: 'petting_zoo',
57623 w17967397: 'n_andrews_st',
57624 w17967315: 's_andrews_st',
57625 w17967326: 'n_constantine_st',
57626 w17966400: 's_constantine_st',
57627 w170848823: 'rocky_river',
57628 w170848824: 'rocky_river',
57629 w170848331: 'rocky_river',
57630 w17967752: 'railroad_dr',
57631 w17965998: 'conrail_rr',
57632 w134150845: 'conrail_rr',
57633 w170989131: 'st_joseph_river',
57634 w143497377: 'n_main_st',
57635 w134150801: 's_main_st',
57636 w134150830: 's_main_st',
57637 w17966462: 's_main_st',
57638 w17967734: 'water_st',
57639 w17964996: 'foster_st',
57640 w170848330: 'portage_river',
57641 w17965351: 'flower_st',
57642 w17965502: 'elm_st',
57643 w17965402: 'walnut_st',
57644 w17964793: 'morris_ave',
57645 w17967444: 'east_st',
57646 w17966984: 'portage_ave'
57649 return features[id] && t('intro.graph.' + features[id]);
57653 var introGraph = {};
57655 for (var key in dataIntroGraph) {
57656 introGraph[key] = osmEntity$$1(dataIntroGraph[key]);
57657 var name = localizedName(key);
57659 introGraph[key].tags.name = name;
57664 function intro(selection$$1) {
57665 context.enter(modeBrowse$$1(context));
57667 // Save current map state
57668 var history = context.history().toJSON(),
57669 hash = window.location.hash,
57670 center = context.map().center(),
57671 zoom$$1 = context.map().zoom(),
57672 background = context.background().baseLayerSource(),
57673 opacity = selectAll('#map .layer-background').style('opacity'),
57674 loadedTiles = context.connection().loadedTiles(),
57675 baseEntities = context.history().graph().base().entities;
57678 context.inIntro(true);
57680 // Load semi-real data used in intro
57681 context.connection().toggle(false).reset();
57682 context.history().reset();
57684 context.history().merge(values(coreGraph$$1().load(introGraph).entities));
57685 context.background().bing();
57687 selectAll('#map .layer-background').style('opacity', 1);
57689 var curtain = d3curtain();
57690 selection$$1.call(curtain);
57693 function reveal(box, text$$1, options) {
57694 options = options || {};
57695 curtain.reveal(box,
57697 options.tooltipClass || '',
57702 var steps = ['navigation', 'point', 'area', 'line', 'startEditing'].map(function(step, i) {
57703 var s = sampleIntros[step](context, reveal)
57704 .on('done', function() {
57705 entered.filter(function(d) {
57706 return d.title === s.title;
57707 }).classed('finished', true);
57708 enter(steps[i + 1]);
57713 steps[steps.length - 1].on('startEditing', function() {
57716 selectAll('#map .layer-background').style('opacity', opacity);
57717 context.connection().toggle(true).reset().loadedTiles(loadedTiles);
57718 context.history().reset().merge(values(baseEntities));
57719 context.background().baseLayerSource(background);
57720 if (history) context.history().fromJSON(history, false);
57721 context.map().centerZoom(center, zoom$$1);
57722 window.location.replace(hash);
57723 context.inIntro(false);
57726 var navwrap = selection$$1
57728 .attr('class', 'intro-nav-wrap fillD');
57730 var buttonwrap = navwrap
57732 .attr('class', 'joined')
57733 .selectAll('button.step');
57735 var entered = buttonwrap
57739 .attr('class', 'step')
57740 .on('click', enter);
57744 .text(function(d) { return t(d.title); });
57748 .attr('class', 'status')
57749 .text(' - ' + t('intro.done'));
57754 function enter(newStep) {
57755 if (step) { step.exit(); }
57757 context.enter(modeBrowse$$1(context));
57762 entered.classed('active', function(d) {
57763 return d.title === step.title;
57773 function uiHelp(context) {
57778 'help.editing_saving',
57787 var docs = docKeys.map(function(key) {
57788 var text$$1 = t(key);
57790 title: text$$1.split('\n')[0].replace('#', '').trim(),
57791 html: marked(text$$1.split('\n').slice(1).join('\n'))
57796 function help(selection$$1) {
57803 function toggle() {
57804 if (event) event.preventDefault();
57805 tooltipBehavior.hide(button);
57806 setVisible(!button.classed('active'));
57810 function setVisible(show) {
57811 if (show !== shown) {
57812 button.classed('active', show);
57816 selection$$1.on('mousedown.help-inside', function() {
57817 return event.stopPropagation();
57819 pane.style('display', 'block')
57820 .style('right', '-500px')
57823 .style('right', '0px');
57825 pane.style('right', '0px')
57828 .style('right', '-500px')
57829 .on('end', function() {
57830 select(this).style('display', 'none');
57832 selection$$1.on('mousedown.help-inside', null);
57838 function clickHelp(d, i) {
57839 pane.property('scrollTop', 0);
57840 doctitle.html(d.title);
57842 body.selectAll('a')
57843 .attr('target', '_blank');
57844 menuItems.classed('selected', function(m) {
57845 return m.title === d.title;
57851 var prevLink = nav.append('a')
57852 .attr('class', 'previous')
57853 .on('click', function() {
57854 clickHelp(docs[i - 1], i - 1);
57856 prevLink.append('span').html('◄ ' + docs[i - 1].title);
57858 if (i < docs.length - 1) {
57859 var nextLink = nav.append('a')
57860 .attr('class', 'next')
57861 .on('click', function() {
57862 clickHelp(docs[i + 1], i + 1);
57864 nextLink.append('span').html(docs[i + 1].title + ' ►');
57869 function clickWalkthrough() {
57870 select(document.body).call(uiIntro(context));
57875 var pane = selection$$1.append('div')
57876 .attr('class', 'help-wrap map-overlay fillL col5 content hide'),
57877 tooltipBehavior = tooltip()
57878 .placement((textDirection === 'rtl') ? 'right' : 'left')
57880 .title(uiTooltipHtml(t('help.title'), key)),
57881 button = selection$$1.append('button')
57882 .attr('tabindex', -1)
57883 .on('click', toggle)
57884 .call(svgIcon('#icon-help', 'light'))
57885 .call(tooltipBehavior),
57889 var toc = pane.append('ul')
57890 .attr('class', 'toc');
57892 var menuItems = toc.selectAll('li')
57897 .html(function(d) { return d.title; })
57898 .on('click', clickHelp);
57901 .attr('class','walkthrough')
57903 .text(t('splash.walkthrough'))
57904 .on('click', clickWalkthrough);
57906 var content = pane.append('div')
57907 .attr('class', 'left-content');
57909 var doctitle = content.append('h2')
57910 .text(t('help.title'));
57912 var body = content.append('div')
57913 .attr('class', 'body');
57915 var nav = content.append('div')
57916 .attr('class', 'nav');
57918 clickHelp(docs[0], 0);
57920 var keybinding = d3keybinding('help')
57928 context.surface().on('mousedown.help-outside', hide);
57929 context.container().on('mousedown.help-outside', hide);
57935 function uiInfo(context) {
57936 var key = uiCmd('⌘I'),
57937 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
57941 function info(selection$$1) {
57943 function radiansToMeters(r) {
57944 // using WGS84 authalic radius (6371007.1809 m)
57945 return r * 6371007.1809;
57948 function steradiansToSqmeters(r) {
57949 // http://gis.stackexchange.com/a/124857/40446
57950 return r / (4 * Math.PI) * 510065621724000;
57954 function toLineString(feature) {
57955 if (feature.type === 'LineString') return feature;
57957 var result = { type: 'LineString', coordinates: [] };
57958 if (feature.type === 'Polygon') {
57959 result.coordinates = feature.coordinates[0];
57960 } else if (feature.type === 'MultiPolygon') {
57961 result.coordinates = feature.coordinates[0][0];
57968 function displayLength(m) {
57969 var d = m * (isImperial ? 3.28084 : 1),
57988 // drop unnecessary precision
57989 p = d > 1000 ? 0 : d > 100 ? 1 : 2;
57991 return String(d.toFixed(p)) + ' ' + unit;
57995 function displayArea(m2) {
57996 var d = m2 * (isImperial ? 10.7639111056 : 1),
57997 d1, d2, p1, p2, unit1, unit2;
58000 if (d >= 6969600) { // > 0.25mi² show mi²
58008 if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres
58014 if (d >= 250000) { // > 0.25km² show km²
58022 if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares
58028 // drop unnecessary precision
58029 p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
58030 p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
58032 return String(d1.toFixed(p1)) + ' ' + unit1 +
58033 (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
58037 function redraw() {
58038 if (isHidden) return;
58040 var resolver = context.graph(),
58041 selected = lodash.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
58042 singular = selected.length === 1 ? selected[0] : null,
58043 extent$$1 = geoExtent$$1(),
58048 .attr('class', 'infobox-heading fillD')
58049 .text(singular || t('infobox.selected', { n: selected.length }));
58051 if (!selected.length) return;
58054 for (var i = 0; i < selected.length; i++) {
58055 entity = context.entity(selected[i]);
58056 extent$$1._extend(entity.extent(resolver));
58058 center = extent$$1.center();
58061 var list = wrap.append('ul');
58063 // multiple features, just display extent center..
58066 .text(t('infobox.center') + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
58070 // single feature, display details..
58071 if (!entity) return;
58072 var geometry = entity.geometry(resolver);
58074 if (geometry === 'line' || geometry === 'area') {
58075 var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
58076 feature = entity.asGeoJSON(resolver),
58077 length = radiansToMeters(d3GeoLength(toLineString(feature))),
58078 lengthLabel = t('infobox.' + (closed ? 'perimeter' : 'length')),
58079 centroid = d3GeoCentroid(feature);
58082 .text(t('infobox.geometry') + ': ' +
58083 (closed ? t('infobox.closed') + ' ' : '') + t('geometry.' + geometry) );
58086 var area$$1 = steradiansToSqmeters(entity.area(resolver));
58088 .text(t('infobox.area') + ': ' + displayArea(area$$1));
58092 .text(lengthLabel + ': ' + displayLength(length));
58095 .text(t('infobox.centroid') + ': ' + centroid[0].toFixed(5) + ', ' + centroid[1].toFixed(5));
58098 var toggle = isImperial ? 'imperial' : 'metric';
58100 .text(t('infobox.' + toggle))
58102 .attr('class', 'button')
58103 .on('click', function() {
58104 event.preventDefault();
58105 isImperial = !isImperial;
58110 var centerLabel = t('infobox.' + (entity.type === 'node' ? 'location' : 'center'));
58113 .text(t('infobox.geometry') + ': ' + t('geometry.' + geometry));
58116 .text(centerLabel + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
58121 function toggle() {
58123 event.preventDefault();
58126 isHidden = !isHidden;
58130 .style('display', 'block')
58131 .style('opacity', 1)
58134 .style('opacity', 0)
58135 .on('end', function() {
58136 select(this).style('display', 'none');
58140 .style('display', 'block')
58141 .style('opacity', 0)
58144 .style('opacity', 1)
58145 .on('end', function() {
58152 var wrap = selection$$1.selectAll('.infobox')
58155 wrap = wrap.enter()
58157 .attr('class', 'infobox fillD2')
58158 .style('display', (isHidden ? 'none' : 'block'))
58162 .on('drawn.info', redraw);
58166 var keybinding = d3keybinding('info')
58176 function uiMapData(context) {
58178 features = context.features().keys(),
58179 layers = context.layers(),
58180 fills = ['wireframe', 'partial', 'full'],
58181 fillDefault = context.storage('area-fill') || 'partial',
58182 fillSelected = fillDefault;
58185 function map_data(selection$$1) {
58187 function showsFeature(d) {
58188 return context.features().enabled(d);
58192 function autoHiddenFeature(d) {
58193 return context.features().autoHidden(d);
58197 function clickFeature(d) {
58198 context.features().toggle(d);
58203 function showsFill(d) {
58204 return fillSelected === d;
58208 function setFill(d) {
58209 lodash.each(fills, function(opt) {
58210 context.surface().classed('fill-' + opt, Boolean(opt === d));
58214 if (d !== 'wireframe') {
58216 context.storage('area-fill', d);
58222 function showsLayer(which) {
58223 var layer = layers.layer(which);
58225 return layer.enabled();
58231 function setLayer(which, enabled) {
58232 var layer = layers.layer(which);
58234 layer.enabled(enabled);
58240 function toggleLayer(which) {
58241 setLayer(which, !showsLayer(which));
58245 function clickGpx() {
58246 toggleLayer('gpx');
58250 function clickMapillaryImages() {
58251 toggleLayer('mapillary-images');
58252 if (!showsLayer('mapillary-images')) {
58253 setLayer('mapillary-signs', false);
58258 function clickMapillarySigns() {
58259 toggleLayer('mapillary-signs');
58263 function drawMapillaryItems(selection$$1) {
58264 var mapillaryImages = layers.layer('mapillary-images'),
58265 mapillarySigns = layers.layer('mapillary-signs'),
58266 supportsMapillaryImages = mapillaryImages && mapillaryImages.supported(),
58267 supportsMapillarySigns = mapillarySigns && mapillarySigns.supported(),
58268 showsMapillaryImages = supportsMapillaryImages && mapillaryImages.enabled(),
58269 showsMapillarySigns = supportsMapillarySigns && mapillarySigns.enabled();
58271 var mapillaryList = selection$$1
58272 .selectAll('.layer-list-mapillary')
58275 mapillaryList = mapillaryList.enter()
58277 .attr('class', 'layer-list layer-list-mapillary')
58278 .merge(mapillaryList);
58281 var mapillaryImageLayerItem = mapillaryList
58282 .selectAll('.list-item-mapillary-images')
58283 .data(supportsMapillaryImages ? [0] : []);
58285 mapillaryImageLayerItem.exit()
58288 var enterImages = mapillaryImageLayerItem.enter()
58290 .attr('class', 'list-item-mapillary-images');
58292 var labelImages = enterImages
58295 .title(t('mapillary_images.tooltip'))
58296 .placement('top'));
58300 .attr('type', 'checkbox')
58301 .on('change', clickMapillaryImages);
58305 .text(t('mapillary_images.title'));
58308 var mapillarySignLayerItem = mapillaryList
58309 .selectAll('.list-item-mapillary-signs')
58310 .data(supportsMapillarySigns ? [0] : []);
58312 mapillarySignLayerItem.exit()
58315 var enterSigns = mapillarySignLayerItem.enter()
58317 .attr('class', 'list-item-mapillary-signs');
58319 var labelSigns = enterSigns
58322 .title(t('mapillary_signs.tooltip'))
58323 .placement('top'));
58327 .attr('type', 'checkbox')
58328 .on('change', clickMapillarySigns);
58332 .text(t('mapillary_signs.title'));
58336 mapillaryImageLayerItem = mapillaryImageLayerItem
58337 .merge(enterImages);
58339 mapillaryImageLayerItem
58340 .classed('active', showsMapillaryImages)
58341 .selectAll('input')
58342 .property('checked', showsMapillaryImages);
58345 mapillarySignLayerItem = mapillarySignLayerItem
58346 .merge(enterSigns);
58348 mapillarySignLayerItem
58349 .classed('active', showsMapillarySigns)
58350 .selectAll('input')
58351 .property('disabled', !showsMapillaryImages)
58352 .property('checked', showsMapillarySigns);
58354 mapillarySignLayerItem
58355 .selectAll('label')
58356 .classed('deemphasize', !showsMapillaryImages);
58360 function drawGpxItem(selection$$1) {
58361 var gpx = layers.layer('gpx'),
58362 hasGpx = gpx && gpx.hasGpx(),
58363 showsGpx = hasGpx && gpx.enabled();
58365 var gpxLayerItem = selection$$1
58366 .selectAll('.layer-list-gpx')
58367 .data(gpx ? [0] : []);
58370 gpxLayerItem.exit()
58374 var enter = gpxLayerItem.enter()
58376 .attr('class', 'layer-list layer-list-gpx')
58378 .classed('list-item-gpx', true);
58382 .attr('class', 'list-item-gpx-extent')
58384 .title(t('gpx.zoom'))
58385 .placement((textDirection === 'rtl') ? 'right' : 'left'))
58386 .on('click', function() {
58387 event.preventDefault();
58388 event.stopPropagation();
58391 .call(svgIcon('#icon-search'));
58395 .attr('class', 'list-item-gpx-browse')
58397 .title(t('gpx.browse'))
58398 .placement((textDirection === 'rtl') ? 'right' : 'left'))
58399 .on('click', function() {
58400 select(document.createElement('input'))
58401 .attr('type', 'file')
58402 .on('change', function() {
58403 gpx.files(event.target.files);
58407 .call(svgIcon('#icon-geolocate'));
58409 var labelGpx = enter
58411 .call(tooltip().title(t('gpx.drag_drop')).placement('top'));
58415 .attr('type', 'checkbox')
58416 .on('change', clickGpx);
58420 .text(t('gpx.local_layer'));
58424 gpxLayerItem = gpxLayerItem
58428 .classed('active', showsGpx)
58429 .selectAll('input')
58430 .property('disabled', !hasGpx)
58431 .property('checked', showsGpx);
58434 .selectAll('label')
58435 .classed('deemphasize', !hasGpx);
58439 function drawList(selection$$1, data, type, name, change, active$$1) {
58440 var items = selection$$1.selectAll('li')
58448 var enter = items.enter()
58450 .attr('class', 'layer')
58453 .title(function(d) {
58454 var tip = t(name + '.' + d + '.tooltip'),
58455 key = (d === 'wireframe' ? 'W' : null);
58457 if (name === 'feature' && autoHiddenFeature(d)) {
58458 tip += '<div>' + t('map_data.autohidden') + '</div>';
58460 return uiTooltipHtml(tip, key);
58470 .attr('type', type)
58471 .attr('name', name)
58472 .on('change', change);
58476 .text(function(d) { return t(name + '.' + d + '.description'); });
58483 .classed('active', active$$1)
58484 .selectAll('input')
58485 .property('checked', active$$1)
58486 .property('indeterminate', function(d) {
58487 return (name === 'feature' && autoHiddenFeature(d));
58492 function update() {
58493 dataLayerContainer.call(drawMapillaryItems);
58494 dataLayerContainer.call(drawGpxItem);
58496 fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);
58497 featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
58501 function hidePanel() {
58506 function togglePanel() {
58507 if (event) event.preventDefault();
58508 tooltipBehavior.hide(button);
58509 setVisible(!button.classed('active'));
58513 function toggleWireframe() {
58515 event.preventDefault();
58516 event.stopPropagation();
58518 setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
58519 context.map().pan([0,0]); // trigger a redraw
58523 function setVisible(show) {
58524 if (show !== shown) {
58525 button.classed('active', show);
58530 selection$$1.on('mousedown.map_data-inside', function() {
58531 return event.stopPropagation();
58533 content.style('display', 'block')
58534 .style('right', '-300px')
58537 .style('right', '0px');
58539 content.style('display', 'block')
58540 .style('right', '0px')
58543 .style('right', '-300px')
58544 .on('end', function() {
58545 select(this).style('display', 'none');
58547 selection$$1.on('mousedown.map_data-inside', null);
58553 var content = selection$$1
58555 .attr('class', 'fillL map-overlay col3 content hide'),
58556 tooltipBehavior = tooltip()
58557 .placement((textDirection === 'rtl') ? 'right' : 'left')
58559 .title(uiTooltipHtml(t('map_data.description'), key)),
58560 button = selection$$1
58562 .attr('tabindex', -1)
58563 .on('click', togglePanel)
58564 .call(svgIcon('#icon-data', 'light'))
58565 .call(tooltipBehavior),
58570 .text(t('map_data.title'));
58576 .text(t('map_data.data_layers'))
58578 .classed('hide-toggle', true)
58579 .classed('expanded', true)
58580 .on('click', function() {
58581 var exp = select(this).classed('expanded');
58582 dataLayerContainer.style('display', exp ? 'none' : 'block');
58583 select(this).classed('expanded', !exp);
58584 event.preventDefault();
58587 var dataLayerContainer = content
58589 .attr('class', 'data-data-layers')
58590 .style('display', 'block');
58596 .text(t('map_data.fill_area'))
58598 .classed('hide-toggle', true)
58599 .classed('expanded', false)
58600 .on('click', function() {
58601 var exp = select(this).classed('expanded');
58602 fillContainer.style('display', exp ? 'none' : 'block');
58603 select(this).classed('expanded', !exp);
58604 event.preventDefault();
58607 var fillContainer = content
58609 .attr('class', 'data-area-fills')
58610 .style('display', 'none');
58612 var fillList = fillContainer
58614 .attr('class', 'layer-list layer-fill-list');
58620 .text(t('map_data.map_features'))
58622 .classed('hide-toggle', true)
58623 .classed('expanded', false)
58624 .on('click', function() {
58625 var exp = select(this).classed('expanded');
58626 featureContainer.style('display', exp ? 'none' : 'block');
58627 select(this).classed('expanded', !exp);
58628 event.preventDefault();
58631 var featureContainer = content
58633 .attr('class', 'data-feature-filters')
58634 .style('display', 'none');
58636 var featureList = featureContainer
58638 .attr('class', 'layer-list layer-feature-list');
58642 .on('change.map_data-update', update);
58644 setFill(fillDefault);
58646 var keybinding = d3keybinding('features')
58647 .on(key, togglePanel)
58648 .on('W', toggleWireframe)
58649 .on('B', hidePanel)
58650 .on('H', hidePanel);
58655 context.surface().on('mousedown.map_data-outside', hidePanel);
58656 context.container().on('mousedown.map_data-outside', hidePanel);
58663 function uiModes(context) {
58665 modeAddPoint$$1(context),
58666 modeAddLine$$1(context),
58667 modeAddArea$$1(context)
58671 function editable() {
58672 return context.editable() && context.mode().id !== 'save';
58676 return function(selection$$1) {
58677 var buttons = selection$$1.selectAll('button.add-button')
58680 buttons = buttons.enter()
58682 .attr('tabindex', -1)
58683 .attr('class', function(mode) { return mode.id + ' add-button col4'; })
58684 .on('click.mode-buttons', function(mode) {
58685 if (mode.id === context.mode().id) {
58686 context.enter(modeBrowse$$1(context));
58688 context.enter(mode);
58692 .placement('bottom')
58694 .title(function(mode) {
58695 return uiTooltipHtml(mode.description, mode.key);
58700 .on('move.modes', lodash.debounce(update, 500));
58703 .on('enter.modes', update);
58706 .each(function(d) {
58708 .call(svgIcon('#icon-' + d.button, 'pre-text'));
58713 .attr('class', 'label')
58714 .text(function(mode) { return mode.title; });
58717 .on('enter.editor', function(entered) {
58718 selection$$1.selectAll('button.add-button')
58719 .classed('active', function(mode) { return entered.button === mode.button; });
58720 context.container()
58721 .classed('mode-' + entered.id, true);
58725 .on('exit.editor', function(exited) {
58726 context.container()
58727 .classed('mode-' + exited.id, false);
58730 var keybinding = d3keybinding('mode-buttons');
58732 modes.forEach(function(m) {
58733 keybinding.on(m.key, function() {
58734 if (editable()) context.enter(m);
58742 function update() {
58743 selection$$1.selectAll('button.add-button')
58744 .property('disabled', !editable());
58749 function uiRestore(context) {
58751 return function(selection) {
58752 if (!context.history().lock() || !context.history().restorableChanges())
58755 var modalSelection = uiModal(selection, true);
58757 modalSelection.select('.modal')
58758 .attr('class', 'modal fillL col6');
58760 var introModal = modalSelection.select('.content');
58763 .attr('class','cf');
58767 .attr('class', 'modal-section')
58769 .text(t('restore.heading'));
58773 .attr('class','modal-section')
58775 .text(t('restore.description'));
58777 var buttonWrap = introModal
58779 .attr('class', 'modal-actions cf');
58781 var restore = buttonWrap
58783 .attr('class', 'restore col6')
58784 .text(t('restore.restore'))
58785 .on('click', function() {
58786 context.history().restore();
58787 modalSelection.remove();
58792 .attr('class', 'reset col6')
58793 .text(t('restore.reset'))
58794 .on('click', function() {
58795 context.history().clearSaved();
58796 modalSelection.remove();
58799 restore.node().focus();
58803 function uiSave(context) {
58804 var history = context.history(),
58808 function saving() {
58809 return context.mode().id === 'save';
58814 event.preventDefault();
58815 if (!context.inIntro() && !saving() && history.hasChanges()) {
58816 context.enter(modeSave$$1(context));
58821 function getBackground(numChanges) {
58823 if (numChanges === 0) {
58825 } else if (numChanges <= 50) {
58826 step = numChanges / 50;
58827 return interpolateRgb('#fff', '#ff8')(step); // white -> yellow
58829 step = Math.min((numChanges - 50) / 50, 1.0);
58830 return interpolateRgb('#ff8', '#f88')(step); // yellow -> red
58835 return function(selection$$1) {
58836 var tooltipBehavior = tooltip()
58837 .placement('bottom')
58839 .title(uiTooltipHtml(t('save.no_changes'), key));
58841 var button = selection$$1
58843 .attr('class', 'save col12 disabled')
58844 .attr('tabindex', -1)
58846 .call(tooltipBehavior);
58850 .attr('class', 'label')
58851 .text(t('save.title'));
58855 .attr('class', 'count')
58858 var keybinding = d3keybinding('undo-redo')
58859 .on(key, save, true);
58864 var numChanges = 0;
58867 .on('change.save', function() {
58868 var _ = history.difference().summary().length;
58869 if (_ === numChanges)
58873 tooltipBehavior.title(uiTooltipHtml(
58874 t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key));
58876 var background = getBackground(numChanges);
58879 .classed('disabled', numChanges === 0)
58880 .classed('has-count', numChanges > 0)
58881 .style('background', background);
58883 button.select('span.count')
58885 .style('background', background)
58886 .style('border-color', background);
58890 .on('enter.save', function() {
58891 button.property('disabled', saving());
58892 if (saving()) button.call(tooltipBehavior.hide);
58897 function uiScale(context) {
58898 var projection = context.projection,
58899 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
58904 function scaleDefs(loc1, loc2) {
58905 var lat = (loc2[1] + loc1[1]) / 2,
58906 conversion = (isImperial ? 3.28084 : 1),
58907 dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
58908 scale = { dist: 0, px: 0, text: '' },
58909 buckets, i, val, dLon;
58912 buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
58914 buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
58917 // determine a user-friendly endpoint for the scale
58918 for (i = 0; i < buckets.length; i++) {
58921 scale.dist = Math.floor(dist / val) * val;
58924 scale.dist = +dist.toFixed(2);
58928 dLon = geoMetersToLon(scale.dist / conversion, lat);
58929 scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
58932 if (scale.dist >= 5280) {
58933 scale.dist /= 5280;
58934 scale.text = String(scale.dist) + ' mi';
58936 scale.text = String(scale.dist) + ' ft';
58939 if (scale.dist >= 1000) {
58940 scale.dist /= 1000;
58941 scale.text = String(scale.dist) + ' km';
58943 scale.text = String(scale.dist) + ' m';
58951 function update(selection) {
58952 // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
58953 var dims = context.map().dimensions(),
58954 loc1 = projection.invert([0, dims[1]]),
58955 loc2 = projection.invert([maxLength, dims[1]]),
58956 scale = scaleDefs(loc1, loc2);
58958 selection.select('#scalepath')
58959 .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
58961 selection.select('#scaletext')
58962 .attr('x', scale.px + 8)
58963 .attr('y', tickHeight)
58968 return function(selection) {
58969 function switchUnits() {
58970 isImperial = !isImperial;
58971 selection.call(update);
58974 var g = selection.append('svg')
58975 .attr('id', 'scale')
58976 .on('click', switchUnits)
58978 .attr('transform', 'translate(10,11)');
58980 g.append('path').attr('id', 'scalepath');
58981 g.append('text').attr('id', 'scaletext');
58983 selection.call(update);
58985 context.map().on('move.scale', function() {
58992 function search(x, dims, r) {
58993 if (!dims) dims = 'NSEW';
58994 if (typeof x !== 'string') return { val: null, regex: r };
58995 r = r || /[\s\,]*([\-|\—|\―]?[0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/gi;
58997 if (!m) return { val: null, regex: r };
58998 else if (m[4] && dims.indexOf(m[4]) === -1) return { val: null, regex: r };
59000 val: (((m[1]) ? parseFloat(m[1]) : 0) +
59001 ((m[2] ? parseFloat(m[2]) / 60 : 0)) +
59002 ((m[3] ? parseFloat(m[3]) / 3600 : 0))) *
59003 ((m[4] && m[4] === 'S' || m[4] === 'W') ? -1 : 1),
59010 function pair(x, dims) {
59012 var one = search(x, dims);
59013 if (one.val === null) return null;
59014 var two = search(x, dims, one.regex);
59015 if (two.val === null) return null;
59016 // null if one/two are not contiguous.
59017 if (one.raw + two.raw !== x) return null;
59019 return swapdim(one.val, two.val, one.dim);
59021 return [one.val, two.val];
59025 function swapdim(a, b, dim) {
59026 if (dim === 'N' || dim === 'S') return [a, b];
59027 if (dim === 'W' || dim === 'E') return [b, a];
59030 function uiFeatureList(context) {
59031 var geocodeResults;
59034 function featureList(selection$$1) {
59035 var header = selection$$1.append('div')
59036 .attr('class', 'header fillL cf');
59038 header.append('h3')
59039 .text(t('inspector.feature_list'));
59041 var searchWrap = selection$$1.append('div')
59042 .attr('class', 'search-header');
59044 var search = searchWrap.append('input')
59045 .attr('placeholder', t('inspector.search'))
59046 .attr('type', 'search')
59047 .on('keypress', keypress)
59048 .on('input', inputevent);
59051 .call(svgIcon('#icon-search', 'pre-text'));
59053 var listWrap = selection$$1.append('div')
59054 .attr('class', 'inspector-body');
59056 var list = listWrap.append('div')
59057 .attr('class', 'feature-list cf');
59060 .on('exit.feature-list', clearSearch);
59062 .on('drawn.feature-list', mapDrawn);
59065 function keypress() {
59066 var q = search.property('value'),
59067 items = list.selectAll('.feature-list-item');
59068 if (event.keyCode === 13 && q.length && items.size()) {
59069 click(items.datum());
59074 function inputevent() {
59075 geocodeResults = undefined;
59080 function clearSearch() {
59081 search.property('value', '');
59086 function mapDrawn(e) {
59093 function features() {
59096 graph = context.graph(),
59097 q = search.property('value').toLowerCase();
59099 if (!q) return result;
59101 var idMatch = q.match(/^([nwr])([0-9]+)$/);
59106 geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
59107 type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
59112 var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
59114 if (locationMatch) {
59115 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
59119 type: t('inspector.location'),
59120 name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6),
59125 function addEntity(entity) {
59126 if (entity.id in entities || result.length > 200)
59129 entities[entity.id] = true;
59131 var name = utilDisplayName(entity) || '';
59132 if (name.toLowerCase().indexOf(q) >= 0) {
59133 var matched = context.presets().match(entity, graph),
59134 type = (matched && matched.name()) || utilDisplayType(entity.id);
59138 geometry: context.geometry(entity.id),
59144 graph.parentRelations(entity).forEach(function(parent) {
59149 var visible = context.surface().selectAll('.point, .line, .area').nodes();
59150 for (var i = 0; i < visible.length && result.length <= 200; i++) {
59151 addEntity(visible[i].__data__);
59154 (geocodeResults || []).forEach(function(d) {
59155 // https://github.com/openstreetmap/iD/issues/1890
59156 if (d.osm_type && d.osm_id) {
59158 id: osmEntity$$1.id.fromOSM(d.osm_type, d.osm_id),
59159 geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
59160 type: d.type !== 'yes' ? (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' ')
59161 : (d.class.charAt(0).toUpperCase() + d.class.slice(1)).replace('_', ' '),
59162 name: d.display_name,
59163 extent: new geoExtent$$1(
59164 [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
59165 [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
59174 function drawList() {
59175 var value = search.property('value'),
59176 results = features();
59178 list.classed('filtered', value.length);
59180 var noResultsWorldwide = geocodeResults && geocodeResults.length === 0;
59182 var resultsIndicator = list.selectAll('.no-results-item')
59184 .enter().append('button')
59185 .property('disabled', true)
59186 .attr('class', 'no-results-item')
59187 .call(svgIcon('#icon-alert', 'pre-text'));
59189 resultsIndicator.append('span')
59190 .attr('class', 'entity-name');
59192 list.selectAll('.no-results-item .entity-name')
59193 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
59195 list.selectAll('.geocode-item')
59197 .enter().append('button')
59198 .attr('class', 'geocode-item')
59199 .on('click', geocode)
59201 .attr('class', 'label')
59203 .attr('class', 'entity-name')
59204 .text(t('geocoder.search'));
59206 list.selectAll('.no-results-item')
59207 .style('display', (value.length && !results.length) ? 'block' : 'none');
59209 list.selectAll('.geocode-item')
59210 .style('display', (value && geocodeResults === undefined) ? 'block' : 'none');
59212 list.selectAll('.feature-list-item')
59216 var items = list.selectAll('.feature-list-item')
59217 .data(results, function(d) { return d.id; });
59219 var enter = items.enter()
59220 .insert('button', '.geocode-item')
59221 .attr('class', 'feature-list-item')
59222 .on('mouseover', mouseover)
59223 .on('mouseout', mouseout)
59224 .on('click', click);
59228 .attr('class', 'label');
59230 label.each(function(d) {
59232 .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
59235 label.append('span')
59236 .attr('class', 'entity-type')
59237 .text(function(d) { return d.type; });
59239 label.append('span')
59240 .attr('class', 'entity-name')
59241 .text(function(d) { return d.name; });
59243 enter.style('opacity', 0)
59245 .style('opacity', 1);
59254 function mouseover(d) {
59255 if (d.id === -1) return;
59257 context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
59258 .classed('hover', true);
59262 function mouseout() {
59263 context.surface().selectAll('.hover')
59264 .classed('hover', false);
59268 function click(d) {
59269 event.preventDefault();
59271 context.map().centerZoom([d.location[1], d.location[0]], 20);
59273 else if (d.entity) {
59274 if (d.entity.type === 'node') {
59275 context.map().center(d.entity.loc);
59276 } else if (d.entity.type === 'way') {
59277 var center = context.projection(context.map().center()),
59278 edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
59279 context.map().center(edge.loc);
59281 context.enter(modeSelect(context, [d.entity.id]).suppressMenu(true));
59283 context.zoomToEntity(d.id);
59288 function geocode() {
59289 var searchVal = encodeURIComponent(search.property('value'));
59290 json('https://nominatim.openstreetmap.org/search/' + searchVal + '?limit=10&format=json', function(err, resp) {
59291 geocodeResults = resp || [];
59298 return featureList;
59301 function uiPresetIcon() {
59302 var preset, geometry;
59305 function presetIcon(selection$$1) {
59306 selection$$1.each(render);
59310 function render() {
59311 var selection$$1 = select(this),
59312 p = preset.apply(this, arguments),
59313 geom = geometry.apply(this, arguments),
59314 picon = p.icon || (geom === 'line' ? 'other-line' : 'marker-stroked'),
59315 isMaki = dataFeatureIcons.hasOwnProperty(picon + '-24');
59317 if (picon === 'dentist') {
59318 isMaki = true; // workaround for dentist icon missing in `maki-sprite.json`
59321 function tag_classes(p) {
59323 for (var i in p.tags) {
59325 if (p.tags[i] !== '*') {
59326 s += ' tag-' + i + '-' + p.tags[i];
59332 var fill = selection$$1.selectAll('.preset-icon-fill')
59335 fill = fill.enter()
59340 .attr('class', function() {
59341 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
59344 var frame = selection$$1.selectAll('.preset-icon-frame')
59347 frame = frame.enter()
59349 .call(svgIcon('#preset-icon-frame'))
59353 .attr('class', function() {
59354 return 'preset-icon-frame ' + (geom === 'area' ? '' : 'hide');
59358 var icon = selection$$1.selectAll('.preset-icon')
59361 icon = icon.enter()
59363 .attr('class', 'preset-icon')
59368 .attr('class', 'preset-icon preset-icon-' + (isMaki ? '32' : (geom === 'area' ? '44' : '60')));
59370 icon.selectAll('svg')
59371 .attr('class', function() {
59372 return 'icon ' + picon + tag_classes(p);
59375 icon.selectAll('use') // workaround: maki parking-24 broken?
59376 .attr('href', '#' + picon + (isMaki ? (picon === 'parking' ? '-18' : '-24') : ''));
59380 presetIcon.preset = function(_) {
59381 if (!arguments.length) return preset;
59382 preset = utilFunctor(_);
59387 presetIcon.geometry = function(_) {
59388 if (!arguments.length) return geometry;
59389 geometry = utilFunctor(_);
59396 function d3combobox() {
59397 var event$$1 = dispatch('accept'),
59401 caseSensitive = false;
59403 var fetcher = function(val, cb) {
59404 cb(data.filter(function(d) {
59408 .indexOf(val.toLowerCase()) !== -1;
59412 var combobox = function(input, attachTo) {
59414 container = select(document.body)
59415 .selectAll('div.combobox')
59416 .filter(function(d) { return d === input.node(); }),
59417 shown = !container.empty();
59420 .classed('combobox-input', true)
59421 .on('focus.typeahead', focus)
59422 .on('blur.typeahead', blur)
59423 .on('keydown.typeahead', keydown)
59424 .on('keyup.typeahead', keyup)
59425 .on('input.typeahead', change)
59427 var parent = this.parentNode,
59428 sibling = this.nextSibling;
59430 var caret = select(parent).selectAll('.combobox-caret')
59431 .filter(function(d) { return d === input.node(); })
59432 .data([input.node()]);
59434 caret = caret.enter()
59435 .insert('div', function() { return sibling; })
59436 .attr('class', 'combobox-caret')
59440 .on('mousedown', function () {
59441 // prevent the form element from blurring. it blurs
59443 event.stopPropagation();
59444 event.preventDefault();
59446 input.node().focus();
59455 fetch(value(), render);
59459 window.setTimeout(hide, 150);
59464 container = select(document.body)
59465 .insert('div', ':first-child')
59466 .datum(input.node())
59467 .attr('class', 'combobox')
59468 .style('position', 'absolute')
59469 .style('display', 'block')
59470 .style('left', '0px')
59471 .on('mousedown', function () {
59472 // prevent moving focus out of the text field
59473 event.preventDefault();
59476 select(document.body)
59477 .on('scroll.combobox', render, true);
59486 container.remove();
59488 select(document.body)
59489 .on('scroll.combobox', null);
59495 function keydown() {
59496 switch (event.keyCode) {
59497 // backspace, delete
59500 input.on('input.typeahead', function() {
59503 var start = input.property('selectionStart');
59504 input.node().setSelectionRange(start, start);
59505 input.on('input.typeahead', change);
59510 container.selectAll('a.selected').each(function (d) {
59511 event$$1.call('accept', this, d);
59517 event.preventDefault();
59522 event.preventDefault();
59527 event.preventDefault();
59530 event.stopPropagation();
59534 switch (event.keyCode) {
59541 container.selectAll('a.selected').each(function (d) {
59542 event$$1.call('accept', this, d);
59549 function change() {
59550 fetch(value(), function() {
59551 if (input.property('selectionEnd') === input.property('value').length) {
59558 function nav(dir) {
59559 if (!suggestions.length) return;
59560 idx = Math.max(Math.min(idx + dir, suggestions.length - 1), 0);
59561 input.property('value', suggestions[idx].value);
59567 var value = input.property('value'),
59568 start = input.property('selectionStart'),
59569 end = input.property('selectionEnd');
59571 if (start && end) {
59572 value = value.substring(0, start);
59578 function fetch(v, cb) {
59579 fetcher.call(input, v, function(_) {
59585 function autocomplete() {
59586 var v = caseSensitive ? value() : value().toLowerCase();
59590 for (var i = 0; i < suggestions.length; i++) {
59591 var suggestion = suggestions[i].value,
59592 compare = caseSensitive ? suggestion : suggestion.toLowerCase();
59594 if (compare.indexOf(v) === 0) {
59596 input.property('value', suggestion);
59597 input.node().setSelectionRange(v.length, suggestion.length);
59603 function render() {
59604 if (suggestions.length >= minItems && document.activeElement === input.node()) {
59611 var options = container
59612 .selectAll('a.combobox-option')
59613 .data(suggestions, function(d) { return d.value; });
59620 .attr('class', 'combobox-option')
59621 .text(function(d) { return d.value; })
59623 .attr('title', function(d) { return d.title; })
59624 .classed('selected', function(d, i) { return i === idx; })
59625 .on('mouseover', select$$1)
59626 .on('click', accept)
59630 var node = attachTo ? attachTo.node() : input.node(),
59631 rect = node.getBoundingClientRect();
59634 .style('left', rect.left + 'px')
59635 .style('width', rect.width + 'px')
59636 .style('top', rect.height + rect.top + 'px');
59639 function select$$1(d, i) {
59644 function ensureVisible() {
59645 var node = container.selectAll('a.selected').node();
59646 if (node) node.scrollIntoView();
59649 function accept(d) {
59650 if (!shown) return;
59652 .property('value', d.value)
59653 .dispatch('change');
59654 event$$1.call('accept', this, d);
59659 combobox.fetcher = function(_) {
59660 if (!arguments.length) return fetcher;
59665 combobox.data = function(_) {
59666 if (!arguments.length) return data;
59671 combobox.minItems = function(_) {
59672 if (!arguments.length) return minItems;
59677 combobox.caseSensitive = function(_) {
59678 if (!arguments.length) return caseSensitive;
59683 return utilRebind(combobox, event$$1, 'on');
59687 d3combobox.off = function(input) {
59689 .on('focus.typeahead', null)
59690 .on('blur.typeahead', null)
59691 .on('keydown.typeahead', null)
59692 .on('keyup.typeahead', null)
59693 .on('input.typeahead', null)
59695 select(this.parentNode).selectAll('.combobox-caret')
59696 .filter(function(d) { return d === input.node(); })
59697 .on('mousedown', null);
59700 select(document.body)
59701 .on('scroll.combobox', null);
59704 function uiDisclosure() {
59705 var dispatch$$1 = dispatch('toggled'),
59708 content = function () {};
59711 var disclosure = function(selection$$1) {
59712 var hideToggle = selection$$1.selectAll('.hide-toggle')
59715 hideToggle = hideToggle.enter()
59718 .attr('class', 'hide-toggle')
59719 .merge(hideToggle);
59723 .on('click', toggle)
59724 .classed('expanded', expanded);
59727 var wrap = selection$$1.selectAll('div')
59730 wrap = wrap.enter()
59735 .classed('hide', !expanded)
59739 function toggle() {
59740 expanded = !expanded;
59741 hideToggle.classed('expanded', expanded);
59742 wrap.call(uiToggle(expanded));
59743 dispatch$$1.call('toggled', this, expanded);
59748 disclosure.title = function(_) {
59749 if (!arguments.length) return title;
59755 disclosure.expanded = function(_) {
59756 if (!arguments.length) return expanded;
59762 disclosure.content = function(_) {
59763 if (!arguments.length) return content;
59769 return utilRebind(disclosure, dispatch$$1, 'on');
59772 function uiRawMemberEditor(context) {
59774 taginfo = services.taginfo;
59777 function selectMember(d) {
59778 event.preventDefault();
59779 context.enter(modeSelect(context, [d.id]));
59783 function changeRole(d) {
59784 var role = select(this).property('value');
59785 var member = { id: d.id, type: d.type, role: role };
59787 actionChangeMember(d.relation.id, member, d.index),
59788 t('operations.change_role.annotation')
59793 function deleteMember(d) {
59795 actionDeleteMember(d.relation.id, d.index),
59796 t('operations.delete_member.annotation')
59799 if (!context.hasEntity(d.relation.id)) {
59800 context.enter(modeBrowse$$1(context));
59805 function rawMemberEditor(selection$$1) {
59806 var entity = context.entity(id),
59809 entity.members.forEach(function(member, index) {
59816 member: context.hasEntity(member.id)
59820 selection$$1.call(uiDisclosure()
59821 .title(t('inspector.all_members') + ' (' + memberships.length + ')')
59823 .on('toggled', toggled)
59828 function toggled(expanded) {
59830 selection$$1.node().parentNode.scrollTop += 200;
59835 function content(wrap) {
59836 var list = wrap.selectAll('.member-list')
59839 list = list.enter()
59841 .attr('class', 'member-list')
59845 var items = list.selectAll('li')
59846 .data(memberships, function(d) {
59847 return osmEntity$$1.key(d.relation) + ',' + d.index + ',' +
59848 (d.member ? osmEntity$$1.key(d.member) : 'incomplete');
59855 var enter = items.enter()
59857 .attr('class', 'member-row form-field')
59858 .classed('member-incomplete', function(d) { return !d.member; });
59861 .each(function(d) {
59863 var label = select(this).append('label')
59864 .attr('class', 'form-label')
59867 .on('click', selectMember);
59869 label.append('span')
59870 .attr('class', 'member-entity-type')
59871 .text(function(d) {
59872 var matched = context.presets().match(d.member, context.graph());
59873 return (matched && matched.name()) || utilDisplayType(d.member.id);
59876 label.append('span')
59877 .attr('class', 'member-entity-name')
59878 .text(function(d) { return utilDisplayName(d.member); });
59881 select(this).append('label')
59882 .attr('class', 'form-label')
59883 .text(t('inspector.incomplete', { id: d.id }));
59889 .attr('class', 'member-role')
59890 .property('type', 'text')
59891 .attr('maxlength', 255)
59892 .attr('placeholder', t('inspector.role'))
59893 .property('value', function(d) { return d.role; })
59894 .on('change', changeRole);
59898 .attr('tabindex', -1)
59899 .attr('class', 'remove button-input-action member-delete minor')
59900 .on('click', deleteMember)
59901 .call(svgIcon('#operation-delete'));
59904 enter.each(bindTypeahead);
59908 function bindTypeahead(d) {
59909 var row = select(this),
59910 role = row.selectAll('input.member-role');
59912 function sort(value, data) {
59913 var sameletter = [],
59915 for (var i = 0; i < data.length; i++) {
59916 if (data[i].value.substring(0, value.length) === value) {
59917 sameletter.push(data[i]);
59919 other.push(data[i]);
59922 return sameletter.concat(other);
59925 role.call(d3combobox()
59926 .fetcher(function(role, callback) {
59927 var rtype = entity.tags.type;
59930 rtype: rtype || '',
59931 geometry: context.geometry(d.member.id),
59933 }, function(err, data) {
59934 if (!err) callback(sort(role, data));
59940 function unbind() {
59941 var row = select(this);
59943 row.selectAll('input.member-role')
59944 .call(d3combobox.off);
59950 rawMemberEditor.entityID = function(_) {
59951 if (!arguments.length) return id;
59953 return rawMemberEditor;
59957 return rawMemberEditor;
59960 function uiRawMembershipEditor(context) {
59961 var taginfo = services.taginfo,
59965 function selectRelation(d) {
59966 event.preventDefault();
59967 context.enter(modeSelect(context, [d.relation.id]));
59971 function changeRole(d) {
59972 var role = select(this).property('value');
59974 actionChangeMember(d.relation.id, lodash.extend({}, d.member, { role: role }), d.index),
59975 t('operations.change_role.annotation')
59980 function addMembership(d, role) {
59985 actionAddMember(d.relation.id, { id: id, type: context.entity(id).type, role: role }),
59986 t('operations.add_member.annotation')
59990 var relation = osmRelation();
59992 actionAddEntity(relation),
59993 actionAddMember(relation.id, { id: id, type: context.entity(id).type, role: role }),
59994 t('operations.add.annotation.relation')
59997 context.enter(modeSelect(context, [relation.id]));
60002 function deleteMembership(d) {
60004 actionDeleteMember(d.relation.id, d.index),
60005 t('operations.delete_member.annotation')
60010 function relations(q) {
60011 var newRelation = {
60013 value: t('inspector.new_relation')
60016 graph = context.graph();
60018 context.intersects(context.extent()).forEach(function(entity) {
60019 if (entity.type !== 'relation' || entity.id === id)
60022 var matched = context.presets().match(entity, graph),
60023 presetName = (matched && matched.name()) || t('inspector.relation'),
60024 entityName = utilDisplayName(entity) || '';
60026 var value = presetName + ' ' + entityName;
60027 if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
60036 result.sort(function(a, b) {
60037 return osmRelation.creationOrder(a.relation, b.relation);
60040 // Dedupe identical names by appending relation id - see #2891
60041 var dupeGroups = lodash(result)
60043 .filter(function(v) { return v.length > 1; })
60046 dupeGroups.forEach(function(group) {
60047 group.forEach(function(obj) {
60048 obj.value += ' ' + obj.relation.id;
60052 result.unshift(newRelation);
60057 function rawMembershipEditor(selection$$1) {
60058 var entity = context.entity(id),
60061 context.graph().parentRelations(entity).forEach(function(relation) {
60062 relation.members.forEach(function(member, index) {
60063 if (member.id === entity.id) {
60064 memberships.push({ relation: relation, member: member, index: index });
60069 selection$$1.call(uiDisclosure()
60070 .title(t('inspector.all_relations') + ' (' + memberships.length + ')')
60072 .on('toggled', toggled)
60077 function toggled(expanded) {
60079 selection$$1.node().parentNode.scrollTop += 200;
60084 function content(wrap) {
60085 var list = wrap.selectAll('.member-list')
60088 list = list.enter()
60090 .attr('class', 'member-list')
60094 var items = list.selectAll('li.member-row-normal')
60095 .data(memberships, function(d) {
60096 return osmEntity$$1.key(d.relation) + ',' + d.index;
60103 var enter = items.enter()
60105 .attr('class', 'member-row member-row-normal form-field');
60109 .attr('class', 'form-label')
60112 .on('click', selectRelation);
60116 .attr('class', 'member-entity-type')
60117 .text(function(d) {
60118 var matched = context.presets().match(d.relation, context.graph());
60119 return (matched && matched.name()) || t('inspector.relation');
60124 .attr('class', 'member-entity-name')
60125 .text(function(d) { return utilDisplayName(d.relation); });
60129 .attr('class', 'member-role')
60130 .property('type', 'text')
60131 .attr('maxlength', 255)
60132 .attr('placeholder', t('inspector.role'))
60133 .property('value', function(d) { return d.member.role; })
60134 .on('change', changeRole);
60138 .attr('tabindex', -1)
60139 .attr('class', 'remove button-input-action member-delete minor')
60140 .on('click', deleteMembership)
60141 .call(svgIcon('#operation-delete'));
60144 enter.each(bindTypeahead);
60148 var newrow = list.selectAll('.member-row-new')
60149 .data(showBlank ? [0] : []);
60154 enter = newrow.enter()
60156 .attr('class', 'member-row member-row-new form-field');
60160 .attr('type', 'text')
60161 .attr('class', 'member-entity-input');
60165 .attr('class', 'member-role')
60166 .property('type', 'text')
60167 .attr('maxlength', 255)
60168 .attr('placeholder', t('inspector.role'))
60169 .on('change', changeRole);
60173 .attr('tabindex', -1)
60174 .attr('class', 'remove button-input-action member-delete minor')
60175 .on('click', deleteMembership)
60176 .call(svgIcon('#operation-delete'));
60181 newrow.selectAll('.member-entity-input')
60184 .fetcher(function(value, callback) { callback(relations(value)); })
60185 .on('accept', onAccept)
60189 var addrel = wrap.selectAll('.add-relation')
60192 addrel = addrel.enter()
60194 .attr('class', 'add-relation')
60198 .call(svgIcon('#icon-plus', 'light'))
60199 .on('click', function() {
60202 list.selectAll('.member-entity-input').node().focus();
60206 function onAccept(d) {
60207 var role = list.selectAll('.member-row-new .member-role').property('value');
60208 addMembership(d, role);
60212 function bindTypeahead(d) {
60213 var row = select(this),
60214 role = row.selectAll('input.member-role');
60216 function sort(value, data) {
60217 var sameletter = [],
60219 for (var i = 0; i < data.length; i++) {
60220 if (data[i].value.substring(0, value.length) === value) {
60221 sameletter.push(data[i]);
60223 other.push(data[i]);
60226 return sameletter.concat(other);
60229 role.call(d3combobox()
60230 .fetcher(function(role, callback) {
60231 var rtype = d.relation.tags.type;
60234 rtype: rtype || '',
60235 geometry: context.geometry(id),
60237 }, function(err, data) {
60238 if (!err) callback(sort(role, data));
60244 function unbind() {
60245 var row = select(this);
60247 row.selectAll('input.member-role')
60248 .call(d3combobox.off);
60254 rawMembershipEditor.entityID = function(_) {
60255 if (!arguments.length) return id;
60257 return rawMembershipEditor;
60261 return rawMembershipEditor;
60264 function uiTagReference(tag) {
60265 var taginfo = services.taginfo,
60273 function findLocal(data) {
60274 var locale = utilDetect().locale.toLowerCase(),
60277 localized = lodash.find(data, function(d) {
60278 return d.lang.toLowerCase() === locale;
60280 if (localized) return localized;
60282 // try the non-regional version of a language, like
60283 // 'en' if the language is 'en-US'
60284 if (locale.indexOf('-') !== -1) {
60285 var first = locale.split('-')[0];
60286 localized = lodash.find(data, function(d) {
60287 return d.lang.toLowerCase() === first;
60289 if (localized) return localized;
60292 // finally fall back to english
60293 return lodash.find(data, function(d) {
60294 return d.lang.toLowerCase() === 'en';
60299 function load(param) {
60300 if (!taginfo) return;
60302 button.classed('tag-reference-loading', true);
60304 taginfo.docs(param, function show(err, data) {
60306 if (!err && data) {
60307 docs = findLocal(data);
60313 if (!docs || !docs.title) {
60314 if (param.hasOwnProperty('value')) {
60315 load(lodash.omit(param, 'value')); // retry with key only
60317 body.append('p').text(t('inspector.no_documentation_key'));
60324 if (docs.image && docs.image.thumb_url_prefix) {
60327 .attr('class', 'wiki-image')
60328 .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
60329 .on('load', function() { done(); })
60330 .on('error', function() { select(this).remove(); done(); });
60337 .text(docs.description || t('inspector.documentation_redirect'));
60341 .attr('target', '_blank')
60342 .attr('tabindex', -1)
60343 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
60344 .call(svgIcon('#icon-out-link', 'inline'))
60346 .text(t('inspector.reference'));
60354 button.classed('tag-reference-loading', false);
60358 .style('max-height', '200px')
60359 .style('opacity', '1');
60365 function hide(selection$$1) {
60366 selection$$1 = selection$$1 || body.transition().duration(200);
60369 .style('max-height', '0px')
60370 .style('opacity', '0');
60376 tagReference.button = function(selection$$1) {
60377 button = selection$$1.selectAll('.tag-reference-button')
60380 button = button.enter()
60382 .attr('class', 'tag-reference-button')
60383 .attr('tabindex', -1)
60384 .call(svgIcon('#icon-inspect'))
60388 .on('click', function () {
60389 event.stopPropagation();
60390 event.preventDefault();
60393 } else if (loaded) {
60402 tagReference.body = function(selection$$1) {
60403 body = selection$$1.selectAll('.tag-reference-body')
60406 body = body.enter()
60408 .attr('class', 'tag-reference-body cf')
60409 .style('max-height', '0')
60410 .style('opacity', '0')
60413 if (showing === false) {
60419 tagReference.showing = function(_) {
60420 if (!arguments.length) return showing;
60422 return tagReference;
60426 return tagReference;
60429 function uiRawTagEditor(context) {
60430 var taginfo = services.taginfo,
60431 dispatch$$1 = dispatch('change'),
60439 function rawTagEditor(selection$$1) {
60440 var count = Object.keys(tags).filter(function(d) { return d; }).length;
60442 selection$$1.call(uiDisclosure()
60443 .title(t('inspector.all_tags') + ' (' + count + ')')
60444 .expanded(context.storage('raw_tag_editor.expanded') === 'true' || preset.isFallback())
60445 .on('toggled', toggled)
60446 .content(content));
60448 function toggled(expanded) {
60449 context.storage('raw_tag_editor.expanded', expanded);
60451 selection$$1.node().parentNode.scrollTop += 200;
60457 function content(wrap) {
60458 var entries$$1 = entries(tags);
60460 if (!entries$$1.length || showBlank) {
60462 entries$$1.push({key: '', value: ''});
60465 var list = wrap.selectAll('.tag-list')
60468 list = list.enter()
60470 .attr('class', 'tag-list')
60473 var newTag = wrap.selectAll('.add-tag')
60478 .attr('class', 'add-tag')
60479 .on('click', addTag)
60480 .call(svgIcon('#icon-plus', 'light'));
60483 var items = list.selectAll('.tag-row')
60484 .data(entries$$1, function(d) { return d.key; });
60492 var enter = items.enter()
60494 .attr('class', 'tag-row cf');
60498 .attr('class', 'key-wrap')
60500 .property('type', 'text')
60501 .attr('class', 'key')
60502 .attr('maxlength', 255)
60503 .on('blur', keyChange)
60504 .on('change', keyChange);
60508 .attr('class', 'input-wrap-position')
60510 .property('type', 'text')
60511 .attr('class', 'value')
60512 .attr('maxlength', 255)
60513 .on('blur', valueChange)
60514 .on('change', valueChange)
60515 .on('keydown.push-more', pushMore);
60519 .attr('tabindex', -1)
60520 .attr('class', 'remove minor')
60521 .call(svgIcon('#operation-delete'));
60528 .sort(function(a, b) {
60529 return (a.key === '') ? 1
60530 : (b.key === '') ? -1
60531 : ascending(a.key, b.key);
60535 .each(function(tag) {
60536 var row = select(this),
60537 key = row.select('input.key'), // propagate bound data to child
60538 value = row.select('input.value'); // propagate bound data to child
60541 bindTypeahead(key, value);
60544 var isRelation = (context.entity(id).type === 'relation'),
60547 if (isRelation && tag.key === 'type') {
60548 reference = uiTagReference({ rtype: tag.value }, context);
60550 reference = uiTagReference({ key: tag.key, value: tag.value }, context);
60553 if (state === 'hover') {
60554 reference.showing(false);
60558 .call(reference.button)
60559 .call(reference.body);
60562 items.selectAll('input.key')
60563 .attr('title', function(d) { return d.key; })
60564 .call(utilGetSetValue, function(d) { return d.key; });
60566 items.selectAll('input.value')
60567 .attr('title', function(d) { return d.value; })
60568 .call(utilGetSetValue, function(d) { return d.value; });
60570 items.selectAll('button.remove')
60571 .on('click', removeTag);
60574 function pushMore() {
60575 if (event.keyCode === 9 && !event.shiftKey &&
60576 list.selectAll('li:last-child input.value').node() === this) {
60582 function bindTypeahead(key, value) {
60584 function sort(value, data) {
60585 var sameletter = [],
60587 for (var i = 0; i < data.length; i++) {
60588 if (data[i].value.substring(0, value.length) === value) {
60589 sameletter.push(data[i]);
60591 other.push(data[i]);
60594 return sameletter.concat(other);
60597 key.call(d3combobox()
60598 .fetcher(function(value, callback) {
60601 geometry: context.geometry(id),
60603 }, function(err, data) {
60604 if (!err) callback(sort(value, data));
60608 value.call(d3combobox()
60609 .fetcher(function(value, callback) {
60612 key: utilGetSetValue(key),
60613 geometry: context.geometry(id),
60615 }, function(err, data) {
60616 if (!err) callback(sort(value, data));
60622 function unbind() {
60623 var row = select(this);
60625 row.selectAll('input.key')
60626 .call(d3combobox.off);
60628 row.selectAll('input.value')
60629 .call(d3combobox.off);
60633 function keyChange(d) {
60635 kNew = this.value.trim(),
60638 if (kNew && kNew !== kOld) {
60639 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
60641 suffix = +(match[2] || 1);
60642 while (tags[kNew]) { // rename key if already in use
60643 kNew = base + '_' + suffix++;
60646 tag[kOld] = undefined;
60647 tag[kNew] = d.value;
60648 d.key = kNew; // Maintain DOM identity through the subsequent update.
60650 dispatch$$1.call('change', this, tag);
60654 function valueChange(d) {
60656 tag[d.key] = this.value;
60657 dispatch$$1.call('change', this, tag);
60661 function removeTag(d) {
60663 tag[d.key] = undefined;
60664 dispatch$$1.call('change', this, tag);
60665 select(this.parentNode).remove();
60669 function addTag() {
60670 // Wrapped in a setTimeout in case it's being called from a blur
60671 // handler. Without the setTimeout, the call to `content` would
60672 // wipe out the pending value change.
60673 setTimeout(function() {
60676 list.selectAll('li:last-child input.key').node().focus();
60682 rawTagEditor.state = function(_) {
60683 if (!arguments.length) return state;
60685 return rawTagEditor;
60689 rawTagEditor.preset = function(_) {
60690 if (!arguments.length) return preset;
60692 return rawTagEditor;
60696 rawTagEditor.tags = function(_) {
60697 if (!arguments.length) return tags;
60699 return rawTagEditor;
60703 rawTagEditor.entityID = function(_) {
60704 if (!arguments.length) return id;
60706 return rawTagEditor;
60710 return utilRebind(rawTagEditor, dispatch$$1, 'on');
60713 function uiFieldCheck(field) {
60714 var dispatch$$1 = dispatch('change'),
60715 options = field.strings && field.strings.options,
60718 input = select(null),
60719 text$$1 = select(null),
60720 label = select(null),
60724 for (var k in options) {
60725 values$$1.push(k === 'undefined' ? undefined : k);
60726 texts.push(field.t('options.' + k, { 'default': options[k] }));
60729 values$$1 = [undefined, 'yes'];
60730 texts = [t('inspector.unknown'), t('inspector.check.yes')];
60731 if (field.type === 'check') {
60732 values$$1.push('no');
60733 texts.push(t('inspector.check.no'));
60738 var check = function(selection$$1) {
60739 // hack: pretend oneway field is a oneway_yes field
60740 // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
60741 if (field.id === 'oneway') {
60742 for (var key in entity.tags) {
60743 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
60744 texts[0] = t('presets.fields.oneway_yes.options.undefined');
60750 selection$$1.classed('checkselect', 'true');
60752 label = selection$$1.selectAll('.preset-input-wrap')
60755 var enter = label.enter()
60757 .attr('class', 'preset-input-wrap');
60761 .property('indeterminate', field.type === 'check')
60762 .attr('type', 'checkbox')
60763 .attr('id', 'preset-input-' + field.id);
60768 .attr('class', 'value');
60770 label = label.merge(enter);
60771 input = label.selectAll('input');
60772 text$$1 = label.selectAll('span.value');
60775 .on('click', function() {
60777 t$$1[field.key] = values$$1[(values$$1.indexOf(value) + 1) % values$$1.length];
60778 dispatch$$1.call('change', this, t$$1);
60779 event.stopPropagation();
60784 check.entity = function(_) {
60785 if (!arguments.length) return entity;
60791 check.tags = function(tags) {
60792 value = tags[field.key];
60793 input.property('indeterminate', field.type === 'check' && !value);
60794 input.property('checked', value === 'yes');
60795 text$$1.text(texts[values$$1.indexOf(value)]);
60796 label.classed('set', !!value);
60800 check.focus = function() {
60801 input.node().focus();
60804 return utilRebind(check, dispatch$$1, 'on');
60807 function uiFieldCombo(field, context) {
60808 var dispatch$$1 = dispatch('change'),
60809 nominatim = services.nominatim,
60810 taginfo = services.taginfo,
60811 isMulti = (field.type === 'multiCombo'),
60812 isNetwork = (field.type === 'networkCombo'),
60813 optstrings = field.strings && field.strings.options,
60814 optarray = field.options,
60815 snake_case = (field.snake_case || (field.snake_case === undefined)),
60816 combobox = d3combobox().minItems(isMulti ? 1 : 2),
60824 // ensure multiCombo field.key ends with a ':'
60825 if (isMulti && field.key.match(/:$/) === null) {
60830 function snake(s) {
60831 return s.replace(/\s+/g, '_');
60834 function unsnake(s) {
60835 return s.replace(/_+/g, ' ');
60838 function clean(s) {
60839 return s.split(';')
60840 .map(function(s) { return s.trim(); })
60845 // returns the tag value for a display value
60846 // (for multiCombo, dval should be the key suffix, not the entire key)
60847 function tagValue(dval) {
60848 dval = clean(dval || '');
60851 var match = lodash.find(comboData, function(o) {
60852 return o.key && clean(o.value) === dval;
60859 if (field.type === 'typeCombo' && !dval) {
60863 return (snake_case ? snake(dval) : dval) || undefined;
60867 // returns the display value for a tag value
60868 // (for multiCombo, tval should be the key suffix, not the entire key)
60869 function displayValue(tval) {
60873 var match = lodash.find(comboData, function(o) { return o.key === tval && o.value; });
60875 return match.value;
60879 if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
60883 return snake_case ? unsnake(tval) : tval;
60887 function objectDifference(a, b) {
60888 return lodash.reject(a, function(d1) {
60889 return lodash.some(b, function(d2) { return d1.value === d2.value; });
60894 function initCombo(selection$$1, attachTo) {
60896 selection$$1.attr('readonly', 'readonly');
60897 selection$$1.call(combobox, attachTo);
60898 setStaticValues(setPlaceholder);
60900 } else if (optarray) {
60901 selection$$1.call(combobox, attachTo);
60902 setStaticValues(setPlaceholder);
60904 } else if (taginfo) {
60905 selection$$1.call(combobox.fetcher(setTaginfoValues), attachTo);
60906 setTaginfoValues('', setPlaceholder);
60911 function setStaticValues(callback) {
60912 if (!(optstrings || optarray)) return;
60915 comboData = Object.keys(optstrings).map(function(k) {
60916 var v = field.t('options.' + k, { 'default': optstrings[k] });
60924 } else if (optarray) {
60925 comboData = optarray.map(function(k) {
60926 var v = snake_case ? unsnake(k) : k;
60935 combobox.data(objectDifference(comboData, multiData));
60936 if (callback) callback(comboData);
60940 function setTaginfoValues(q, callback) {
60941 var fn = isMulti ? 'multikeys' : 'values';
60942 var query = (isMulti ? field.key : '') + q;
60943 var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
60944 if (hasCountryPrefix) {
60945 query = country + ':';
60950 geometry: context.geometry(entity.id),
60952 }, function(err, data) {
60954 if (hasCountryPrefix) {
60955 data = lodash.filter(data, function(d) {
60956 return d.value.toLowerCase().indexOf(country + ':') === 0;
60959 comboData = lodash.map(data, function(d) {
60961 if (isMulti) k = k.replace(field.key, '');
60962 var v = snake_case ? unsnake(k) : k;
60966 title: isMulti ? v : d.title
60969 comboData = objectDifference(comboData, multiData);
60970 if (callback) callback(comboData);
60975 function setPlaceholder(d) {
60978 ph = field.placeholder() || t('inspector.add');
60980 var vals = lodash.map(d, 'value').filter(function(s) { return s.length < 20; }),
60981 placeholders = vals.length > 1 ? vals : lodash.map(d, 'key');
60982 ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
60985 container.selectAll('input')
60986 .attr('placeholder', ph + '…');
60990 function change() {
60991 var val = tagValue(utilGetSetValue(input)),
60996 container.classed('active', false);
60997 utilGetSetValue(input, '');
60998 field.keys.push(field.key + val);
60999 t$$1[field.key + val] = 'yes';
61000 window.setTimeout(function() { input.node().focus(); }, 10);
61003 t$$1[field.key] = val;
61006 dispatch$$1.call('change', this, t$$1);
61010 function removeMultikey(d) {
61011 event.stopPropagation();
61013 t$$1[d.key] = undefined;
61014 dispatch$$1.call('change', this, t$$1);
61018 function combo(selection$$1) {
61020 container = selection$$1.selectAll('ul').data([0]);
61022 container = container.enter()
61024 .attr('class', 'form-field-multicombo')
61025 .on('click', function() {
61026 window.setTimeout(function() { input.node().focus(); }, 10);
61031 container = selection$$1;
61034 input = container.selectAll('input')
61037 input = input.enter()
61039 .attr('type', 'text')
61040 .attr('id', 'preset-input-' + field.id)
61041 .call(initCombo, selection$$1)
61044 if (isNetwork && nominatim && entity) {
61045 var center = entity.extent(context.graph()).center();
61046 nominatim.countryCode(center, function (err, code) {
61052 .on('change', change)
61053 .on('blur', change);
61057 .on('accept', function() {
61058 input.node().blur();
61059 input.node().focus();
61063 .on('focus', function() { container.classed('active', true); });
61068 combo.tags = function(tags) {
61072 // Build multiData array containing keys already set..
61073 Object.keys(tags).forEach(function(key) {
61074 if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
61076 var suffix = key.substring(field.key.length);
61079 value: displayValue(suffix)
61083 // Set keys for form-field modified (needed for undo and reset buttons)..
61084 field.keys = lodash.map(multiData, 'key');
61086 // Exclude existing multikeys from combo options..
61087 var available = objectDifference(comboData, multiData);
61088 combobox.data(available);
61090 // Hide 'Add' button if this field uses fixed set of
61091 // translateable optstrings and they're all currently used..
61092 container.selectAll('.combobox-input, .combobox-caret')
61093 .classed('hide', optstrings && !available.length);
61097 var chips = container.selectAll('.chips')
61103 var enter = chips.enter()
61104 .insert('li', 'input')
61105 .attr('class', 'chips');
61107 enter.append('span');
61110 chips = chips.merge(enter);
61112 chips.select('span')
61113 .text(function(d) { return d.value; });
61116 .on('click', removeMultikey)
61117 .attr('class', 'remove')
61121 utilGetSetValue(input, displayValue(tags[field.key]));
61126 combo.focus = function() {
61127 input.node().focus();
61131 combo.entity = function(_) {
61132 if (!arguments.length) return entity;
61138 return utilRebind(combo, dispatch$$1, 'on');
61141 function uiFieldText(field, context) {
61142 var dispatch$$1 = dispatch('change'),
61143 nominatim = services.nominatim,
61148 function i(selection$$1) {
61149 var fieldId = 'preset-input-' + field.id;
61151 input = selection$$1.selectAll('input')
61154 input = input.enter()
61156 .attr('type', field.type)
61157 .attr('id', fieldId)
61158 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
61162 .on('input', change(true))
61163 .on('blur', change())
61164 .on('change', change());
61166 if (field.type === 'tel' && nominatim && entity) {
61167 var center = entity.extent(context.graph()).center();
61168 nominatim.countryCode(center, function (err, countryCode) {
61169 if (err || !dataPhoneFormats[countryCode]) return;
61170 selection$$1.selectAll('#' + fieldId)
61171 .attr('placeholder', dataPhoneFormats[countryCode]);
61174 } else if (field.type === 'number') {
61175 input.attr('type', 'text');
61177 var spinControl = selection$$1.selectAll('.spin-control')
61180 var enter = spinControl.enter()
61182 .attr('class', 'spin-control');
61187 .attr('class', 'increment')
61188 .attr('tabindex', -1);
61193 .attr('class', 'decrement')
61194 .attr('tabindex', -1);
61196 spinControl = spinControl
61199 spinControl.selectAll('button')
61200 .on('click', function(d) {
61201 event.preventDefault();
61202 var num = parseInt(input.node().value || 0, 10);
61203 if (!isNaN(num)) input.node().value = num + d;
61210 function change(onInput) {
61211 return function() {
61213 t$$1[field.key] = utilGetSetValue(input) || undefined;
61214 dispatch$$1.call('change', this, t$$1, onInput);
61219 i.entity = function(_) {
61220 if (!arguments.length) return entity;
61226 i.tags = function(tags) {
61227 utilGetSetValue(input, tags[field.key] || '');
61231 i.focus = function() {
61232 var node = input.node();
61233 if (node) node.focus();
61236 return utilRebind(i, dispatch$$1, 'on');
61239 function uiFieldAccess(field) {
61240 var dispatch$$1 = dispatch('change'),
61243 function access(selection$$1) {
61244 var wrap = selection$$1.selectAll('.preset-input-wrap')
61247 wrap = wrap.enter()
61249 .attr('class', 'cf preset-input-wrap')
61253 var list = wrap.selectAll('ul')
61256 list = list.enter()
61261 items = list.selectAll('li')
61265 var enter = items.enter()
61267 .attr('class', function(d) { return 'cf preset-access-' + d; });
61271 .attr('class', 'col6 label preset-label-access')
61272 .attr('for', function(d) { return 'preset-input-access-' + d; })
61273 .text(function(d) { return field.t('types.' + d); });
61277 .attr('class', 'col6 preset-input-access-wrap')
61279 .attr('type', 'text')
61280 .attr('class', 'preset-input-access')
61281 .attr('id', function(d) { return 'preset-input-access-' + d; })
61282 .each(function(d) {
61285 .data(access.options(d)));
61290 items = items.merge(enter);
61292 wrap.selectAll('.preset-input-access')
61293 .on('change', change)
61294 .on('blur', change);
61298 function change(d) {
61300 tag[d] = utilGetSetValue(select(this)) || undefined;
61301 dispatch$$1.call('change', this, tag);
61305 access.options = function(type) {
61306 var options = ['no', 'permissive', 'private', 'destination'];
61308 if (type !== 'access') {
61309 options.unshift('yes');
61310 options.push('designated');
61312 if (type === 'bicycle') {
61313 options.push('dismount');
61317 return options.map(function(option) {
61319 title: field.t('options.' + option + '.description'),
61326 var placeholders = {
61328 foot: 'designated',
61329 motor_vehicle: 'no'
61333 motor_vehicle: 'no',
61339 motor_vehicle: 'no'
61342 motor_vehicle: 'no',
61343 bicycle: 'designated'
61346 motor_vehicle: 'no',
61347 horse: 'designated'
61351 motor_vehicle: 'no',
61357 motor_vehicle: 'yes',
61362 motor_vehicle: 'yes'
61366 motor_vehicle: 'yes',
61372 motor_vehicle: 'yes',
61378 motor_vehicle: 'yes',
61384 motor_vehicle: 'yes',
61390 motor_vehicle: 'yes',
61396 motor_vehicle: 'yes',
61402 motor_vehicle: 'yes',
61407 motor_vehicle: 'yes'
61411 motor_vehicle: 'yes',
61417 motor_vehicle: 'yes',
61423 motor_vehicle: 'yes',
61430 access.tags = function(tags) {
61431 utilGetSetValue(items.selectAll('.preset-input-access'),
61432 function(d) { return tags[d] || ''; })
61433 .attr('placeholder', function() {
61434 return tags.access ? tags.access : field.placeholder();
61437 items.selectAll('#preset-input-access-access')
61438 .attr('placeholder', 'yes');
61440 lodash.forEach(placeholders[tags.highway], function(v, k) {
61441 items.selectAll('#preset-input-access-' + k)
61442 .attr('placeholder', function() { return (tags.access || v); });
61447 access.focus = function() {
61448 items.selectAll('.preset-input-access')
61453 return utilRebind(access, dispatch$$1, 'on');
61456 function uiFieldAddress(field, context) {
61457 var dispatch$$1 = dispatch('init', 'change'),
61458 nominatim = services.nominatim,
61459 wrap = select(null),
61460 isInitialized = false,
61472 function getNearStreets() {
61473 var extent$$1 = entity.extent(context.graph()),
61474 l = extent$$1.center(),
61475 box = geoExtent$$1(l).padByMeters(200);
61477 var streets = context.intersects(box)
61478 .filter(isAddressable)
61480 var loc = context.projection([
61481 (extent$$1[0][0] + extent$$1[1][0]) / 2,
61482 (extent$$1[0][1] + extent$$1[1][1]) / 2]),
61483 choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
61485 title: d.tags.name,
61486 value: d.tags.name,
61487 dist: choice.distance
61490 .sort(function(a, b) {
61491 return a.dist - b.dist;
61494 return lodash.uniqBy(streets, 'value');
61496 function isAddressable(d) {
61497 return d.tags.highway && d.tags.name && d.type === 'way';
61502 function getNearCities() {
61503 var extent$$1 = entity.extent(context.graph()),
61504 l = extent$$1.center(),
61505 box = geoExtent$$1(l).padByMeters(200);
61507 var cities = context.intersects(box)
61508 .filter(isAddressable)
61511 title: d.tags['addr:city'] || d.tags.name,
61512 value: d.tags['addr:city'] || d.tags.name,
61513 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
61516 .sort(function(a, b) {
61517 return a.dist - b.dist;
61520 return lodash.uniqBy(cities, 'value');
61523 function isAddressable(d) {
61525 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
61528 if (d.tags.place && d.tags.name && (
61529 d.tags.place === 'city' ||
61530 d.tags.place === 'town' ||
61531 d.tags.place === 'village'))
61534 if (d.tags['addr:city']) return true;
61541 function getNearValues(key) {
61542 var extent$$1 = entity.extent(context.graph()),
61543 l = extent$$1.center(),
61544 box = geoExtent$$1(l).padByMeters(200);
61546 var results = context.intersects(box)
61547 .filter(function hasTag(d) {
61548 return d.tags[key];
61552 title: d.tags[key],
61553 value: d.tags[key],
61554 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
61557 .sort(function(a, b) {
61558 return a.dist - b.dist;
61561 return lodash.uniqBy(results, 'value');
61565 function initCallback(err, countryCode) {
61568 var addressFormat = lodash.find(dataAddressFormats, function (a) {
61569 return a && a.countryCodes && lodash.includes(a.countryCodes, countryCode);
61570 }) || lodash.first(dataAddressFormats);
61573 // Normalize widths.
61574 var total = lodash.reduce(r, function(sum$$1, field) {
61575 return sum$$1 + (widths[field] || 0.5);
61578 return r.map(function (field) {
61581 width: (widths[field] || 0.5) / total
61586 wrap.selectAll('div')
61587 .data(addressFormat.format)
61590 .attr('class', 'addr-row')
61591 .selectAll('input')
61595 .property('type', 'text')
61596 .attr('placeholder', function (d) { return field.t('placeholders.' + d.id); })
61597 .attr('class', function (d) { return 'addr-' + d.id; })
61598 .style('width', function (d) { return d.width * 100 + '%'; });
61601 // setup dropdowns for common address tags
61603 'street', 'city', 'state', 'province', 'district',
61604 'subdistrict', 'suburb', 'place', 'postcode'
61607 addrTags.forEach(function(tag) {
61608 var nearValues = (tag === 'street') ? getNearStreets
61609 : (tag === 'city') ? getNearCities
61612 wrap.selectAll('.addr-' + tag)
61615 .fetcher(function(value, callback) {
61616 callback(nearValues('addr:' + tag));
61620 wrap.selectAll('input')
61621 .on('blur', change())
61622 .on('change', change());
61624 wrap.selectAll('input:not(.combobox-input)')
61625 .on('input', change(true));
61627 dispatch$$1.call('init');
61628 isInitialized = true;
61632 function address(selection$$1) {
61633 isInitialized = false;
61635 wrap = selection$$1.selectAll('.preset-input-wrap')
61638 wrap = wrap.enter()
61640 .attr('class', 'preset-input-wrap')
61644 if (nominatim && entity) {
61645 var center = entity.extent(context.graph()).center();
61646 nominatim.countryCode(center, initCallback);
61651 function change(onInput) {
61652 return function() {
61655 wrap.selectAll('input')
61656 .each(function (field) {
61657 tags['addr:' + field.id] = this.value || undefined;
61660 dispatch$$1.call('change', this, tags, onInput);
61665 function updateTags(tags) {
61666 utilGetSetValue(wrap.selectAll('input'), function (field) {
61667 return tags['addr:' + field.id] || '';
61672 address.entity = function(_) {
61673 if (!arguments.length) return entity;
61679 address.tags = function(tags) {
61680 if (isInitialized) {
61683 dispatch$$1.on('init', function () {
61690 address.focus = function() {
61691 var node = wrap.selectAll('input').node();
61692 if (node) node.focus();
61696 return utilRebind(address, dispatch$$1, 'on');
61699 function uiFieldCycleway(field) {
61700 var dispatch$$1 = dispatch('change'),
61701 items = select(null);
61704 function cycleway(selection$$1) {
61706 function stripcolon(s) {
61707 return s.replace(':', '');
61711 var wrap = selection$$1.selectAll('.preset-input-wrap')
61714 wrap = wrap.enter()
61716 .attr('class', 'cf preset-input-wrap')
61720 var div = wrap.selectAll('ul')
61728 items = div.selectAll('li')
61731 var enter = items.enter()
61733 .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
61737 .attr('class', 'col6 label preset-label-cycleway')
61738 .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
61739 .text(function(d) { return field.t('types.' + d); });
61743 .attr('class', 'col6 preset-input-cycleway-wrap')
61745 .attr('type', 'text')
61746 .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
61747 .each(function(d) {
61748 select(this).call(d3combobox().data(cycleway.options(d)));
61753 wrap.selectAll('.preset-input-cycleway')
61754 .on('change', change)
61755 .on('blur', change);
61759 function change() {
61760 var left = utilGetSetValue(select('.preset-input-cyclewayleft')),
61761 right = utilGetSetValue(select('.preset-input-cyclewayright')),
61764 if (left === 'none' || left === '') { left = undefined; }
61765 if (right === 'none' || right === '') { right = undefined; }
61767 // Always set both left and right as changing one can affect the other
61769 cycleway: undefined,
61770 'cycleway:left': left,
61771 'cycleway:right': right
61774 // If the left and right tags match, use the cycleway tag to tag both
61775 // sides the same way
61776 if (left === right) {
61779 'cycleway:left': undefined,
61780 'cycleway:right': undefined
61784 dispatch$$1.call('change', this, tag);
61788 cycleway.options = function() {
61789 return keys(field.strings.options).map(function(option) {
61791 title: field.t('options.' + option + '.description'),
61798 cycleway.tags = function(tags) {
61799 utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
61800 // If cycleway is set, always return that
61801 if (tags.cycleway) {
61802 return tags.cycleway;
61804 return tags[d] || '';
61806 .attr('placeholder', field.placeholder());
61810 cycleway.focus = function() {
61811 items.selectAll('.preset-input-cycleway')
61816 return utilRebind(cycleway, dispatch$$1, 'on');
61819 function uiFieldLanes(field, context) {
61820 var dispatch$$1 = dispatch('change'),
61826 function lanes(selection$$1) {
61827 lanesData = context.entity(wayID).lanes();
61829 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
61830 selection$$1.call(lanes.off);
61834 var wrap = selection$$1.selectAll('.preset-input-wrap')
61837 wrap = wrap.enter()
61839 .attr('class', 'preset-input-wrap')
61842 var surface = wrap.selectAll('.surface')
61845 var d = utilGetDimensions(wrap);
61846 var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
61848 surface = surface.enter()
61850 .attr('width', d[0])
61851 .attr('height', 300)
61852 .attr('class', 'surface')
61856 var lanesSelection = surface.selectAll('.lanes')
61859 lanesSelection = lanesSelection.enter()
61861 .attr('class', 'lanes')
61862 .merge(lanesSelection);
61865 .attr('transform', function () {
61866 return 'translate(' + (freeSpace / 2) + ', 0)';
61870 var lane = lanesSelection.selectAll('.lane')
61871 .data(lanesData.lanes);
61876 var enter = lane.enter()
61878 .attr('class', 'lane');
61884 .attr('width', LANE_WIDTH)
61885 .attr('height', LANE_HEIGHT);
61889 .attr('class', 'forward')
61897 .attr('class', 'bothways')
61905 .attr('class', 'backward')
61916 .attr('transform', function(d) {
61917 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
61920 lane.select('.forward')
61921 .style('visibility', function(d) {
61922 return d.direction === 'forward' ? 'visible' : 'hidden';
61925 lane.select('.bothways')
61926 .style('visibility', function(d) {
61927 return d.direction === 'bothways' ? 'visible' : 'hidden';
61930 lane.select('.backward')
61931 .style('visibility', function(d) {
61932 return d.direction === 'backward' ? 'visible' : 'hidden';
61937 lanes.entity = function(_) {
61938 if (!wayID || wayID !== _.id) {
61943 lanes.tags = function() {};
61944 lanes.focus = function() {};
61945 lanes.off = function() {};
61947 return utilRebind(lanes, dispatch$$1, 'on');
61950 function uiFieldLocalized(field, context) {
61951 var dispatch$$1 = dispatch('change', 'input'),
61952 wikipedia = services.wikipedia,
61953 input = select(null),
61954 localizedInputs = select(null),
61959 function localized(selection$$1) {
61960 input = selection$$1.selectAll('.localized-main')
61963 input = input.enter()
61965 .attr('type', 'text')
61966 .attr('id', 'preset-input-' + field.id)
61967 .attr('class', 'localized-main')
61968 .attr('placeholder', field.placeholder())
61971 if (field.id === 'name') {
61972 var preset = context.presets().match(entity, context.graph());
61973 input.call(d3combobox().fetcher(
61974 utilSuggestNames(preset, dataSuggestions)
61979 .on('input', change(true))
61980 .on('blur', change())
61981 .on('change', change());
61984 var translateButton = selection$$1.selectAll('.localized-add')
61987 translateButton = translateButton.enter()
61989 .attr('class', 'button-input-action localized-add minor')
61990 .attr('tabindex', -1)
61991 .call(svgIcon('#icon-plus'))
61993 .title(t('translate.translate'))
61994 .placement('left'))
61995 .merge(translateButton);
61998 .on('click', addNew);
62001 localizedInputs = selection$$1.selectAll('.localized-wrap')
62004 localizedInputs = localizedInputs.enter().append('div')
62005 .attr('class', 'localized-wrap')
62006 .merge(localizedInputs);
62010 function addNew() {
62011 event.preventDefault();
62012 var data$$1 = localizedInputs.selectAll('div.entry').data();
62013 var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
62014 var langExists = lodash.find(data$$1, function(datum) { return datum.lang === defaultLang;});
62015 var isLangEn = defaultLang.indexOf('en') > -1;
62016 if (isLangEn || langExists) {
62019 data$$1.push({ lang: defaultLang, value: '' });
62020 localizedInputs.call(render, data$$1);
62024 function change(onInput) {
62025 return function() {
62027 t$$1[field.key] = utilGetSetValue(select(this)) || undefined;
62028 dispatch$$1.call('change', this, t$$1, onInput);
62033 function key(lang) {
62034 return field.key + ':' + lang;
62038 function changeLang(d) {
62039 var lang = utilGetSetValue(select(this)),
62041 language = lodash.find(dataWikipedia, function(d) {
62042 return d[0].toLowerCase() === lang.toLowerCase() ||
62043 d[1].toLowerCase() === lang.toLowerCase();
62046 if (language) lang = language[2];
62048 if (d.lang && d.lang !== lang) {
62049 t$$1[key(d.lang)] = undefined;
62052 var value = utilGetSetValue(select(this.parentNode)
62053 .selectAll('.localized-value'));
62055 if (lang && value) {
62056 t$$1[key(lang)] = value;
62057 } else if (lang && wikiTitles && wikiTitles[d.lang]) {
62058 t$$1[key(lang)] = wikiTitles[d.lang];
62062 dispatch$$1.call('change', this, t$$1);
62066 function changeValue(d) {
62067 if (!d.lang) return;
62069 t$$1[key(d.lang)] = utilGetSetValue(select(this)) || undefined;
62070 dispatch$$1.call('change', this, t$$1);
62074 function fetcher(value, cb) {
62075 var v = value.toLowerCase();
62077 cb(dataWikipedia.filter(function(d) {
62078 return d[0].toLowerCase().indexOf(v) >= 0 ||
62079 d[1].toLowerCase().indexOf(v) >= 0 ||
62080 d[2].toLowerCase().indexOf(v) >= 0;
62081 }).map(function(d) {
62082 return { value: d[1] };
62087 function render(selection$$1, data$$1) {
62088 var wraps = selection$$1.selectAll('div.entry').
62089 data(data$$1, function(d) { return d.lang; });
62094 .style('max-height','0px')
62095 .style('opacity', '0')
62096 .style('top','-10px')
62099 var innerWrap = wraps.enter()
62100 .insert('div', ':first-child');
62102 innerWrap.attr('class', 'entry')
62104 var wrap = select(this);
62105 var langcombo = d3combobox().fetcher(fetcher).minItems(0);
62109 .attr('class','form-label')
62110 .text(t('translate.localized_translation_label'))
62111 .attr('for','localized-lang');
62115 .attr('class', 'minor remove')
62116 .on('click', function(d){
62117 event.preventDefault();
62119 t$$1[key(d.lang)] = undefined;
62120 dispatch$$1.call('change', this, t$$1);
62121 select(this.parentNode.parentNode)
62123 .style('max-height','240px')
62125 .style('opacity', '0')
62126 .style('max-height','0px')
62129 .call(svgIcon('#operation-delete'));
62133 .attr('class', 'localized-lang')
62134 .attr('type', 'text')
62135 .attr('placeholder',t('translate.localized_translation_language'))
62136 .on('blur', changeLang)
62137 .on('change', changeLang)
62142 .on('blur', changeValue)
62143 .on('change', changeValue)
62144 .attr('type', 'text')
62145 .attr('placeholder', t('translate.localized_translation_name'))
62146 .attr('class', 'localized-value');
62150 .style('margin-top', '0px')
62151 .style('max-height', '0px')
62152 .style('opacity', '0')
62155 .style('margin-top', '10px')
62156 .style('max-height', '240px')
62157 .style('opacity', '1')
62158 .on('end', function() {
62160 .style('max-height', '')
62161 .style('overflow', 'visible');
62165 var entry = selection$$1.selectAll('.entry');
62167 utilGetSetValue(entry.select('.localized-lang'), function(d) {
62168 var lang = lodash.find(dataWikipedia, function(lang) { return lang[2] === d.lang; });
62169 return lang ? lang[1] : d.lang;
62172 utilGetSetValue(entry.select('.localized-value'),
62173 function(d) { return d.value; });
62177 localized.tags = function(tags) {
62178 // Fetch translations from wikipedia
62179 if (tags.wikipedia && !wikiTitles) {
62181 var wm = tags.wikipedia.match(/([^:]+):(.+)/);
62182 if (wm && wm[0] && wm[1]) {
62183 wikipedia.translations(wm[1], wm[2], function(d) {
62189 utilGetSetValue(input, tags[field.key] || '');
62191 var postfixed = [], k, m;
62193 m = k.match(/^(.*):([a-zA-Z_-]+)$/);
62194 if (m && m[1] === field.key && m[2]) {
62195 postfixed.push({ lang: m[2], value: tags[k] });
62199 localizedInputs.call(render, postfixed.reverse());
62203 localized.focus = function() {
62204 input.node().focus();
62208 localized.entity = function(_) {
62209 if (!arguments.length) return entity;
62214 return utilRebind(localized, dispatch$$1, 'on');
62217 function uiFieldMaxspeed(field, context) {
62218 var dispatch$$1 = dispatch('change'),
62221 unitInput = select(null),
62222 input = select(null),
62225 var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
62226 imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
62229 function maxspeed(selection$$1) {
62230 combobox = d3combobox();
62231 var unitCombobox = d3combobox().data(['km/h', 'mph'].map(comboValues));
62233 input = selection$$1.selectAll('#preset-input-' + field.id)
62236 input = input.enter()
62238 .attr('type', 'text')
62239 .attr('id', 'preset-input-' + field.id)
62240 .attr('placeholder', field.placeholder())
62245 .on('change', change)
62246 .on('blur', change);
62248 var childNodes = context.graph().childNodes(context.entity(entity.id)),
62249 loc = childNodes[~~(childNodes.length/2)].loc;
62251 isImperial = lodash.some(dataImperial.features, function(f) {
62252 return lodash.some(f.geometry.coordinates, function(d) {
62253 return geoPointInPolygon(loc, d);
62257 unitInput = selection$$1.selectAll('input.maxspeed-unit')
62260 unitInput = unitInput.enter()
62262 .attr('type', 'text')
62263 .attr('class', 'maxspeed-unit')
62264 .call(unitCombobox)
62268 .on('blur', changeUnits)
62269 .on('change', changeUnits);
62272 function changeUnits() {
62273 isImperial = utilGetSetValue(unitInput) === 'mph';
62274 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
62281 function setSuggestions() {
62282 combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
62283 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
62287 function comboValues(d) {
62289 value: d.toString(),
62290 title: d.toString()
62295 function change() {
62297 value = utilGetSetValue(input);
62300 tag[field.key] = undefined;
62301 } else if (isNaN(value) || !isImperial) {
62302 tag[field.key] = value;
62304 tag[field.key] = value + ' mph';
62307 dispatch$$1.call('change', this, tag);
62311 maxspeed.tags = function(tags) {
62312 var value = tags[field.key];
62314 if (value && value.indexOf('mph') >= 0) {
62315 value = parseInt(value, 10);
62317 } else if (value) {
62318 isImperial = false;
62322 utilGetSetValue(input, value || '');
62326 maxspeed.focus = function() {
62327 input.node().focus();
62331 maxspeed.entity = function(_) {
62336 return utilRebind(maxspeed, dispatch$$1, 'on');
62339 function uiFieldRadio(field) {
62340 var dispatch$$1 = dispatch('change'),
62341 placeholder = select(null),
62342 labels = select(null),
62343 radios = select(null);
62346 function radio(selection$$1) {
62347 selection$$1.classed('preset-radio', true);
62349 var wrap = selection$$1.selectAll('.preset-input-wrap')
62352 var enter = wrap.enter()
62354 .attr('class', 'preset-input-wrap toggle-list');
62358 .attr('class', 'placeholder');
62364 placeholder = wrap.selectAll('.placeholder');
62366 labels = wrap.selectAll('label')
62367 .data(field.options || field.keys);
62369 enter = labels.enter()
62372 enter.append('input')
62373 .attr('type', 'radio')
62374 .attr('name', field.id)
62375 .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
62376 .attr('checked', false);
62378 enter.append('span')
62379 .text(function(d) { return field.t('options.' + d, { 'default': d }); });
62384 radios = labels.selectAll('input')
62385 .on('change', change);
62389 function change() {
62391 if (field.key) t$$1[field.key] = undefined;
62392 radios.each(function(d) {
62393 var active$$1 = select(this).property('checked');
62395 if (active$$1) t$$1[field.key] = d;
62397 t$$1[d] = active$$1 ? 'yes' : undefined;
62400 dispatch$$1.call('change', this, t$$1);
62404 radio.tags = function(tags) {
62405 function checked(d) {
62407 return tags[field.key] === d;
62409 return !!(tags[d] && tags[d] !== 'no');
62413 labels.classed('active', checked);
62414 radios.property('checked', checked);
62415 var selection$$1 = radios.filter(function() { return this.checked; });
62416 if (selection$$1.empty()) {
62417 placeholder.text(t('inspector.none'));
62419 placeholder.text(selection$$1.attr('value'));
62424 radio.focus = function() {
62425 radios.node().focus();
62429 return utilRebind(radio, dispatch$$1, 'on');
62432 function uiFieldRestrictions(field, context) {
62433 var dispatch$$1 = dispatch('change'),
62434 breathe = behaviorBreathe(context),
62435 hover = behaviorHover(context),
62436 initialized = false,
62441 function restrictions(selection$$1) {
62442 // if form field is hidden or has detached from dom, clean up.
62443 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
62444 selection$$1.call(restrictions.off);
62448 var wrap = selection$$1.selectAll('.preset-input-wrap')
62451 var enter = wrap.enter()
62453 .attr('class', 'preset-input-wrap');
62457 .attr('class', 'restriction-help');
62460 var intersection = osmIntersection(context.graph(), vertexID),
62461 graph = intersection.graph,
62462 vertex = graph.entity(vertexID),
62463 filter = utilFunctor(true),
62464 extent$$1 = geoExtent$$1(),
62465 projection = geoRawMercator();
62467 var d = utilGetDimensions(wrap.merge(enter)),
62468 c = [d[0] / 2, d[1] / 2],
62472 .scale(256 * Math.pow(2, z) / (2 * Math.PI));
62474 var s = projection(vertex.loc);
62477 .translate([c[0] - s[0], c[1] - s[1]])
62478 .clipExtent([[0, 0], d]);
62480 var drawLayers = svgLayers(projection, context).only('osm').dimensions(d),
62481 drawVertices = svgVertices$$1(projection, context),
62482 drawLines = svgLines$$1(projection, context),
62483 drawTurns = svgTurns(projection, context);
62491 var surface = wrap.selectAll('.surface');
62493 if (!enter.empty()) {
62494 initialized = true;
62501 .call(utilSetDimensions, d)
62502 .call(drawVertices, graph, [vertex], filter, extent$$1, z)
62503 .call(drawLines, graph, intersection.ways, filter)
62504 .call(drawTurns, graph, intersection.turns(fromNodeID));
62507 .on('click.restrictions', click)
62508 .on('mouseover.restrictions', mouseover)
62509 .on('mouseout.restrictions', mouseout);
62512 .selectAll('.selected')
62513 .classed('selected', false);
62517 .selectAll('.' + intersection.highways[fromNodeID].id)
62518 .classed('selected', true);
62524 .on('change.restrictions', render);
62527 .on('resize.restrictions', function() {
62528 utilSetDimensions(wrap, null);
62538 var datum = event.target.__data__;
62539 if (datum instanceof osmEntity$$1) {
62540 fromNodeID = intersection.adjacentNodeId(datum.id);
62542 } else if (datum instanceof osmTurn) {
62543 if (datum.restriction) {
62545 actionUnrestrictTurn(datum, projection),
62546 t('operations.restriction.annotation.delete')
62550 actionRestrictTurn(datum, projection),
62551 t('operations.restriction.annotation.create')
62558 function mouseover() {
62559 var datum = event.target.__data__;
62560 if (datum instanceof osmTurn) {
62561 var graph = context.graph(),
62562 presets = context.presets(),
62565 if (datum.restriction) {
62566 preset = presets.match(graph.entity(datum.restriction), graph);
62568 preset = presets.item('type/restriction/' +
62569 osmInferRestriction(
62579 wrap.selectAll('.restriction-help')
62580 .text(t('operations.restriction.help.' +
62581 (datum.restriction ? 'toggle_off' : 'toggle_on'),
62582 { restriction: preset.name() })
62588 function mouseout() {
62589 wrap.selectAll('.restriction-help')
62590 .text(t('operations.restriction.help.' +
62591 (fromNodeID ? 'toggle' : 'select'))
62596 function render() {
62597 if (context.hasEntity(vertexID)) {
62598 restrictions(selection$$1);
62604 restrictions.entity = function(_) {
62605 if (!vertexID || vertexID !== _.id) {
62612 restrictions.tags = function() {};
62613 restrictions.focus = function() {};
62616 restrictions.off = function(selection$$1) {
62617 if (!initialized) return;
62619 selection$$1.selectAll('.surface')
62622 .on('click.restrictions', null)
62623 .on('mouseover.restrictions', null)
62624 .on('mouseout.restrictions', null);
62627 .on('change.restrictions', null);
62630 .on('resize.restrictions', null);
62634 return utilRebind(restrictions, dispatch$$1, 'on');
62637 function uiFieldTextarea(field) {
62638 var dispatch$$1 = dispatch('change'),
62639 input = select(null);
62642 function textarea(selection$$1) {
62643 input = selection$$1.selectAll('textarea')
62646 input = input.enter()
62647 .append('textarea')
62648 .attr('id', 'preset-input-' + field.id)
62649 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
62650 .attr('maxlength', 255)
62651 .on('input', change(true))
62652 .on('blur', change())
62653 .on('change', change())
62658 function change(onInput) {
62659 return function() {
62661 t$$1[field.key] = utilGetSetValue(input) || undefined;
62662 dispatch$$1.call('change', this, t$$1, onInput);
62667 textarea.tags = function(tags) {
62668 utilGetSetValue(input, tags[field.key] || '');
62672 textarea.focus = function() {
62673 input.node().focus();
62677 return utilRebind(textarea, dispatch$$1, 'on');
62680 function uiFieldWikipedia(field, context) {
62681 var dispatch$$1 = dispatch('change'),
62682 wikipedia = services.wikipedia,
62683 wikidata = services.wikidata,
62684 link = select(null),
62685 lang = select(null),
62686 title = select(null),
62690 function wiki(selection$$1) {
62691 var langcombo = d3combobox()
62692 .fetcher(function(value, cb) {
62693 var v = value.toLowerCase();
62695 cb(dataWikipedia.filter(function(d) {
62696 return d[0].toLowerCase().indexOf(v) >= 0 ||
62697 d[1].toLowerCase().indexOf(v) >= 0 ||
62698 d[2].toLowerCase().indexOf(v) >= 0;
62699 }).map(function(d) {
62700 return { value: d[1] };
62704 var titlecombo = d3combobox()
62705 .fetcher(function(value, cb) {
62707 value = context.entity(entity.id).tags.name || '';
62710 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
62711 searchfn(language()[2], value, function(query, data$$1) {
62712 cb(data$$1.map(function(d) {
62713 return { value: d };
62719 lang = selection$$1.selectAll('input.wiki-lang')
62722 lang = lang.enter()
62724 .attr('type', 'text')
62725 .attr('class', 'wiki-lang')
62726 .attr('placeholder', t('translate.localized_translation_language'))
62729 utilGetSetValue(lang, language()[1]);
62733 .on('blur', changeLang)
62734 .on('change', changeLang);
62737 title = selection$$1.selectAll('input.wiki-title')
62740 title = title.enter()
62742 .attr('type', 'text')
62743 .attr('class', 'wiki-title')
62744 .attr('id', 'preset-input-' + field.id)
62750 .on('change', change);
62753 link = selection$$1.selectAll('a.wiki-link')
62756 link = link.enter()
62758 .attr('class', 'wiki-link button-input-action minor')
62759 .attr('tabindex', -1)
62760 .attr('target', '_blank')
62761 .call(svgIcon('#icon-out-link', 'inline'))
62766 function language() {
62767 var value = utilGetSetValue(lang).toLowerCase();
62768 var locale = utilDetect().locale.toLowerCase();
62769 var localeLanguage;
62770 return lodash.find(dataWikipedia, function(d) {
62771 if (d[2] === locale) localeLanguage = d;
62772 return d[0].toLowerCase() === value ||
62773 d[1].toLowerCase() === value ||
62775 }) || localeLanguage || ['English', 'English', 'en'];
62779 function changeLang() {
62780 utilGetSetValue(lang, language()[1]);
62790 function change(skipWikidata) {
62791 var value = utilGetSetValue(title),
62792 m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
62793 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
62798 // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
62799 value = decodeURIComponent(m[2]).replace(/_/g, ' ');
62802 // Best-effort `anchordecode:` implementation
62803 anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
62805 anchor = decodeURIComponent(m[3]);
62807 value += '#' + anchor.replace(/_/g, ' ');
62809 value = value.slice(0, 1).toUpperCase() + value.slice(1);
62810 utilGetSetValue(lang, l[1]);
62811 utilGetSetValue(title, value);
62814 syncTags.wikipedia = value ? language()[2] + ':' + value : undefined;
62815 if (!skipWikidata) {
62816 syncTags.wikidata = undefined;
62819 dispatch$$1.call('change', this, syncTags);
62822 if (skipWikidata || !value || !language()[2]) return;
62824 // attempt asynchronous update of wikidata tag..
62825 var initEntityId = entity.id,
62826 initWikipedia = context.entity(initEntityId).tags.wikipedia;
62828 wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
62829 if (!data$$1 || !Object.keys(data$$1).length) return;
62830 var qids = Object.keys(data$$1);
62832 // 1. most recent change was a tag change
62833 var annotation = t('operations.change_tags.annotation'),
62834 currAnnotation = context.history().undoAnnotation();
62835 if (currAnnotation !== annotation) return;
62837 // 2. same entity exists and still selected
62838 var selectedIds = context.selectedIDs(),
62839 currEntityId = selectedIds.length > 0 && selectedIds[0];
62840 if (currEntityId !== initEntityId) return;
62842 // 3. wikipedia value has not changed
62843 var currTags = lodash.clone(context.entity(currEntityId).tags);
62844 if (initWikipedia !== currTags.wikipedia) return;
62846 // ok to coalesce the update of wikidata tag into the previous tag change
62847 currTags.wikidata = qids && lodash.find(qids, function(id) {
62848 return id.match(/^Q\d+$/);
62851 context.overwrite(actionChangeTags(currEntityId, currTags), annotation);
62852 dispatch$$1.call('change', this, currTags);
62857 wiki.tags = function(tags) {
62858 var value = tags[field.key] || '',
62859 m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
62860 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
62861 anchor = m && m[3];
62863 // value in correct format
62865 utilGetSetValue(lang, l[1]);
62866 utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
62869 // Best-effort `anchorencode:` implementation
62870 anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
62872 anchor = anchor.replace(/ /g, '_');
62875 link.attr('href', 'https://' + m[1] + '.wikipedia.org/wiki/' +
62876 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : ''));
62878 // unrecognized value format
62880 utilGetSetValue(title, value);
62881 if (value && value !== '') {
62882 utilGetSetValue(lang, '');
62884 link.attr('href', 'https://en.wikipedia.org/wiki/Special:Search?search=' + value);
62889 wiki.entity = function(_) {
62890 if (!arguments.length) return entity;
62896 wiki.focus = function() {
62897 title.node().focus();
62901 return utilRebind(wiki, dispatch$$1, 'on');
62905 access: uiFieldAccess,
62906 address: uiFieldAddress,
62907 check: uiFieldCheck,
62908 defaultcheck: uiFieldCheck,
62909 combo: uiFieldCombo,
62910 typeCombo: uiFieldCombo,
62911 multiCombo: uiFieldCombo,
62912 networkCombo: uiFieldCombo,
62913 cycleway: uiFieldCycleway,
62916 number: uiFieldText,
62917 email: uiFieldText,
62919 localized: uiFieldLocalized,
62920 lanes: uiFieldLanes,
62921 maxspeed: uiFieldMaxspeed,
62922 radio: uiFieldRadio,
62923 restrictions: uiFieldRestrictions,
62924 textarea: uiFieldTextarea,
62925 wikipedia: uiFieldWikipedia
62928 function uiPreset(context) {
62929 var dispatch$$1 = dispatch('change'),
62937 // Field Constructor
62938 function UIField(field, entity, show) {
62939 field = lodash.clone(field);
62941 field.input = uiFields[field.type](field, context)
62942 .on('change', function(t$$1, onInput) {
62943 dispatch$$1.call('change', field, t$$1, onInput);
62946 if (field.input.entity) field.input.entity(entity);
62948 field.keys = field.keys || [field.key];
62952 field.shown = function() {
62953 return field.id === 'name' || field.show || lodash.some(field.keys, function(key) { return !!tags[key]; });
62956 field.modified = function() {
62957 var original = context.graph().base().entities[entity.id];
62958 return lodash.some(field.keys, function(key) {
62959 return original ? tags[key] !== original.tags[key] : tags[key];
62963 field.revert = function() {
62964 var original = context.graph().base().entities[entity.id],
62966 field.keys.forEach(function(key) {
62967 t$$1[key] = original ? original.tags[key] : undefined;
62972 field.present = function() {
62973 return lodash.some(field.keys, function(key) {
62978 field.remove = function() {
62980 field.keys.forEach(function(key) {
62981 t$$1[key] = undefined;
62990 function fieldKey(field) {
62995 function presets(selection$$1) {
62996 selection$$1.call(uiDisclosure()
62997 .title(t('inspector.all_fields'))
62998 .expanded(context.storage('preset_fields.expanded') !== 'false')
62999 .on('toggled', toggled)
63003 function toggled(expanded) {
63004 context.storage('preset_fields.expanded', expanded);
63009 function content(selection$$1) {
63011 var entity = context.entity(id),
63012 geometry = context.geometry(id),
63013 presets = context.presets();
63017 if (presets.field('name')) {
63018 fieldsArr.push(UIField(presets.field('name'), entity));
63021 preset.fields.forEach(function(field) {
63022 if (field.matchGeometry(geometry)) {
63023 fieldsArr.push(UIField(field, entity, true));
63027 if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
63028 fieldsArr.push(UIField(presets.field('restrictions'), entity, true));
63031 presets.universal().forEach(function(field) {
63032 if (preset.fields.indexOf(field) < 0) {
63033 fieldsArr.push(UIField(field, entity));
63038 var shown = fieldsArr.filter(function(field) { return field.shown(); }),
63039 notShown = fieldsArr.filter(function(field) { return !field.shown(); });
63042 var form = selection$$1.selectAll('.preset-form')
63045 form = form.enter()
63047 .attr('class', 'preset-form inspector-inner fillL3')
63051 var fields = form.selectAll('.form-field')
63052 .data(shown, fieldKey);
63058 var enter = fields.enter()
63060 .attr('class', function(field) {
63061 return 'form-field form-field-' + field.id;
63066 .attr('class', 'form-label')
63067 .attr('for', function(field) { return 'preset-input-' + field.id; })
63068 .text(function(field) { return field.label(); });
63072 .attr('class', 'form-label-button-wrap');
63074 wrap.append('button')
63075 .attr('class', 'remove-icon')
63076 .attr('tabindex', -1)
63077 .call(svgIcon('#operation-delete'));
63079 wrap.append('button')
63080 .attr('class', 'modified-icon')
63081 .attr('tabindex', -1)
63083 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
63091 fields.selectAll('.form-label-button-wrap .remove-icon')
63092 .on('click', remove);
63094 fields.selectAll('.modified-icon')
63095 .on('click', revert);
63099 .classed('modified', function(field) { return field.modified(); })
63100 .classed('present', function(field) { return field.present(); })
63101 .each(function(field) {
63102 var reference = uiTagReference(field.reference || { key: field.key }, context);
63104 if (state === 'hover') {
63105 reference.showing(false);
63110 .selectAll('input')
63111 .on('keydown', function() {
63112 // if user presses enter, and combobox is not active, accept edits..
63113 if (event.keyCode === 13 && select('.combobox').empty()) {
63114 context.enter(modeBrowse$$1(context));
63117 .call(reference.body)
63118 .select('.form-label-button-wrap')
63119 .call(reference.button);
63121 field.input.tags(tags);
63124 notShown = notShown.map(function(field) {
63126 title: field.label(),
63127 value: field.label(),
63133 var more = selection$$1.selectAll('.more-fields')
63134 .data((notShown.length > 0) ? [0] : []);
63139 more = more.enter()
63141 .attr('class', 'more-fields')
63143 .text(t('inspector.add_fields'))
63147 var input = more.selectAll('.value')
63153 input = input.enter()
63155 .attr('class', 'value')
63156 .attr('type', 'text')
63160 .call(utilGetSetValue, '')
63161 .attr('placeholder', function() {
63162 var placeholder = [];
63163 for (var field in notShown) {
63164 placeholder.push(notShown[field].title);
63166 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
63168 .call(d3combobox().data(notShown)
63170 .on('accept', show));
63173 function show(field) {
63174 field = field.field;
63176 content(selection$$1);
63177 field.input.focus();
63181 function revert(field) {
63182 event.stopPropagation();
63183 event.preventDefault();
63184 dispatch$$1.call('change', field, field.revert());
63188 function remove(field) {
63189 event.stopPropagation();
63190 event.preventDefault();
63191 dispatch$$1.call('change', field, field.remove());
63196 presets.preset = function(_) {
63197 if (!arguments.length) return preset;
63198 if (preset && preset.id === _.id) return presets;
63205 presets.state = function(_) {
63206 if (!arguments.length) return state;
63212 presets.tags = function(_) {
63213 if (!arguments.length) return tags;
63215 // Don't reset fieldsArr here.
63220 presets.entityID = function(_) {
63221 if (!arguments.length) return id;
63222 if (id === _) return presets;
63229 return utilRebind(presets, dispatch$$1, 'on');
63232 function uiEntityEditor(context) {
63233 var dispatch$$1 = dispatch('choose'),
63235 coalesceChanges = false,
63242 var presetEditor = uiPreset(context)
63243 .on('change', changeTags);
63244 var rawTagEditor = uiRawTagEditor(context)
63245 .on('change', changeTags);
63248 function entityEditor(selection$$1) {
63249 var entity = context.entity(id),
63250 tags = lodash.clone(entity.tags);
63253 var header = selection$$1.selectAll('.header')
63257 var enter = header.enter()
63259 .attr('class', 'header fillL cf');
63263 .attr('class', 'fl preset-reset preset-choose')
63265 .html((textDirection === 'rtl') ? '►' : '◄');
63269 .attr('class', 'fr preset-close')
63270 .on('click', function() { context.enter(modeBrowse$$1(context)); })
63271 .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
63275 .text(t('inspector.edit'));
63281 header.selectAll('.preset-reset')
63282 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
63286 var body = selection$$1.selectAll('.inspector-body')
63290 enter = body.enter()
63292 .attr('class', 'inspector-body');
63296 .attr('class', 'preset-list-item inspector-inner')
63298 .attr('class', 'preset-list-button-wrap')
63300 .attr('class', 'preset-list-button preset-reset')
63301 .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
63303 .attr('class', 'label');
63307 .attr('class', 'inspector-border inspector-preset');
63311 .attr('class', 'inspector-border raw-tag-editor inspector-inner');
63315 .attr('class', 'inspector-border raw-member-editor inspector-inner');
63319 .attr('class', 'raw-membership-editor inspector-inner');
63325 body.selectAll('.preset-list-button-wrap')
63326 .call(reference.button);
63328 body.selectAll('.preset-list-item')
63329 .call(reference.body);
63331 body.selectAll('.preset-reset')
63332 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
63334 body.select('.preset-list-item button')
63335 .call(uiPresetIcon()
63336 .geometry(context.geometry(id))
63337 .preset(activePreset));
63339 body.select('.preset-list-item .label')
63340 .text(activePreset.name());
63342 body.select('.inspector-preset')
63344 .preset(activePreset)
63349 body.select('.raw-tag-editor')
63351 .preset(activePreset)
63356 if (entity.type === 'relation') {
63357 body.select('.raw-member-editor')
63358 .style('display', 'block')
63359 .call(uiRawMemberEditor(context)
63362 body.select('.raw-member-editor')
63363 .style('display', 'none');
63366 body.select('.raw-membership-editor')
63367 .call(uiRawMembershipEditor(context)
63372 .on('change.entity-editor', historyChanged);
63375 function historyChanged() {
63376 if (state === 'hide') return;
63378 var entity = context.hasEntity(id),
63379 graph = context.graph();
63380 if (!entity) return;
63382 entityEditor.preset(context.presets().match(entity, graph));
63383 entityEditor.modified(base !== graph);
63384 entityEditor(selection$$1);
63389 function clean(o) {
63391 function cleanVal(k, v) {
63392 function keepSpaces(k) {
63393 var whitelist = ['opening_hours', 'service_times', 'collection_times',
63394 'operating_times', 'smoking_hours', 'happy_hours'];
63395 return lodash.some(whitelist, function(s) { return k.indexOf(s) !== -1; });
63398 var blacklist = ['description', 'note', 'fixme'];
63399 if (lodash.some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
63401 var cleaned = v.split(';')
63402 .map(function(s) { return s.trim(); })
63403 .join(keepSpaces(k) ? '; ' : ';');
63405 // The code below is not intended to validate websites and emails.
63406 // It is only intended to prevent obvious copy-paste errors. (#2323)
63408 // clean website- and email-like tags
63409 if (k.indexOf('website') !== -1 ||
63410 k.indexOf('email') !== -1 ||
63411 cleaned.indexOf('http') === 0) {
63413 .replace(/[\u200B-\u200F\uFEFF]/g, ''); // strip LRM and other zero width chars
63420 var out = {}, k, v;
63422 if (k && (v = o[k]) !== undefined) {
63423 out[k] = cleanVal(k, v);
63430 // Tag changes that fire on input can all get coalesced into a single
63431 // history operation when the user leaves the field. #2342
63432 function changeTags(changed, onInput) {
63433 var entity = context.entity(id),
63434 annotation = t('operations.change_tags.annotation'),
63435 tags = lodash.clone(entity.tags);
63437 lodash.forEach(changed, function(v, k) {
63438 if (v !== undefined || tags.hasOwnProperty(k)) {
63444 tags = clean(tags);
63447 if (!lodash.isEqual(entity.tags, tags)) {
63448 if (coalesceChanges) {
63449 context.overwrite(actionChangeTags(id, tags), annotation);
63451 context.perform(actionChangeTags(id, tags), annotation);
63452 coalesceChanges = !!onInput;
63458 entityEditor.modified = function(_) {
63459 if (!arguments.length) return modified;
63461 selectAll('button.preset-close use')
63462 .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
63466 entityEditor.state = function(_) {
63467 if (!arguments.length) return state;
63469 return entityEditor;
63473 entityEditor.entityID = function(_) {
63474 if (!arguments.length) return id;
63476 base = context.graph();
63477 entityEditor.preset(context.presets().match(context.entity(id), base));
63478 entityEditor.modified(false);
63479 coalesceChanges = false;
63480 return entityEditor;
63484 entityEditor.preset = function(_) {
63485 if (!arguments.length) return activePreset;
63486 if (_ !== activePreset) {
63488 reference = uiTagReference(activePreset.reference(context.geometry(id)), context)
63491 return entityEditor;
63495 return utilRebind(entityEditor, dispatch$$1, 'on');
63498 function uiPresetList(context) {
63499 var dispatch$$1 = dispatch('choose'),
63505 function presetList(selection$$1) {
63506 var entity = context.entity(id),
63507 geometry = context.geometry(id);
63509 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
63510 if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
63511 geometry = 'point';
63514 var presets = context.presets().matchGeometry(geometry);
63516 selection$$1.html('');
63518 var messagewrap = selection$$1
63520 .attr('class', 'header fillL cf');
63522 var message = messagewrap
63524 .text(t('inspector.choose'));
63526 if (context.entity(id).isUsed(context.graph())) {
63529 .attr('class', 'preset-choose')
63530 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
63532 .html((textDirection === 'rtl') ? '◄' : '►');
63536 .attr('class', 'close')
63537 .on('click', function() {
63538 context.enter(modeBrowse$$1(context));
63540 .call(svgIcon('#icon-close'));
63543 function keydown() {
63544 // hack to let delete shortcut work when search is autofocused
63545 if (search.property('value').length === 0 &&
63546 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
63547 event.keyCode === d3keybinding.keyCodes['⌦'])) {
63548 event.preventDefault();
63549 event.stopPropagation();
63550 operationDelete([id], context)();
63551 } else if (search.property('value').length === 0 &&
63552 (event.ctrlKey || event.metaKey) &&
63553 event.keyCode === d3keybinding.keyCodes.z) {
63554 event.preventDefault();
63555 event.stopPropagation();
63557 } else if (!event.ctrlKey && !event.metaKey) {
63558 select(this).on('keydown', null);
63562 function keypress() {
63564 var value = search.property('value');
63565 if (event.keyCode === 13 && value.length) {
63566 list.selectAll('.preset-list-item:first-child').datum().choose();
63570 function inputevent() {
63571 var value = search.property('value');
63572 list.classed('filtered', value.length);
63573 if (value.length) {
63574 var results = presets.search(value, geometry);
63575 message.text(t('inspector.results', {
63576 n: results.collection.length,
63579 list.call(drawList, results);
63581 list.call(drawList, context.presets().defaults(geometry, 36));
63582 message.text(t('inspector.choose'));
63586 var searchWrap = selection$$1
63588 .attr('class', 'search-header');
63590 var search = searchWrap
63592 .attr('class', 'preset-search-input')
63593 .attr('placeholder', t('inspector.search'))
63594 .attr('type', 'search')
63595 .on('keydown', keydown)
63596 .on('keypress', keypress)
63597 .on('input', inputevent);
63600 .call(svgIcon('#icon-search', 'pre-text'));
63603 search.node().focus();
63606 var listWrap = selection$$1
63608 .attr('class', 'inspector-body');
63610 var list = listWrap
63612 .attr('class', 'preset-list fillL cf')
63613 .call(drawList, context.presets().defaults(geometry, 36));
63617 function drawList(list, presets) {
63618 var collection = presets.collection.map(function(preset) {
63619 return preset.members ? CategoryItem(preset) : PresetItem(preset);
63622 var items = list.selectAll('.preset-list-item')
63623 .data(collection, function(d) { return d.preset.id; });
63632 .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
63633 .classed('current', function(item) { return item.preset === currentPreset; })
63634 .each(function(item) { select(this).call(item); })
63635 .style('opacity', 0)
63637 .style('opacity', 1);
63641 function CategoryItem(preset) {
63642 var box, sublist, shown = false;
63644 function item(selection$$1) {
63645 var wrap = selection$$1.append('div')
63646 .attr('class', 'preset-list-button-wrap category col12');
63648 wrap.append('button')
63649 .attr('class', 'preset-list-button')
63650 .classed('expanded', false)
63651 .call(uiPresetIcon()
63652 .geometry(context.geometry(id))
63654 .on('click', function() {
63655 var isExpanded = select(this).classed('expanded');
63656 var triangle = isExpanded ? '▶ ' : '▼ ';
63657 select(this).classed('expanded', !isExpanded);
63658 select(this).selectAll('.label').text(triangle + preset.name());
63662 .attr('class', 'label')
63664 return '▶ ' + preset.name();
63667 box = selection$$1.append('div')
63668 .attr('class', 'subgrid col12')
63669 .style('max-height', '0px')
63670 .style('opacity', 0);
63673 .attr('class', 'arrow');
63675 sublist = box.append('div')
63676 .attr('class', 'preset-list fillL3 cf fl');
63679 item.choose = function() {
63680 if (!box || !sublist) return;
63686 .style('opacity', '0')
63687 .style('max-height', '0px')
63688 .style('padding-bottom', '0px');
63691 sublist.call(drawList, preset.members);
63694 .style('opacity', '1')
63695 .style('max-height', 200 + preset.members.collection.length * 80 + 'px')
63696 .style('padding-bottom', '20px');
63700 item.preset = preset;
63706 function PresetItem(preset) {
63707 function item(selection$$1) {
63708 var wrap = selection$$1.append('div')
63709 .attr('class', 'preset-list-button-wrap col12');
63711 wrap.append('button')
63712 .attr('class', 'preset-list-button')
63713 .call(uiPresetIcon()
63714 .geometry(context.geometry(id))
63716 .on('click', item.choose)
63718 .attr('class', 'label')
63719 .text(preset.name());
63721 wrap.call(item.reference.button);
63722 selection$$1.call(item.reference.body);
63725 item.choose = function() {
63726 context.presets().choose(preset);
63729 actionChangePreset(id, currentPreset, preset),
63730 t('operations.change_tags.annotation')
63733 dispatch$$1.call('choose', this, preset);
63736 item.help = function() {
63737 event.stopPropagation();
63738 item.reference.toggle();
63741 item.preset = preset;
63742 item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
63748 presetList.autofocus = function(_) {
63749 if (!arguments.length) return autofocus;
63755 presetList.entityID = function(_) {
63756 if (!arguments.length) return id;
63758 presetList.preset(context.presets().match(context.entity(id), context.graph()));
63763 presetList.preset = function(_) {
63764 if (!arguments.length) return currentPreset;
63770 return utilRebind(presetList, dispatch$$1, 'on');
63773 function uiViewOnOSM(context) {
63776 function viewOnOSM(selection) {
63777 var entity = context.entity(id);
63779 selection.style('display', entity.isNew() ? 'none' : null);
63781 var link = selection.selectAll('.view-on-osm')
63786 .attr('class', 'view-on-osm')
63787 .attr('target', '_blank')
63788 .call(svgIcon('#icon-out-link', 'inline'))
63790 .text(t('inspector.view_on_osm'));
63793 .attr('href', context.connection().entityURL(entity));
63797 viewOnOSM.entityID = function(_) {
63798 if (!arguments.length) return id;
63806 function uiInspector(context) {
63807 var presetList = uiPresetList(context),
63808 entityEditor = uiEntityEditor(context),
63811 newFeature = false;
63814 function inspector(selection$$1) {
63816 .entityID(entityID)
63817 .autofocus(newFeature)
63818 .on('choose', setPreset);
63822 .entityID(entityID)
63823 .on('choose', showList);
63825 var wrap = selection$$1.selectAll('.panewrap')
63828 var enter = wrap.enter()
63830 .attr('class', 'panewrap');
63834 .attr('class', 'preset-list-pane pane');
63838 .attr('class', 'entity-editor-pane pane');
63840 wrap = wrap.merge(enter);
63841 var presetPane = wrap.selectAll('.preset-list-pane');
63842 var editorPane = wrap.selectAll('.entity-editor-pane');
63844 var graph = context.graph(),
63845 entity = context.entity(entityID),
63846 showEditor = state === 'hover' ||
63847 entity.isUsed(graph) ||
63848 entity.isHighwayIntersection(graph);
63851 wrap.style('right', '0%');
63852 editorPane.call(entityEditor);
63854 wrap.style('right', '-100%');
63855 presetPane.call(presetList);
63858 var footer = selection$$1.selectAll('.footer')
63861 footer = footer.enter()
63863 .attr('class', 'footer')
63867 .call(uiViewOnOSM(context).entityID(entityID));
63870 function showList(preset) {
63872 .styleTween('right', function() { return interpolate('0%', '-100%'); });
63875 .call(presetList.preset(preset).autofocus(true));
63879 function setPreset(preset) {
63881 .styleTween('right', function() { return interpolate('-100%', '0%'); });
63884 .call(entityEditor.preset(preset));
63889 inspector.state = function(_) {
63890 if (!arguments.length) return state;
63892 entityEditor.state(state);
63897 inspector.entityID = function(_) {
63898 if (!arguments.length) return entityID;
63904 inspector.newFeature = function(_) {
63905 if (!arguments.length) return newFeature;
63914 function uiNotice(context) {
63916 return function(selection) {
63917 var div = selection
63919 .attr('class', 'notice');
63923 .attr('class', 'zoom-to notice')
63924 .on('click', function() { context.map().zoom(context.minEditableZoom()); });
63927 .call(svgIcon('#icon-plus', 'pre-text'))
63929 .attr('class', 'label')
63930 .text(t('zoom_in_edit'));
63933 function disableTooHigh() {
63934 div.style('display', context.editable() ? 'none' : 'block');
63938 .on('move.notice', lodash.debounce(disableTooHigh, 500));
63944 function uiSidebar(context) {
63945 var inspector = uiInspector(context),
63949 function sidebar(selection) {
63950 var featureListWrap = selection
63952 .attr('class', 'feature-list-pane')
63953 .call(uiFeatureList(context));
63956 .call(uiNotice(context));
63958 var inspectorWrap = selection
63960 .attr('class', 'inspector-hidden inspector-wrap fr');
63963 function hover(id) {
63964 if (!current && context.hasEntity(id)) {
63966 .classed('inspector-hidden', true);
63969 .classed('inspector-hidden', false)
63970 .classed('inspector-hover', true);
63972 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
63981 } else if (!current) {
63983 .classed('inspector-hidden', false);
63985 .classed('inspector-hidden', true);
63992 sidebar.hover = lodash.throttle(hover, 200);
63995 sidebar.select = function(id, newFeature) {
63996 if (!current && id) {
63998 .classed('inspector-hidden', true);
64001 .classed('inspector-hidden', false)
64002 .classed('inspector-hover', false);
64004 if (inspector.entityID() !== id || inspector.state() !== 'select') {
64008 .newFeature(newFeature);
64014 } else if (!current) {
64016 .classed('inspector-hidden', false);
64018 .classed('inspector-hidden', true);
64025 sidebar.show = function(component) {
64027 .classed('inspector-hidden', true);
64029 .classed('inspector-hidden', true);
64031 if (current) current.remove();
64032 current = selection
64034 .attr('class', 'sidebar-component')
64039 sidebar.hide = function() {
64041 .classed('inspector-hidden', false);
64043 .classed('inspector-hidden', true);
64045 if (current) current.remove();
64051 sidebar.hover = function() {};
64052 sidebar.hover.cancel = function() {};
64053 sidebar.select = function() {};
64054 sidebar.show = function() {};
64055 sidebar.hide = function() {};
64060 function uiSpinner(context) {
64061 var connection = context.connection();
64064 return function(selection) {
64065 var img = selection
64067 .attr('src', context.imagePath('loader-black.gif'))
64068 .style('opacity', 0);
64071 .on('loading.spinner', function() {
64073 .style('opacity', 1);
64077 .on('loaded.spinner', function() {
64079 .style('opacity', 0);
64084 function uiSplash(context) {
64086 return function(selection$$1) {
64087 if (context.storage('sawSplash'))
64090 context.storage('sawSplash', true);
64092 var modalSelection = uiModal(selection$$1);
64094 modalSelection.select('.modal')
64095 .attr('class', 'modal-splash modal col6');
64097 var introModal = modalSelection.select('.content')
64099 .attr('class', 'fillL');
64103 .attr('class','modal-section cf')
64104 .append('h3').text(t('splash.welcome'));
64108 .attr('class','modal-section')
64110 .html(t('splash.text', {
64111 version: context.version,
64112 website: '<a href="http://ideditor.com/">ideditor.com</a>',
64113 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
64116 var buttons = introModal
64118 .attr('class', 'modal-actions cf');
64122 .attr('class', 'col6 walkthrough')
64123 .text(t('splash.walkthrough'))
64124 .on('click', function() {
64125 select(document.body).call(uiIntro(context));
64126 modalSelection.close();
64131 .attr('class', 'col6 start')
64132 .text(t('splash.start'))
64133 .on('click', modalSelection.close);
64135 modalSelection.select('button.close')
64136 .attr('class','hide');
64141 function uiStatus(context) {
64142 var connection = context.connection();
64144 return function(selection$$1) {
64146 function update() {
64147 connection.status(function(err, apiStatus) {
64148 selection$$1.html('');
64151 if (apiStatus === 'rateLimited') {
64153 .text(t('status.rateLimit'))
64155 .attr('class', 'api-status-login')
64156 .attr('target', '_blank')
64157 .call(svgIcon('#icon-out-link', 'inline'))
64160 .on('click.login', function() {
64161 event.preventDefault();
64162 connection.authenticate();
64165 // TODO: nice messages for different error types
64166 selection$$1.text(t('status.error'));
64169 } else if (apiStatus === 'readonly') {
64170 selection$$1.text(t('status.readonly'));
64171 } else if (apiStatus === 'offline') {
64172 selection$$1.text(t('status.offline'));
64175 selection$$1.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
64180 .on('change', function() { update(selection$$1); });
64182 window.setInterval(update, 90000);
64183 update(selection$$1);
64187 function uiUndoRedo(context) {
64191 action: function() { if (!(context.inIntro() || saving())) context.undo(); },
64192 annotation: function() { return context.history().undoAnnotation(); }
64196 action: function() {if (!(context.inIntro() || saving())) context.redo(); },
64197 annotation: function() { return context.history().redoAnnotation(); }
64201 function saving() {
64202 return context.mode().id === 'save';
64206 return function(selection$$1) {
64207 var tooltipBehavior = tooltip()
64208 .placement('bottom')
64210 .title(function (d) {
64211 return uiTooltipHtml(d.annotation() ?
64212 t(d.id + '.tooltip', {action: d.annotation()}) :
64213 t(d.id + '.nothing'), d.cmd);
64216 var buttons = selection$$1.selectAll('button')
64220 .attr('class', 'col6 disabled')
64221 .on('click', function(d) { return d.action(); })
64222 .call(tooltipBehavior);
64224 buttons.each(function(d) {
64225 var iconName = d.id;
64226 if (textDirection === 'rtl') {
64227 if (iconName === 'undo') {
64229 } else if (iconName === 'redo') {
64234 .call(svgIcon('#icon-' + iconName));
64237 var keybinding = d3keybinding('undo')
64238 .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
64239 .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
64245 .on('change.undo_redo', update);
64248 .on('enter.undo_redo', update);
64250 function update() {
64252 .property('disabled', saving())
64253 .classed('disabled', function(d) { return !d.annotation(); })
64255 var selection$$1 = select(this);
64256 if (selection$$1.property('tooltipVisible')) {
64257 selection$$1.call(tooltipBehavior.show);
64264 function uiZoom(context) {
64268 title: t('zoom.in'),
64269 action: context.zoomIn,
64274 title: t('zoom.out'),
64275 action: context.zoomOut,
64280 function zoomIn() {
64281 event.preventDefault();
64282 if (!context.inIntro()) context.zoomIn();
64286 function zoomOut() {
64287 event.preventDefault();
64288 if (!context.inIntro()) context.zoomOut();
64292 function zoomInFurther() {
64293 event.preventDefault();
64294 if (!context.inIntro()) context.zoomInFurther();
64298 function zoomOutFurther() {
64299 event.preventDefault();
64300 if (!context.inIntro()) context.zoomOutFurther();
64304 return function(selection$$1) {
64305 var button = selection$$1.selectAll('button')
64309 .attr('tabindex', -1)
64310 .attr('class', function(d) { return d.id; })
64311 .on('click.editor', function(d) { d.action(); })
64313 .placement((textDirection === 'rtl') ? 'right' : 'left')
64315 .title(function(d) {
64316 return uiTooltipHtml(d.title, d.key);
64320 button.each(function(d) {
64322 .call(svgIcon('#icon-' + d.icon, 'light'));
64325 var keybinding = d3keybinding('zoom');
64327 lodash.each(['=','ffequals','plus','ffplus'], function(key) {
64328 keybinding.on([key, '⇧' + key], zoomIn);
64329 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomInFurther);
64331 lodash.each(['-','ffminus','dash'], function(key) {
64332 keybinding.on([key, '⇧' + key], zoomOut);
64333 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomOutFurther);
64341 function uiInit(context) {
64343 function render(container) {
64344 var map$$1 = context.map();
64346 var hash = behaviorHash(context);
64349 if (!hash.hadHash) {
64350 map$$1.centerZoom([0, 0], 2);
64355 .attr('id', 'defs')
64356 .call(svgDefs(context));
64360 .attr('id', 'sidebar')
64361 .attr('class', 'col4')
64364 var content = container
64366 .attr('id', 'content');
64371 .attr('class', 'fillD');
64376 .attr('dir', 'ltr')
64379 if (textDirection === 'rtl') {
64380 select('body').attr('dir', 'rtl');
64384 .call(uiMapInMap(context));
64388 .call(uiInfo(context));
64392 .attr('class', 'spacer col4');
64394 var limiter = bar.append('div')
64395 .attr('class', 'limiter');
64399 .attr('class', 'button-wrap joined col3')
64400 .call(uiModes(context), limiter);
64404 .attr('class', 'button-wrap joined col1')
64405 .call(uiUndoRedo(context));
64409 .attr('class', 'button-wrap col1')
64410 .call(uiSave(context));
64414 .attr('class', 'full-screen')
64415 .call(uiFullScreen(context));
64419 .attr('class', 'spinner')
64420 .call(uiSpinner(context));
64424 .attr('class', 'map-controls');
64428 .attr('class', 'map-control zoombuttons')
64429 .call(uiZoom(context));
64433 .attr('class', 'map-control geolocate-control')
64434 .call(uiGeolocate(context));
64438 .attr('class', 'map-control background-control')
64439 .call(uiBackground(context));
64443 .attr('class', 'map-control map-data-control')
64444 .call(uiMapData(context));
64448 .attr('class', 'map-control help-control')
64449 .call(uiHelp(context));
64451 var about = content
64453 .attr('id', 'about');
64457 .attr('id', 'attrib')
64458 .attr('dir', 'ltr')
64459 .call(uiAttribution(context));
64463 .attr('id', 'footer')
64464 .attr('class', 'fillD');
64468 .attr('class', 'api-status')
64469 .call(uiStatus(context));
64473 .attr('id', 'scale-block')
64474 .call(uiScale(context));
64476 var aboutList = footer
64478 .attr('id', 'info-block')
64480 .attr('id', 'about-list');
64482 if (!context.embed()) {
64483 aboutList.call(uiAccount(context));
64489 .attr('target', '_blank')
64490 .attr('tabindex', -1)
64491 .attr('href', 'https://github.com/openstreetmap/iD')
64492 .text(context.version);
64494 var issueLinks = aboutList
64499 .attr('target', '_blank')
64500 .attr('tabindex', -1)
64501 .attr('href', 'https://github.com/openstreetmap/iD/issues')
64502 .call(svgIcon('#icon-bug', 'light'))
64503 .call(tooltip().title(t('report_a_bug')).placement('top'));
64507 .attr('target', '_blank')
64508 .attr('tabindex', -1)
64509 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
64510 .call(svgIcon('#icon-translate', 'light'))
64511 .call(tooltip().title(t('help_translate')).placement('top'));
64515 .attr('class', 'feature-warning')
64516 .attr('tabindex', -1)
64517 .call(uiFeatureInfo(context));
64521 .attr('class', 'user-list')
64522 .attr('tabindex', -1)
64523 .call(uiContributors(context));
64526 window.onbeforeunload = function() {
64527 return context.save();
64530 window.onunload = function() {
64531 context.history().unlock();
64534 var mapDimensions = map$$1.dimensions();
64536 function onResize() {
64537 mapDimensions = utilGetDimensions(content, true);
64538 map$$1.dimensions(mapDimensions);
64542 .on('resize.editor', onResize);
64547 return function() {
64548 event.preventDefault();
64549 if (!context.inIntro()) {
64550 context.pan(d, 100);
64558 var keybinding = d3keybinding('main')
64559 .on('⌫', function() { event.preventDefault(); })
64560 .on('←', pan([pa, 0]))
64561 .on('↑', pan([0, pa]))
64562 .on('→', pan([-pa, 0]))
64563 .on('↓', pan([0, -pa]))
64564 .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
64565 .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
64566 .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
64567 .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
64572 context.enter(modeBrowse$$1(context));
64574 context.container()
64575 .call(uiSplash(context))
64576 .call(uiRestore(context));
64578 var authenticating = uiLoading(context)
64579 .message(t('loading_auth'))
64582 context.connection()
64583 .on('authLoading.ui', function() {
64584 context.container()
64585 .call(authenticating);
64587 .on('authDone.ui', function() {
64588 authenticating.close();
64593 function ui(node, callback) {
64594 var container = select(node);
64595 context.container(container);
64596 context.loadLocale(function(err) {
64606 ui.sidebar = uiSidebar(context);
64611 function uiCommit(context) {
64612 var dispatch$$1 = dispatch('cancel', 'save');
64615 function commit(selection$$1) {
64616 var changes = context.history().changes(),
64617 summary = context.history().difference().summary();
64621 .attr('class', 'header fillL')
64623 .text(t('commit.title'));
64625 var body = selection$$1
64627 .attr('class', 'body');
64629 var commentSection = body
64631 .attr('class', 'modal-section form-field commit-form');
64635 .attr('class', 'form-label')
64636 .text(t('commit.message_label'));
64638 var commentField = commentSection
64639 .append('textarea')
64640 .attr('placeholder', t('commit.description_placeholder'))
64641 .attr('maxlength', 255)
64642 .property('value', context.storage('comment') || '')
64643 .on('input.save', checkComment)
64644 .on('change.save', checkComment)
64645 .on('blur.save', function() {
64646 context.storage('comment', this.value);
64650 commentField.node().select();
64652 context.connection().userChangesets(function (err, changesets) {
64657 for (var i = 0; i < changesets.length; i++) {
64658 if (changesets[i].tags.comment) {
64660 title: changesets[i].tags.comment,
64661 value: changesets[i].tags.comment
64667 .call(d3combobox().caseSensitive(true).data(comments));
64670 var clippyArea = commentSection.append('div')
64671 .attr('class', 'clippy-area');
64673 var changeSetInfo = commentSection.append('div')
64674 .attr('class', 'changeset-info');
64676 changeSetInfo.append('a')
64677 .attr('target', '_blank')
64678 .attr('tabindex', -1)
64679 .call(svgIcon('#icon-out-link', 'inline'))
64680 .attr('href', t('commit.about_changeset_comments_link'))
64682 .text(t('commit.about_changeset_comments'));
64686 var warnings = body.selectAll('div.warning-section')
64687 .data([context.history().validate(changes)]);
64689 warnings = warnings.enter()
64691 .attr('class', 'modal-section warning-section fillL2')
64692 .style('display', function(d) { return lodash.isEmpty(d) ? 'none' : null; })
64693 .style('background', '#ffb')
64698 .text(t('commit.warnings'));
64702 .attr('class', 'changeset-list');
64704 var warningLi = warnings.select('ul').selectAll('li')
64705 .data(function(d) { return d; });
64707 warningLi = warningLi.enter()
64709 .on('mouseover', mouseover)
64710 .on('mouseout', mouseout)
64711 .on('click', warningClick)
64715 .call(svgIcon('#icon-alert', 'pre-text'));
64719 .text(function(d) { return d.message; });
64721 warningLi.filter(function(d) { return d.tooltip; })
64723 .title(function(d) { return d.tooltip; })
64728 // Upload Explanation
64729 var saveSection = body
64731 .attr('class','modal-section save-section fillL cf');
64733 var prose = saveSection
64735 .attr('class', 'commit-info')
64736 .html(t('commit.upload_explanation'));
64739 context.connection().userDetails(function(err, user) {
64742 var userLink = select(document.createElement('div'));
64744 if (user.image_url) {
64747 .attr('src', user.image_url)
64748 .attr('class', 'icon pre-text user-icon');
64753 .attr('class','user-info')
64754 .text(user.display_name)
64755 .attr('href', context.connection().userURL(user.display_name))
64756 .attr('tabindex', -1)
64757 .attr('target', '_blank');
64760 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
64765 var buttonSection = saveSection
64767 .attr('class','buttons fillL cf');
64769 var cancelButton = buttonSection
64771 .attr('class', 'secondary-action col5 button cancel-button')
64772 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
64776 .attr('class', 'label')
64777 .text(t('commit.cancel'));
64779 var saveButton = buttonSection
64781 .attr('class', 'action col5 button save-button')
64782 .attr('disabled', function() {
64783 var n = select('.commit-form textarea').node();
64784 return (n && n.value.length) ? null : true;
64786 .on('click.save', function() {
64787 dispatch$$1.call('save', this, {
64788 comment: commentField.node().value
64794 .attr('class', 'label')
64795 .text(t('commit.save'));
64799 var changeSection = body
64801 .attr('class', 'commit-section modal-section fillL2');
64803 changeSection.append('h3')
64804 .text(t('commit.changes', { count: summary.length }));
64806 var li = changeSection
64808 .attr('class', 'changeset-list')
64814 .on('mouseover', mouseover)
64815 .on('mouseout', mouseout)
64816 .on('click', zoomToEntity)
64819 li.each(function(d) {
64821 .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
64825 .attr('class', 'change-type')
64826 .text(function(d) { return t('commit.' + d.changeType) + ' '; });
64828 li.append('strong')
64829 .attr('class', 'entity-type')
64830 .text(function(d) {
64831 var matched = context.presets().match(d.entity, d.graph);
64832 return (matched && matched.name()) || utilDisplayType(d.entity.id);
64836 .attr('class', 'entity-name')
64837 .text(function(d) {
64838 var name = utilDisplayName(d.entity) || '',
64840 if (name !== '') string += ':';
64841 return string += ' ' + name;
64844 li.style('opacity', 0)
64846 .style('opacity', 1);
64849 // Call checkComment off the bat, in case a changeset
64850 // comment is recovered from localStorage
64851 utilTriggerEvent(commentField, 'input');
64854 function mouseover(d) {
64856 context.surface().selectAll(
64857 utilEntityOrMemberSelector([d.entity.id], context.graph())
64858 ).classed('hover', true);
64863 function mouseout() {
64864 context.surface().selectAll('.hover')
64865 .classed('hover', false);
64869 function warningClick(d) {
64871 context.map().zoomTo(d.entity);
64873 modeSelect(context, [d.entity.id]).suppressMenu(true)
64879 function zoomToEntity(change) {
64880 var entity = change.entity;
64881 if (change.changeType !== 'deleted' &&
64882 context.graph().entity(entity.id).geometry(context.graph()) !== 'vertex') {
64883 context.map().zoomTo(entity);
64884 context.surface().selectAll(
64885 utilEntityOrMemberSelector([entity.id], context.graph()))
64886 .classed('hover', true);
64891 function checkComment() {
64892 selectAll('.save-section .save-button')
64893 .attr('disabled', (this.value.length ? null : true));
64895 var googleWarning = clippyArea
64898 .data(this.value.match(/google/i) ? [true] : []);
64900 googleWarning.exit()
64903 googleWarning.enter()
64905 .attr('target', '_blank')
64906 .attr('tabindex', -1)
64907 .call(svgIcon('#icon-alert', 'inline'))
64908 .attr('href', t('commit.google_warning_link'))
64910 .text(t('commit.google_warning'));
64914 return utilRebind(commit, dispatch$$1, 'on');
64917 function uiConfirm(selection) {
64918 var modalSelection = uiModal(selection);
64920 modalSelection.select('.modal')
64921 .classed('modal-alert', true);
64923 var section = modalSelection.select('.content');
64925 section.append('div')
64926 .attr('class', 'modal-section header');
64928 section.append('div')
64929 .attr('class', 'modal-section message-text');
64931 var buttons = section.append('div')
64932 .attr('class', 'modal-section buttons cf');
64935 modalSelection.okButton = function() {
64938 .attr('class', 'action col4')
64939 .on('click.confirm', function() {
64940 modalSelection.remove();
64942 .text(t('confirm.okay'));
64944 return modalSelection;
64948 return modalSelection;
64951 function uiConflicts(context) {
64952 var dispatch$$1 = dispatch('download', 'cancel', 'save'),
64956 function conflicts(selection$$1) {
64957 var header = selection$$1
64959 .attr('class', 'header fillL');
64963 .attr('class', 'fr')
64964 .on('click', function() { dispatch$$1.call('cancel'); })
64965 .call(svgIcon('#icon-close'));
64969 .text(t('save.conflict.header'));
64971 var body = selection$$1
64973 .attr('class', 'body fillL');
64977 .attr('class', 'conflicts-help')
64978 .text(t('save.conflict.help'))
64980 .attr('class', 'conflicts-download')
64981 .text(t('save.conflict.download_changes'))
64982 .on('click.download', function() { dispatch$$1.call('download'); });
64986 .attr('class', 'conflict-container fillL3')
64987 .call(showConflict, 0);
64991 .attr('class', 'conflicts-done')
64992 .attr('opacity', 0)
64993 .style('display', 'none')
64994 .text(t('save.conflict.done'));
64998 .attr('class','buttons col12 joined conflicts-buttons');
65002 .attr('disabled', list.length > 1)
65003 .attr('class', 'action conflicts-button col6')
65004 .text(t('save.title'))
65005 .on('click.try_again', function() { dispatch$$1.call('save'); });
65009 .attr('class', 'secondary-action conflicts-button col6')
65010 .text(t('confirm.cancel'))
65011 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
65015 function showConflict(selection$$1, index) {
65016 if (index < 0 || index >= list.length) return;
65018 var parent = select(selection$$1.node().parentNode);
65020 // enable save button if this is the last conflict being reviewed..
65021 if (index === list.length - 1) {
65022 window.setTimeout(function() {
65023 parent.select('.conflicts-button')
65024 .attr('disabled', null);
65026 parent.select('.conflicts-done')
65028 .attr('opacity', 1)
65029 .style('display', 'block');
65033 var item = selection$$1
65034 .selectAll('.conflict')
65035 .data([list[index]]);
65037 var enter = item.enter()
65039 .attr('class', 'conflict');
65043 .attr('class', 'conflict-count')
65044 .text(t('save.conflict.count', { num: index + 1, total: list.length }));
65048 .attr('class', 'conflict-description')
65050 .text(function(d) { return d.name; })
65051 .on('click', function(d) {
65052 zoomToEntity(d.id);
65053 event.preventDefault();
65056 var details = enter
65058 .attr('class', 'conflict-detail-container');
65062 .attr('class', 'conflict-detail-list')
65064 .data(function(d) { return d.details || []; })
65067 .attr('class', 'conflict-detail-item')
65068 .html(function(d) { return d; });
65072 .attr('class', 'conflict-choices')
65077 .attr('class', 'conflict-nav-buttons joined cf')
65078 .selectAll('button')
65079 .data(['previous', 'next'])
65082 .text(function(d) { return t('save.conflict.' + d); })
65083 .attr('class', 'conflict-nav-button action col6')
65084 .attr('disabled', function(d, i) {
65085 return (i === 0 && index === 0) ||
65086 (i === 1 && index === list.length - 1) || null;
65088 .on('click', function(d, i) {
65089 var container = parent.select('.conflict-container'),
65090 sign = (i === 0 ? -1 : 1);
65093 .selectAll('.conflict')
65097 .call(showConflict, index + sign);
65099 event.preventDefault();
65107 function addChoices(selection$$1) {
65108 var choices = selection$$1
65110 .attr('class', 'layer-list')
65112 .data(function(d) { return d.choices || []; });
65114 var enter = choices.enter()
65116 .attr('class', 'layer');
65123 .attr('type', 'radio')
65124 .attr('name', function(d) { return d.id; })
65125 .on('change', function(d, i) {
65126 var ul = this.parentNode.parentNode.parentNode;
65127 ul.__data__.chosen = i;
65133 .text(function(d) { return d.text; });
65136 .each(function(d, i) {
65137 var ul = this.parentNode;
65138 if (ul.__data__.chosen === i) choose(ul, d);
65143 function choose(ul, datum) {
65144 if (event) event.preventDefault();
65148 .classed('active', function(d) { return d === datum; })
65149 .selectAll('input')
65150 .property('checked', function(d) { return d === datum; });
65152 var extent$$1 = geoExtent$$1(),
65155 entity = context.graph().hasEntity(datum.id);
65156 if (entity) extent$$1._extend(entity.extent(context.graph()));
65160 entity = context.graph().hasEntity(datum.id);
65161 if (entity) extent$$1._extend(entity.extent(context.graph()));
65163 zoomToEntity(datum.id, extent$$1);
65167 function zoomToEntity(id, extent$$1) {
65168 context.surface().selectAll('.hover')
65169 .classed('hover', false);
65171 var entity = context.graph().hasEntity(id);
65174 context.map().trimmedExtent(extent$$1);
65176 context.map().zoomTo(entity);
65178 context.surface().selectAll(
65179 utilEntityOrMemberSelector([entity.id], context.graph()))
65180 .classed('hover', true);
65185 // The conflict list should be an array of objects like:
65188 // name: entityName(local),
65189 // details: merge.conflicts(),
65192 // choice(id, keepMine, forceLocal),
65193 // choice(id, keepTheirs, forceRemote)
65196 conflicts.list = function(_) {
65197 if (!arguments.length) return list;
65203 return utilRebind(conflicts, dispatch$$1, 'on');
65206 function uiFlash(selection) {
65207 var modalSelection = uiModal(selection);
65209 modalSelection.select('.modal')
65210 .classed('modal-flash', true);
65212 modalSelection.select('.content')
65213 .classed('modal-section', true)
65215 .attr('class', 'description');
65217 modalSelection.on('click.flash', function() {
65218 modalSelection.remove();
65221 setTimeout(function() {
65222 modalSelection.remove();
65227 return modalSelection;
65230 function uiLasso(context) {
65231 var group, polygon;
65233 lasso.coordinates = [];
65235 function lasso(selection$$1) {
65236 context.container()
65237 .classed('lasso', true);
65239 group = selection$$1
65241 .attr('class', 'lasso hide');
65245 .attr('class', 'lasso-path');
65248 .call(uiToggle(true));
65254 polygon.data([lasso.coordinates])
65255 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
65260 lasso.extent = function () {
65261 return lasso.coordinates.reduce(function(extent$$1, point) {
65262 return extent$$1.extend(geoExtent$$1(point));
65263 }, geoExtent$$1());
65267 lasso.p = function(_) {
65268 if (!arguments.length) return lasso;
65269 lasso.coordinates.push(_);
65275 lasso.close = function() {
65277 group.call(uiToggle(false, function() {
65278 select(this).remove();
65281 context.container().classed('lasso', false);
65288 function uiRadialMenu(context, operations) {
65294 var radialMenu = function(selection$$1) {
65295 if (!operations.length) return;
65297 selection$$1.node().parentNode.focus();
65299 function click(operation) {
65300 event.stopPropagation();
65301 if (operation.disabled()) return;
65303 radialMenu.close();
65306 menu = selection$$1
65308 .attr('class', 'radial-menu')
65309 .attr('transform', 'translate(' + center + ')')
65310 .attr('opacity', 0);
65314 .attr('opacity', 1);
65319 a1 = a0 + (operations.length - 1) * a;
65323 .attr('class', 'radial-menu-background')
65324 .attr('d', 'M' + r * Math.sin(a0) + ',' +
65326 ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
65327 (r * Math.sin(a1) + 1e-3) + ',' +
65328 (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
65329 .attr('stroke-width', 50)
65330 .attr('stroke-linecap', 'round');
65332 var button = menu.selectAll()
65336 .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
65337 .classed('disabled', function(d) { return d.disabled(); })
65338 .attr('transform', function(d, i) {
65339 return 'translate(' + geoRoundCoords([
65340 r * Math.sin(a0 + i * a),
65341 r * Math.cos(a0 + i * a)]).join(',') + ')';
65347 .on('click', click)
65348 .on('mousedown', mousedown)
65349 .on('mouseover', mouseover)
65350 .on('mouseout', mouseout);
65354 .attr('transform', 'translate(-10,-10)')
65355 .attr('width', '20')
65356 .attr('height', '20')
65357 .attr('xlink:href', function(d) { return '#operation-' + d.id; });
65359 tooltip = select(document.body)
65361 .attr('class', 'tooltip-inner radial-menu-tooltip');
65363 function mousedown() {
65364 event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
65367 function mouseover(d, i) {
65368 var rect = context.surfaceRect(),
65369 angle = a0 + i * a,
65370 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
65371 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
65372 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
65373 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
65376 .style('top', null)
65377 .style('left', null)
65378 .style('bottom', null)
65379 .style('right', null)
65380 .style('display', 'block')
65381 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
65385 .style('right', right)
65386 .style('top', top);
65387 } else if (i >= 4) {
65389 .style('left', left)
65390 .style('bottom', bottom);
65393 .style('left', left)
65394 .style('top', top);
65398 function mouseout() {
65399 tooltip.style('display', 'none');
65404 radialMenu.close = function() {
65407 .style('pointer-events', 'none')
65409 .attr('opacity', 0)
65419 radialMenu.center = function(_) {
65420 if (!arguments.length) return center;
65429 function uiSelectionList(context, selectedIDs) {
65431 function selectEntity(entity) {
65432 context.enter(modeSelect(context, [entity.id]).suppressMenu(true));
65436 function deselectEntity(entity) {
65437 event.stopPropagation();
65438 var index = selectedIDs.indexOf(entity.id);
65440 selectedIDs.splice(index, 1);
65442 context.enter(modeSelect(context, selectedIDs).suppressMenu(true));
65446 function selectionList(selection$$1) {
65447 selection$$1.classed('selection-list-pane', true);
65449 var header = selection$$1
65451 .attr('class', 'header fillL cf');
65455 .text(t('inspector.multiselect'));
65457 var listWrap = selection$$1
65459 .attr('class', 'inspector-body');
65461 var list = listWrap
65463 .attr('class', 'feature-list cf');
65465 context.history().on('change.selection-list', drawList);
65469 function drawList() {
65470 var entities = selectedIDs
65471 .map(function(id) { return context.hasEntity(id); })
65472 .filter(function(entity) { return entity; });
65474 var items = list.selectAll('.feature-list-item')
65475 .data(entities, osmEntity$$1.key);
65481 var enter = items.enter()
65483 .attr('class', 'feature-list-item')
65484 .on('click', selectEntity);
65488 .attr('class', 'label');
65492 .attr('class', 'close')
65493 .on('click', deselectEntity)
65494 .call(svgIcon('#icon-close'));
65498 .attr('class', 'entity-geom-icon')
65499 .call(svgIcon('', 'pre-text'));
65503 .attr('class', 'entity-type');
65507 .attr('class', 'entity-name');
65510 items = items.merge(enter);
65512 items.selectAll('.entity-geom-icon use')
65513 .attr('href', function() {
65514 var entity = this.parentNode.parentNode.__data__;
65515 return '#icon-' + context.geometry(entity.id);
65518 items.selectAll('.entity-type')
65519 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
65521 items.selectAll('.entity-name')
65522 .text(function(entity) { return utilDisplayName(entity); });
65526 return selectionList;
65529 function uiSourceSwitch(context) {
65534 event.preventDefault();
65536 if (context.history().hasChanges() &&
65537 !window.confirm(t('source_switch.lose_changes'))) return;
65539 var live = select(this)
65542 context.connection()
65543 .switch(live ? keys$$1[1] : keys$$1[0]);
65545 context.enter(modeBrowse$$1(context));
65549 .text(live ? t('source_switch.dev') : t('source_switch.live'))
65550 .classed('live', !live);
65553 var sourceSwitch = function(selection$$1) {
65557 .text(t('source_switch.live'))
65558 .classed('live', true)
65559 .attr('tabindex', -1)
65560 .on('click', click);
65564 sourceSwitch.keys = function(_) {
65565 if (!arguments.length) return keys$$1;
65567 return sourceSwitch;
65571 return sourceSwitch;
65574 function uiSuccess(context) {
65575 var dispatch$$1 = dispatch('cancel'),
65579 function success(selection$$1) {
65580 var message = (changeset.comment || t('success.edited_osm')).substring(0, 130) +
65581 ' ' + context.connection().changesetURL(changeset.id);
65583 var header = selection$$1
65585 .attr('class', 'header fillL');
65589 .attr('class', 'fr')
65590 .on('click', function() { dispatch$$1.call('cancel'); })
65591 .call(svgIcon('#icon-close'));
65595 .text(t('success.just_edited'));
65597 var body = selection$$1
65599 .attr('class', 'body save-success fillL');
65603 .html(t('success.help_html'));
65607 .attr('class', 'details')
65608 .attr('target', '_blank')
65609 .attr('tabindex', -1)
65610 .call(svgIcon('#icon-out-link', 'inline'))
65611 .attr('href', t('success.help_link_url'))
65613 .text(t('success.help_link_text'));
65615 var changesetURL = context.connection().changesetURL(changeset.id);
65619 .attr('class', 'button col12 osm')
65620 .attr('target', '_blank')
65621 .attr('href', changesetURL)
65622 .text(t('success.view_on_osm'));
65625 facebook: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL),
65626 twitter: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message),
65627 google: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL)
65630 body.selectAll('.button.social')
65631 .data(entries(sharing))
65634 .attr('class', 'button social col4')
65635 .attr('target', '_blank')
65636 .attr('href', function(d) { return d.value; })
65638 .title(function(d) { return t('success.' + d.key); })
65639 .placement('bottom'))
65640 .each(function(d) { select(this).call(svgIcon('#logo-' + d.key, 'social')); });
65644 success.changeset = function(_) {
65645 if (!arguments.length) return changeset;
65651 return utilRebind(success, dispatch$$1, 'on');
65654 function coreHistory(context) {
65655 var stack$$1, index, tree$$1,
65656 imageryUsed = ['Bing'],
65657 dispatch$$1 = dispatch('change', 'undone', 'redone'),
65658 lock = utilSessionMutex('lock');
65661 function perform(actions) {
65662 actions = Array.prototype.slice.call(actions);
65666 if (!lodash.isFunction(lodash.last(actions))) {
65667 annotation = actions.pop();
65670 stack$$1[index].transform = context.projection.transform();
65671 stack$$1[index].selectedIDs = context.selectedIDs();
65673 var graph = stack$$1[index].graph;
65674 for (var i = 0; i < actions.length; i++) {
65675 graph = actions[i](graph);
65680 annotation: annotation,
65681 imageryUsed: imageryUsed
65686 function change(previous) {
65687 var difference = coreDifference(previous, history.graph());
65688 dispatch$$1.call('change', this, difference);
65693 // iD uses namespaced keys so multiple installations do not conflict
65694 function getKey(n) {
65695 return 'iD_' + window.location.origin + '_' + n;
65701 graph: function() {
65702 return stack$$1[index].graph;
65707 return stack$$1[0].graph;
65711 merge: function(entities, extent$$1) {
65712 stack$$1[0].graph.rebase(entities, lodash.map(stack$$1, 'graph'), false);
65713 tree$$1.rebase(entities, false);
65715 dispatch$$1.call('change', this, undefined, extent$$1);
65719 perform: function() {
65720 var previous = stack$$1[index].graph;
65722 stack$$1 = stack$$1.slice(0, index + 1);
65723 stack$$1.push(perform(arguments));
65726 return change(previous);
65730 replace: function() {
65731 var previous = stack$$1[index].graph;
65733 // assert(index == stack.length - 1)
65734 stack$$1[index] = perform(arguments);
65736 return change(previous);
65741 var previous = stack$$1[index].graph;
65746 return change(previous);
65751 // Same as calling pop and then perform
65752 overwrite: function() {
65753 var previous = stack$$1[index].graph;
65759 stack$$1 = stack$$1.slice(0, index + 1);
65760 stack$$1.push(perform(arguments));
65763 return change(previous);
65768 var previous = stack$$1[index].graph;
65770 // Pop to the next annotated state.
65771 while (index > 0) {
65773 if (stack$$1[index].annotation) break;
65776 dispatch$$1.call('undone', this, stack$$1[index]);
65777 return change(previous);
65782 var previous = stack$$1[index].graph;
65784 while (index < stack$$1.length - 1) {
65786 if (stack$$1[index].annotation) break;
65789 dispatch$$1.call('redone', this, stack$$1[index]);
65790 return change(previous);
65794 undoAnnotation: function() {
65797 if (stack$$1[i].annotation) return stack$$1[i].annotation;
65803 redoAnnotation: function() {
65805 while (i <= stack$$1.length - 1) {
65806 if (stack$$1[i].annotation) return stack$$1[i].annotation;
65812 intersects: function(extent$$1) {
65813 return tree$$1.intersects(extent$$1, stack$$1[index].graph);
65817 difference: function() {
65818 var base = stack$$1[0].graph,
65819 head = stack$$1[index].graph;
65820 return coreDifference(base, head);
65824 changes: function(action) {
65825 var base = stack$$1[0].graph,
65826 head = stack$$1[index].graph;
65829 head = action(head);
65832 var difference = coreDifference(base, head);
65835 modified: difference.modified(),
65836 created: difference.created(),
65837 deleted: difference.deleted()
65842 validate: function(changes) {
65843 return lodash(Validations)
65844 .map(function(fn) { return fn()(changes, stack$$1[index].graph); })
65850 hasChanges: function() {
65851 return this.difference().length() > 0;
65855 imageryUsed: function(sources) {
65857 imageryUsed = sources;
65860 return lodash(stack$$1.slice(1, index + 1))
65861 .map('imageryUsed')
65864 .without(undefined, 'Custom')
65870 reset: function() {
65871 stack$$1 = [{graph: coreGraph$$1()}];
65873 tree$$1 = coreTree(stack$$1[0].graph);
65874 dispatch$$1.call('change');
65879 toJSON: function() {
65880 if (!this.hasChanges()) return;
65882 var allEntities = {},
65884 base = stack$$1[0];
65886 var s = stack$$1.map(function(i) {
65887 var modified = [], deleted = [];
65889 lodash.forEach(i.graph.entities, function(entity, id) {
65891 var key = osmEntity$$1.key(entity);
65892 allEntities[key] = entity;
65893 modified.push(key);
65898 // make sure that the originals of changed or deleted entities get merged
65899 // into the base of the stack after restoring the data from JSON.
65900 if (id in base.graph.entities) {
65901 baseEntities[id] = base.graph.entities[id];
65903 // get originals of parent entities too
65904 lodash.forEach(base.graph._parentWays[id], function(parentId) {
65905 if (parentId in base.graph.entities) {
65906 baseEntities[parentId] = base.graph.entities[parentId];
65913 if (modified.length) x.modified = modified;
65914 if (deleted.length) x.deleted = deleted;
65915 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
65916 if (i.annotation) x.annotation = i.annotation;
65921 return JSON.stringify({
65923 entities: lodash.values(allEntities),
65924 baseEntities: lodash.values(baseEntities),
65926 nextIDs: osmEntity$$1.id.next,
65932 fromJSON: function(json$$1, loadChildNodes) {
65933 var h = JSON.parse(json$$1),
65934 loadComplete = true;
65936 osmEntity$$1.id.next = h.nextIDs;
65939 if (h.version === 2 || h.version === 3) {
65940 var allEntities = {};
65942 h.entities.forEach(function(entity) {
65943 allEntities[osmEntity$$1.key(entity)] = osmEntity$$1(entity);
65946 if (h.version === 3) {
65947 // This merges originals for changed entities into the base of
65948 // the stack even if the current stack doesn't have them (for
65949 // example when iD has been restarted in a different region)
65950 var baseEntities = h.baseEntities.map(function(d) { return osmEntity$$1(d); });
65951 stack$$1[0].graph.rebase(baseEntities, lodash.map(stack$$1, 'graph'), true);
65952 tree$$1.rebase(baseEntities, true);
65954 // When we restore a modified way, we also need to fetch any missing
65955 // childnodes that would normally have been downloaded with it.. #2142
65956 if (loadChildNodes) {
65957 var missing = lodash(baseEntities)
65958 .filter({ type: 'way' })
65962 .reject(function(n) { return stack$$1[0].graph.hasEntity(n); })
65965 if (!lodash.isEmpty(missing)) {
65966 loadComplete = false;
65967 context.redrawEnable(false);
65969 var loading = uiLoading(context).blocking(true);
65970 context.container().call(loading);
65972 var childNodesLoaded = function(err, result) {
65974 var visible = lodash.groupBy(result.data, 'visible');
65975 if (!lodash.isEmpty(visible.true)) {
65976 missing = lodash.difference(missing, lodash.map(visible.true, 'id'));
65977 stack$$1[0].graph.rebase(visible.true, lodash.map(stack$$1, 'graph'), true);
65978 tree$$1.rebase(visible.true, true);
65981 // fetch older versions of nodes that were deleted..
65982 lodash.each(visible.false, function(entity) {
65983 context.connection()
65984 .loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
65988 if (err || lodash.isEmpty(missing)) {
65990 context.redrawEnable(true);
65991 dispatch$$1.call('change');
65995 context.connection().loadMultiple(missing, childNodesLoaded);
66000 stack$$1 = h.stack.map(function(d) {
66001 var entities = {}, entity;
66004 d.modified.forEach(function(key) {
66005 entity = allEntities[key];
66006 entities[entity.id] = entity;
66011 d.deleted.forEach(function(id) {
66012 entities[id] = undefined;
66017 graph: coreGraph$$1(stack$$1[0].graph).load(entities),
66018 annotation: d.annotation,
66019 imageryUsed: d.imageryUsed
66023 } else { // original version
66024 stack$$1 = h.stack.map(function(d) {
66027 for (var i in d.entities) {
66028 var entity = d.entities[i];
66029 entities[i] = entity === 'undefined' ? undefined : osmEntity$$1(entity);
66032 d.graph = coreGraph$$1(stack$$1[0].graph).load(entities);
66037 if (loadComplete) {
66038 dispatch$$1.call('change');
66046 if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
66051 clearSaved: function() {
66052 context.debouncedSave.cancel();
66053 if (lock.locked()) context.storage(getKey('saved_history'), null);
66059 return lock.lock();
66063 unlock: function() {
66068 // is iD not open in another window and it detects that
66069 // there's a history stored in localStorage that's recoverable?
66070 restorableChanges: function() {
66071 return lock.locked() && !!context.storage(getKey('saved_history'));
66075 // load history from a version stored in localStorage
66076 restore: function() {
66077 if (!lock.locked()) return;
66079 var json$$1 = context.storage(getKey('saved_history'));
66080 if (json$$1) history.fromJSON(json$$1, true);
66091 return utilRebind(history, dispatch$$1, 'on');
66094 function presetCollection(collection) {
66095 var maxSearchResults = 50,
66096 maxSuggestionResults = 10;
66100 collection: collection,
66103 item: function(id) {
66104 return lodash.find(collection, function(d) {
66105 return d.id === id;
66110 matchGeometry: function(geometry) {
66111 return presetCollection(collection.filter(function(d) {
66112 return d.matchGeometry(geometry);
66117 search: function(value, geometry) {
66118 if (!value) return this;
66120 function leading(a) {
66121 var index = a.indexOf(value);
66122 return index === 0 || a[index - 1] === ' ';
66125 function suggestionName(name) {
66126 var nameArray = name.split(' - ');
66127 if (nameArray.length > 1) {
66128 name = nameArray.slice(0, nameArray.length - 1).join(' - ');
66130 return name.toLowerCase();
66134 value = value.toLowerCase();
66136 var searchable = lodash.filter(collection, function(a) {
66137 return a.searchable !== false && a.suggestion !== true;
66139 suggestions = lodash.filter(collection, function(a) {
66140 return a.suggestion === true;
66144 // matches value to preset.name
66145 var leading_name = lodash.filter(searchable, function(a) {
66146 return leading(a.name().toLowerCase());
66147 }).sort(function(a, b) {
66148 var i = a.name().toLowerCase().indexOf(value) - b.name().toLowerCase().indexOf(value);
66149 if (i === 0) return a.name().length - b.name().length;
66153 // matches value to preset.terms values
66154 var leading_terms = lodash.filter(searchable, function(a) {
66155 return lodash.some(a.terms() || [], leading);
66158 // matches value to preset.tags values
66159 var leading_tag_values = lodash.filter(searchable, function(a) {
66160 return lodash.some(lodash.without(lodash.values(a.tags || {}), '*'), leading);
66164 // finds close matches to value in preset.name
66165 var similar_name = searchable.map(function(a) {
66168 dist: utilEditDistance(value, a.name())
66170 }).filter(function(a) {
66171 return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
66172 }).sort(function(a, b) {
66173 return a.dist - b.dist;
66174 }).map(function(a) {
66178 // finds close matches to value in preset.terms
66179 var similar_terms = lodash.filter(searchable, function(a) {
66180 return lodash.some(a.terms() || [], function(b) {
66181 return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
66185 var leading_suggestions = lodash.filter(suggestions, function(a) {
66186 return leading(suggestionName(a.name()));
66187 }).sort(function(a, b) {
66188 a = suggestionName(a.name());
66189 b = suggestionName(b.name());
66190 var i = a.indexOf(value) - b.indexOf(value);
66191 if (i === 0) return a.length - b.length;
66195 var similar_suggestions = suggestions.map(function(a) {
66198 dist: utilEditDistance(value, suggestionName(a.name()))
66200 }).filter(function(a) {
66201 return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
66202 }).sort(function(a, b) {
66203 return a.dist - b.dist;
66204 }).map(function(a) {
66208 var other = presets.item(geometry);
66210 var results = leading_name.concat(
66212 leading_tag_values,
66213 leading_suggestions.slice(0, maxSuggestionResults + 5),
66216 similar_suggestions.slice(0, maxSuggestionResults)
66217 ).slice(0, maxSearchResults - 1);
66219 return presetCollection(lodash.uniq(results.concat(other)));
66227 function presetCategory(id, category, all) {
66228 category = lodash.clone(category);
66233 category.members = presetCollection(category.members.map(function(id) {
66234 return all.item(id);
66238 category.matchGeometry = function(geometry) {
66239 return category.geometry.indexOf(geometry) >= 0;
66243 category.matchScore = function() {
66248 category.name = function() {
66249 return t('presets.categories.' + id + '.name', {'default': id});
66253 category.terms = function() {
66261 function presetField(id, field) {
66262 field = lodash.clone(field);
66267 field.matchGeometry = function(geometry) {
66268 return !field.geometry || field.geometry === geometry;
66272 field.t = function(scope, options) {
66273 return t('presets.fields.' + id + '.' + scope, options);
66277 field.label = function() {
66278 return field.t('label', {'default': id});
66282 var placeholder = field.placeholder;
66283 field.placeholder = function() {
66284 return field.t('placeholder', {'default': placeholder});
66291 function presetPreset(id, preset, fields) {
66292 preset = lodash.clone(preset);
66295 preset.fields = (preset.fields || []).map(getFields);
66296 preset.geometry = (preset.geometry || []);
66299 function getFields(f) {
66304 preset.matchGeometry = function(geometry) {
66305 return preset.geometry.indexOf(geometry) >= 0;
66309 var matchScore = preset.matchScore || 1;
66310 preset.matchScore = function(entity) {
66311 var tags = preset.tags,
66314 for (var t$$1 in tags) {
66315 if (entity.tags[t$$1] === tags[t$$1]) {
66316 score += matchScore;
66317 } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
66318 score += matchScore / 2;
66328 preset.t = function(scope, options) {
66329 return t('presets.presets.' + id + '.' + scope, options);
66333 var name = preset.name || '';
66334 preset.name = function() {
66335 if (preset.suggestion) {
66336 id = id.split('/');
66337 id = id[0] + '/' + id[1];
66338 return name + ' - ' + t('presets.presets.' + id + '.name');
66340 return preset.t('name', {'default': name});
66344 preset.terms = function() {
66345 return preset.t('terms', {'default': ''}).toLowerCase().trim().split(/\s*,+\s*/);
66349 preset.isFallback = function() {
66350 var tagCount = Object.keys(preset.tags).length;
66351 return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
66355 preset.reference = function(geometry) {
66356 var key = Object.keys(preset.tags)[0],
66357 value = preset.tags[key];
66359 if (geometry === 'relation' && key === 'type') {
66360 if (value in preset.tags) {
66362 value = preset.tags[key];
66364 return { rtype: value };
66368 if (value === '*') {
66369 return { key: key };
66371 return { key: key, value: value };
66376 var removeTags = preset.removeTags || preset.tags;
66377 preset.removeTags = function(tags, geometry) {
66378 tags = lodash.omit(tags, lodash.keys(removeTags));
66380 for (var f in preset.fields) {
66381 var field = preset.fields[f];
66382 if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
66383 delete tags[field.key];
66392 var applyTags = preset.addTags || preset.tags;
66393 preset.applyTags = function(tags, geometry) {
66396 tags = lodash.clone(tags);
66398 for (k in applyTags) {
66399 if (applyTags[k] === '*') {
66402 tags[k] = applyTags[k];
66406 // Add area=yes if necessary.
66407 // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
66408 // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
66409 // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
66410 if (geometry === 'area') {
66411 var needsAreaTag = true;
66412 if (preset.geometry.indexOf('line') === -1) {
66413 for (k in applyTags) {
66414 if (k in areaKeys) {
66415 needsAreaTag = false;
66420 if (needsAreaTag) {
66425 for (var f in preset.fields) {
66426 var field = preset.fields[f];
66427 if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
66428 tags[field.key] = field.default;
66439 function presetIndex() {
66440 // a presetCollection with methods for
66441 // loading new data and returning defaults
66443 var all = presetCollection([]),
66444 defaults = { area: all, line: all, point: all, vertex: all, relation: all },
66447 recent = presetCollection([]);
66449 // Index of presets by (geometry, tag key).
66458 all.match = function(entity, resolver) {
66459 var geometry = entity.geometry(resolver);
66461 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
66462 if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
66463 geometry = 'point';
66466 var geometryMatches = index[geometry],
66470 for (var k in entity.tags) {
66471 var keyMatches = geometryMatches[k];
66472 if (!keyMatches) continue;
66474 for (var i = 0; i < keyMatches.length; i++) {
66475 var score = keyMatches[i].matchScore(entity);
66476 if (score > best) {
66478 match = keyMatches[i];
66483 return match || all.item(geometry);
66487 // Because of the open nature of tagging, iD will never have a complete
66488 // list of tags used in OSM, so we want it to have logic like "assume
66489 // that a closed way with an amenity tag is an area, unless the amenity
66490 // is one of these specific types". This function computes a structure
66491 // that allows testing of such conditions, based on the presets designated
66492 // as as supporting (or not supporting) the area geometry.
66494 // The returned object L is a whitelist/blacklist of tags. A closed way
66495 // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
66496 // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
66497 // and the subkeys form the blacklist.
66498 all.areaKeys = function() {
66500 ignore = ['barrier', 'highway', 'footway', 'railway', 'type'],
66501 presets = lodash.reject(all.collection, 'suggestion');
66504 presets.forEach(function(d) {
66505 for (var key in d.tags) break;
66507 if (ignore.indexOf(key) !== -1) return;
66509 if (d.geometry.indexOf('area') !== -1) {
66510 areaKeys[key] = areaKeys[key] || {};
66515 presets.forEach(function(d) {
66516 for (var key in d.tags) break;
66518 if (ignore.indexOf(key) !== -1) return;
66520 var value = d.tags[key];
66521 if (d.geometry.indexOf('area') === -1 &&
66522 d.geometry.indexOf('line') !== -1 &&
66523 key in areaKeys && value !== '*') {
66524 areaKeys[key][value] = true;
66532 all.init = function() {
66533 var d = data.presets;
66536 lodash.forEach(d.fields, function(d, id) {
66537 fields[id] = presetField(id, d);
66538 if (d.universal) universal.push(fields[id]);
66543 lodash.forEach(d.presets, function(d, id) {
66544 all.collection.push(presetPreset(id, d, fields));
66548 if (d.categories) {
66549 lodash.forEach(d.categories, function(d, id) {
66550 all.collection.push(presetCategory(id, d, all));
66555 var getItem = lodash.bind(all.item, all);
66557 area: presetCollection(d.defaults.area.map(getItem)),
66558 line: presetCollection(d.defaults.line.map(getItem)),
66559 point: presetCollection(d.defaults.point.map(getItem)),
66560 vertex: presetCollection(d.defaults.vertex.map(getItem)),
66561 relation: presetCollection(d.defaults.relation.map(getItem))
66565 for (var i = 0; i < all.collection.length; i++) {
66566 var preset = all.collection[i],
66567 geometry = preset.geometry;
66569 for (var j = 0; j < geometry.length; j++) {
66570 var g = index[geometry[j]];
66571 for (var k in preset.tags) {
66572 (g[k] = g[k] || []).push(preset);
66580 all.field = function(id) {
66584 all.universal = function() {
66588 all.defaults = function(geometry, n) {
66589 var rec = recent.matchGeometry(geometry).collection.slice(0, 4),
66590 def = lodash.uniq(rec.concat(defaults[geometry].collection)).slice(0, n - 1);
66591 return presetCollection(lodash.uniq(rec.concat(def).concat(all.item(geometry))));
66594 all.choose = function(preset) {
66595 if (!preset.isFallback()) {
66596 recent = presetCollection(lodash.uniq([preset].concat(recent.collection)));
66606 function setAreaKeys(value) {
66611 function coreContext() {
66612 addTranslation('en', en);
66615 var dispatch$$1 = dispatch('enter', 'exit', 'change'),
66618 // https://github.com/openstreetmap/iD/issues/772
66619 // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
66621 try { storage = localStorage; } catch (e) {} // eslint-disable-line no-empty
66622 storage = storage || (function() {
66625 getItem: function(k) { return s[k]; },
66626 setItem: function(k, v) { s[k] = v; },
66627 removeItem: function(k) { delete s[k]; }
66631 context.storage = function(k, v) {
66633 if (arguments.length === 1) return storage.getItem(k);
66634 else if (v === null) storage.removeItem(k);
66635 else storage.setItem(k, v);
66637 // localstorage quota exceeded
66638 /* eslint-disable no-console */
66639 if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
66640 /* eslint-enable no-console */
66645 /* Straight accessors. Avoid using these if you can. */
66646 var ui, connection, history;
66647 context.ui = function() { return ui; };
66648 context.connection = function() { return connection; };
66649 context.history = function() { return history; };
66653 function entitiesLoaded(err, result) {
66654 if (!err) history.merge(result.data, result.extent);
66657 context.preauth = function(options) {
66658 connection.switch(options);
66662 context.loadTiles = function(projection, dimensions, callback) {
66663 function done(err, result) {
66664 entitiesLoaded(err, result);
66665 if (callback) callback(err, result);
66667 connection.loadTiles(projection, dimensions, done);
66670 context.loadEntity = function(id, callback) {
66671 function done(err, result) {
66672 entitiesLoaded(err, result);
66673 if (callback) callback(err, result);
66675 connection.loadEntity(id, done);
66678 context.zoomToEntity = function(id, zoomTo) {
66679 if (zoomTo !== false) {
66680 this.loadEntity(id, function(err, result) {
66682 var entity = lodash.find(result.data, function(e) { return e.id === id; });
66683 if (entity) { map$$1.zoomTo(entity); }
66687 map$$1.on('drawn.zoomToEntity', function() {
66688 if (!context.hasEntity(id)) return;
66689 map$$1.on('drawn.zoomToEntity', null);
66690 context.on('enter.zoomToEntity', null);
66691 context.enter(modeSelect(context, [id]));
66694 context.on('enter.zoomToEntity', function() {
66695 if (mode.id !== 'browse') {
66696 map$$1.on('drawn.zoomToEntity', null);
66697 context.on('enter.zoomToEntity', null);
66702 var minEditableZoom = 16;
66703 context.minEditableZoom = function(_) {
66704 if (!arguments.length) return minEditableZoom;
66705 minEditableZoom = _;
66706 connection.tileZoom(_);
66712 var inIntro = false;
66713 context.inIntro = function(_) {
66714 if (!arguments.length) return inIntro;
66719 context.save = function() {
66720 if (inIntro || (mode && mode.id === 'save') || select('.modal').size()) return;
66722 if (history.hasChanges()) return t('save.unsaved_changes');
66727 context.hasEntity = function(id) {
66728 return history.graph().hasEntity(id);
66730 context.entity = function(id) {
66731 return history.graph().entity(id);
66733 context.childNodes = function(way) {
66734 return history.graph().childNodes(way);
66736 context.geometry = function(id) {
66737 return context.entity(id).geometry(history.graph());
66743 context.mode = function() {
66746 context.enter = function(newMode) {
66749 dispatch$$1.call('exit', this, mode);
66754 dispatch$$1.call('enter', this, mode);
66757 context.selectedIDs = function() {
66758 if (mode && mode.selectedIDs) {
66759 return mode.selectedIDs();
66767 context.install = function(behavior) {
66768 context.surface().call(behavior);
66770 context.uninstall = function(behavior) {
66771 context.surface().call(behavior.off);
66776 var copyIDs = [], copyGraph;
66777 context.copyGraph = function() { return copyGraph; };
66778 context.copyIDs = function(_) {
66779 if (!arguments.length) return copyIDs;
66781 copyGraph = history.graph();
66788 context.background = function() { return background; };
66793 context.features = function() { return features; };
66794 context.hasHiddenConnections = function(id) {
66795 var graph = history.graph(),
66796 entity = graph.entity(id);
66797 return features.hasHiddenConnections(entity, graph);
66803 context.presets = function() { return presets; };
66808 context.map = function() { return map$$1; };
66809 context.layers = function() { return map$$1.layers; };
66810 context.surface = function() { return map$$1.surface; };
66811 context.editable = function() { return map$$1.editable(); };
66813 context.surfaceRect = function() {
66814 // Work around a bug in Firefox.
66815 // http://stackoverflow.com/questions/18153989/
66816 // https://bugzilla.mozilla.org/show_bug.cgi?id=530985
66817 return context.surface().node().parentNode.getBoundingClientRect();
66829 context.debugFlags = function() {
66832 context.setDebug = function(flag, val) {
66833 if (arguments.length === 1) val = true;
66834 debugFlags[flag] = val;
66835 dispatch$$1.call('change');
66838 context.getDebug = function(flag) {
66839 return flag && debugFlags[flag];
66844 var container, embed;
66845 context.container = function(_) {
66846 if (!arguments.length) return container;
66848 container.classed('id-container', true);
66851 context.embed = function(_) {
66852 if (!arguments.length) return embed;
66859 var assetPath = '';
66860 context.assetPath = function(_) {
66861 if (!arguments.length) return assetPath;
66867 context.assetMap = function(_) {
66868 if (!arguments.length) return assetMap;
66873 context.asset = function(_) {
66874 var filename = assetPath + _;
66875 return assetMap[filename] || filename;
66878 context.imagePath = function(_) {
66879 return context.asset('img/' + _);
66884 // `locale` variable contains a "requested locale".
66885 // It won't become the `currentLocale` until after loadLocale() is called.
66886 var locale, localePath;
66888 context.locale = function(loc, path$$1) {
66889 if (!arguments.length) return currentLocale;
66891 localePath = path$$1;
66895 context.loadLocale = function(callback) {
66896 if (locale && locale !== 'en' && dataLocales.hasOwnProperty(locale)) {
66897 localePath = localePath || context.asset('locales/' + locale + '.json');
66898 json(localePath, function(err, result) {
66900 addTranslation(locale, result[locale]);
66920 /* reset (aka flush) */
66921 context.reset = context.flush = function() {
66922 context.debouncedSave.cancel();
66923 lodash.each(services, function(service) {
66924 if (service && typeof service.reset === 'function') {
66925 service.reset(context);
66935 context.version = '2.0.2';
66937 context.projection = geoRawMercator();
66939 locale = utilDetect().locale;
66940 if (locale && !dataLocales.hasOwnProperty(locale)) {
66941 locale = locale.split('-')[0];
66944 history = coreHistory(context);
66945 context.graph = history.graph;
66946 context.changes = history.changes;
66947 context.intersects = history.intersects;
66949 // Debounce save, since it's a synchronous localStorage write,
66950 // and history changes can happen frequently (e.g. when dragging).
66951 context.debouncedSave = lodash.debounce(context.save, 350);
66952 function withDebouncedSave(fn) {
66953 return function() {
66954 var result = fn.apply(history, arguments);
66955 context.debouncedSave();
66960 context.perform = withDebouncedSave(history.perform);
66961 context.replace = withDebouncedSave(history.replace);
66962 context.pop = withDebouncedSave(history.pop);
66963 context.overwrite = withDebouncedSave(history.overwrite);
66964 context.undo = withDebouncedSave(history.undo);
66965 context.redo = withDebouncedSave(history.redo);
66967 ui = uiInit(context);
66969 connection = services.osm;
66970 background = rendererBackground(context);
66971 features = rendererFeatures(context);
66972 presets = presetIndex();
66974 map$$1 = rendererMap(context);
66975 context.mouse = map$$1.mouse;
66976 context.extent = map$$1.extent;
66977 context.pan = map$$1.pan;
66978 context.zoomIn = map$$1.zoomIn;
66979 context.zoomOut = map$$1.zoomOut;
66980 context.zoomInFurther = map$$1.zoomInFurther;
66981 context.zoomOutFurther = map$$1.zoomOutFurther;
66982 context.redrawEnable = map$$1.redrawEnable;
66984 lodash.each(services, function(service) {
66985 if (service && typeof service.init === 'function') {
66986 service.init(context);
66992 areaKeys = presets.areaKeys();
66995 return utilRebind(context, dispatch$$1, 'on');
66998 function osmWay() {
66999 if (!(this instanceof osmWay)) {
67000 return (new osmWay()).initialize(arguments);
67001 } else if (arguments.length) {
67002 this.initialize(arguments);
67007 osmEntity$$1.way = osmWay;
67009 osmWay.prototype = Object.create(osmEntity$$1.prototype);
67012 lodash.extend(osmWay.prototype, {
67017 copy: function(resolver, copies) {
67018 if (copies[this.id])
67019 return copies[this.id];
67021 var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
67023 var nodes = this.nodes.map(function(id) {
67024 return resolver.entity(id).copy(resolver, copies).id;
67027 copy = copy.update({ nodes: nodes });
67028 copies[this.id] = copy;
67034 extent: function(resolver) {
67035 return resolver.transient(this, 'extent', function() {
67036 var extent$$1 = geoExtent$$1();
67037 for (var i = 0; i < this.nodes.length; i++) {
67038 var node = resolver.hasEntity(this.nodes[i]);
67040 extent$$1._extend(node.extent());
67048 first: function() {
67049 return this.nodes[0];
67054 return this.nodes[this.nodes.length - 1];
67058 contains: function(node) {
67059 return this.nodes.indexOf(node) >= 0;
67063 affix: function(node) {
67064 if (this.nodes[0] === node) return 'prefix';
67065 if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
67069 layer: function() {
67070 // explicit layer tag, clamp between -10, 10..
67071 if (isFinite(this.tags.layer)) {
67072 return Math.max(-10, Math.min(+(this.tags.layer), 10));
67075 // implied layer tag..
67076 if (this.tags.location === 'overground') return 1;
67077 if (this.tags.location === 'underground') return -1;
67078 if (this.tags.location === 'underwater') return -10;
67080 if (this.tags.power === 'line') return 10;
67081 if (this.tags.power === 'minor_line') return 10;
67082 if (this.tags.aerialway) return 10;
67083 if (this.tags.bridge) return 1;
67084 if (this.tags.cutting) return -1;
67085 if (this.tags.tunnel) return -1;
67086 if (this.tags.waterway) return -1;
67087 if (this.tags.man_made === 'pipeline') return -10;
67088 if (this.tags.boundary) return -10;
67093 isOneWay: function() {
67094 // explicit oneway tag..
67095 if (['yes', '1', '-1'].indexOf(this.tags.oneway) !== -1) { return true; }
67096 if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; }
67098 // implied oneway tag..
67099 for (var key in this.tags) {
67100 if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
67107 lanes: function() {
67108 return osmLanes(this);
67112 isClosed: function() {
67113 return this.nodes.length > 0 && this.first() === this.last();
67117 isConvex: function(resolver) {
67118 if (!this.isClosed() || this.isDegenerate()) return null;
67120 var nodes = lodash.uniq(resolver.childNodes(this)),
67121 coords = lodash.map(nodes, 'loc'),
67122 curr = 0, prev = 0;
67124 for (var i = 0; i < coords.length; i++) {
67125 var o = coords[(i+1) % coords.length],
67127 b = coords[(i+2) % coords.length],
67128 res = geoCross(o, a, b);
67130 curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
67133 } else if (prev && curr !== prev) {
67142 isArea: function() {
67143 if (this.tags.area === 'yes')
67145 if (!this.isClosed() || this.tags.area === 'no')
67147 for (var key in this.tags) {
67148 if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
67156 isDegenerate: function() {
67157 return lodash.uniq(this.nodes).length < (this.isArea() ? 3 : 2);
67161 areAdjacent: function(n1, n2) {
67162 for (var i = 0; i < this.nodes.length; i++) {
67163 if (this.nodes[i] === n1) {
67164 if (this.nodes[i - 1] === n2) return true;
67165 if (this.nodes[i + 1] === n2) return true;
67172 geometry: function(graph) {
67173 return graph.transient(this, 'geometry', function() {
67174 return this.isArea() ? 'area' : 'line';
67179 addNode: function(id, index) {
67180 var nodes = this.nodes.slice();
67181 nodes.splice(index === undefined ? nodes.length : index, 0, id);
67182 return this.update({nodes: nodes});
67186 updateNode: function(id, index) {
67187 var nodes = this.nodes.slice();
67188 nodes.splice(index, 1, id);
67189 return this.update({nodes: nodes});
67193 replaceNode: function(needle, replacement) {
67194 if (this.nodes.indexOf(needle) < 0)
67197 var nodes = this.nodes.slice();
67198 for (var i = 0; i < nodes.length; i++) {
67199 if (nodes[i] === needle) {
67200 nodes[i] = replacement;
67203 return this.update({nodes: nodes});
67207 removeNode: function(id) {
67210 for (var i = 0; i < this.nodes.length; i++) {
67211 var node = this.nodes[i];
67212 if (node !== id && nodes[nodes.length - 1] !== node) {
67217 // Preserve circularity
67218 if (this.nodes.length > 1 && this.first() === id && this.last() === id && nodes[nodes.length - 1] !== nodes[0]) {
67219 nodes.push(nodes[0]);
67222 return this.update({nodes: nodes});
67226 asJXON: function(changeset_id) {
67229 '@id': this.osmId(),
67230 '@version': this.version || 0,
67231 nd: lodash.map(this.nodes, function(id) {
67232 return { keyAttributes: { ref: osmEntity$$1.id.toOSM(id) } };
67234 tag: lodash.map(this.tags, function(v, k) {
67235 return { keyAttributes: { k: k, v: v } };
67239 if (changeset_id) r.way['@changeset'] = changeset_id;
67244 asGeoJSON: function(resolver) {
67245 return resolver.transient(this, 'GeoJSON', function() {
67246 var coordinates = lodash.map(resolver.childNodes(this), 'loc');
67247 if (this.isArea() && this.isClosed()) {
67250 coordinates: [coordinates]
67254 type: 'LineString',
67255 coordinates: coordinates
67262 area: function(resolver) {
67263 return resolver.transient(this, 'area', function() {
67264 var nodes = resolver.childNodes(this);
67268 coordinates: [lodash.map(nodes, 'loc')]
67271 if (!this.isClosed() && nodes.length) {
67272 json$$1.coordinates[0].push(nodes[0].loc);
67275 var area$$1 = area$1(json$$1);
67277 // Heuristic for detecting counterclockwise winding order. Assumes
67278 // that OpenStreetMap polygons are not hemisphere-spanning.
67279 if (area$$1 > 2 * Math.PI) {
67280 json$$1.coordinates[0] = json$$1.coordinates[0].reverse();
67281 area$$1 = area$1(json$$1);
67284 return isNaN(area$$1) ? 0 : area$$1;
67289 function osmTurn(turn) {
67290 if (!(this instanceof osmTurn))
67291 return new osmTurn(turn);
67292 lodash.extend(this, turn);
67296 function osmIntersection(graph, vertexId) {
67297 var vertex = graph.entity(vertexId),
67298 parentWays = graph.parentWays(vertex),
67302 function addHighway(way, adjacentNodeId) {
67303 if (highways[adjacentNodeId]) {
67304 coincident.push(adjacentNodeId);
67306 highways[adjacentNodeId] = way;
67310 // Pre-split ways that would need to be split in
67311 // order to add a restriction. The real split will
67312 // happen when the restriction is added.
67313 parentWays.forEach(function(way) {
67314 if (!way.tags.highway || way.isArea() || way.isDegenerate())
67317 var isFirst = (vertexId === way.first()),
67318 isLast = (vertexId === way.last()),
67319 isAffix = (isFirst || isLast),
67320 isClosingNode = (isFirst && isLast);
67322 if (isAffix && !isClosingNode) {
67323 var index = (isFirst ? 1 : way.nodes.length - 2);
67324 addHighway(way, way.nodes[index]);
67327 var splitIndex, wayA, wayB, indexA, indexB;
67328 if (isClosingNode) {
67329 splitIndex = Math.ceil(way.nodes.length / 2); // split at midpoint
67330 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
67331 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
67333 indexB = way.nodes.length - 2;
67335 splitIndex = lodash.indexOf(way.nodes, vertex.id, 1); // split at vertexid
67336 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
67337 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
67338 indexA = splitIndex - 1;
67339 indexB = splitIndex + 1;
67341 graph = graph.replace(wayA).replace(wayB);
67342 addHighway(wayA, way.nodes[indexA]);
67343 addHighway(wayB, way.nodes[indexB]);
67347 // remove any ways from this intersection that are coincident
67348 // (i.e. any adjacent node used by more than one intersecting way)
67349 coincident.forEach(function (n) {
67350 delete highways[n];
67354 var intersection = {
67355 highways: highways,
67356 ways: lodash.values(highways),
67361 intersection.adjacentNodeId = function(fromWayId) {
67362 return lodash.find(lodash.keys(highways), function(k) {
67363 return highways[k].id === fromWayId;
67368 intersection.turns = function(fromNodeId) {
67369 var start = highways[fromNodeId];
67373 if (start.first() === vertex.id && start.tags.oneway === 'yes')
67375 if (start.last() === vertex.id && start.tags.oneway === '-1')
67378 function withRestriction(turn) {
67379 graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
67380 if (relation.tags.type !== 'restriction')
67383 var f = relation.memberByRole('from'),
67384 t = relation.memberByRole('to'),
67385 v = relation.memberByRole('via');
67387 if (f && f.id === turn.from.way &&
67388 v && v.id === turn.via.node &&
67389 t && t.id === turn.to.way) {
67390 turn.restriction = relation.id;
67391 } else if (/^only_/.test(relation.tags.restriction) &&
67392 f && f.id === turn.from.way &&
67393 v && v.id === turn.via.node &&
67394 t && t.id !== turn.to.way) {
67395 turn.restriction = relation.id;
67396 turn.indirect_restriction = true;
67400 return osmTurn(turn);
67406 way: start.id.split(/-(a|b)/)[0]
67408 via = { node: vertex.id },
67411 lodash.each(highways, function(end, adjacentNodeId) {
67416 if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
67417 turns.push(withRestriction({
67421 node: adjacentNodeId,
67422 way: end.id.split(/-(a|b)/)[0]
67428 if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
67429 turns.push(withRestriction({
67433 node: adjacentNodeId,
67434 way: end.id.split(/-(a|b)/)[0]
67442 if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
67443 turns.push(withRestriction({
67454 return intersection;
67458 function osmInferRestriction(graph, from, via, to, projection) {
67459 var fromWay = graph.entity(from.way),
67460 fromNode = graph.entity(from.node),
67461 toWay = graph.entity(to.way),
67462 toNode = graph.entity(to.node),
67463 viaNode = graph.entity(via.node),
67464 fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
67465 (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
67466 toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
67467 (toWay.tags.oneway === '-1' && toWay.last() === via.node),
67468 angle = geoAngle(viaNode, fromNode, projection) -
67469 geoAngle(viaNode, toNode, projection);
67471 angle = angle * 180 / Math.PI;
67476 if (fromNode === toNode)
67477 return 'no_u_turn';
67478 if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
67479 return 'no_u_turn';
67481 return 'no_right_turn';
67483 return 'no_left_turn';
67485 return 'no_straight_on';
67488 function actionAddMember(relationId, member, memberIndex) {
67489 return function(graph) {
67490 var relation = graph.entity(relationId);
67492 if (isNaN(memberIndex) && member.type === 'way') {
67493 var members = relation.indexedMembers();
67494 members.push(member);
67496 var joined = osmJoinWays(members, graph);
67497 for (var i = 0; i < joined.length; i++) {
67498 var segment = joined[i];
67499 for (var j = 0; j < segment.length && segment.length >= 2; j++) {
67500 if (segment[j] !== member)
67504 memberIndex = segment[j + 1].index;
67505 } else if (j === segment.length - 1) {
67506 memberIndex = segment[j - 1].index + 1;
67508 memberIndex = Math.min(segment[j - 1].index + 1, segment[j + 1].index + 1);
67514 return graph.replace(relation.addMember(member, memberIndex));
67518 function actionAddMidpoint(midpoint, node) {
67519 return function(graph) {
67520 graph = graph.replace(node.move(midpoint.loc));
67522 var parents = lodash.intersection(
67523 graph.parentWays(graph.entity(midpoint.edge[0])),
67524 graph.parentWays(graph.entity(midpoint.edge[1])));
67526 parents.forEach(function(way) {
67527 for (var i = 0; i < way.nodes.length - 1; i++) {
67528 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
67529 graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
67531 // Add only one midpoint on doubled-back segments,
67532 // turning them into self-intersections.
67542 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
67543 function actionAddVertex(wayId, nodeId, index) {
67544 return function(graph) {
67545 return graph.replace(graph.entity(wayId).addNode(nodeId, index));
67549 function actionChangeMember(relationId, member, memberIndex) {
67550 return function(graph) {
67551 return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
67555 function actionChangePreset(entityId, oldPreset, newPreset) {
67556 return function(graph) {
67557 var entity = graph.entity(entityId),
67558 geometry = entity.geometry(graph),
67559 tags = entity.tags;
67561 if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
67562 if (newPreset) tags = newPreset.applyTags(tags, geometry);
67564 return graph.replace(entity.update({tags: tags}));
67568 function actionChangeTags(entityId, tags) {
67569 return function(graph) {
67570 var entity = graph.entity(entityId);
67571 return graph.replace(entity.update({tags: tags}));
67575 function actionCircularize(wayId, projection, maxAngle) {
67576 maxAngle = (maxAngle || 20) * Math.PI / 180;
67579 var action = function(graph) {
67580 var way = graph.entity(wayId);
67582 if (!way.isConvex(graph)) {
67583 graph = action.makeConvex(graph);
67586 var nodes = lodash.uniq(graph.childNodes(way)),
67587 keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
67588 points = nodes.map(function(n) { return projection(n.loc); }),
67589 keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
67590 centroid = (points.length === 2) ? geoInterp(points[0], points[1], 0.5) : d3polygonCentroid(points),
67591 radius = median(points, function(p) { return geoEuclideanDistance(centroid, p); }),
67592 sign = d3polygonArea(points) > 0 ? 1 : -1,
67595 // we need atleast two key nodes for the algorithm to work
67596 if (!keyNodes.length) {
67597 keyNodes = [nodes[0]];
67598 keyPoints = [points[0]];
67601 if (keyNodes.length === 1) {
67602 var index = nodes.indexOf(keyNodes[0]),
67603 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
67605 keyNodes.push(nodes[oppositeIndex]);
67606 keyPoints.push(points[oppositeIndex]);
67609 // key points and nodes are those connected to the ways,
67610 // they are projected onto the circle, inbetween nodes are moved
67611 // to constant intervals between key nodes, extra inbetween nodes are
67612 // added if necessary.
67613 for (var i = 0; i < keyPoints.length; i++) {
67614 var nextKeyNodeIndex = (i + 1) % keyNodes.length,
67615 startNode = keyNodes[i],
67616 endNode = keyNodes[nextKeyNodeIndex],
67617 startNodeIndex = nodes.indexOf(startNode),
67618 endNodeIndex = nodes.indexOf(endNode),
67619 numberNewPoints = -1,
67620 indexRange = endNodeIndex - startNodeIndex,
67621 distance, totalAngle, eachAngle, startAngle, endAngle,
67622 angle, loc, node, j,
67623 inBetweenNodes = [];
67625 if (indexRange < 0) {
67626 indexRange += nodes.length;
67629 // position this key node
67630 distance = geoEuclideanDistance(centroid, keyPoints[i]);
67631 if (distance === 0) { distance = 1e-4; }
67633 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
67634 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius];
67635 graph = graph.replace(keyNodes[i].move(projection.invert(keyPoints[i])));
67637 // figure out the between delta angle we want to match to
67638 startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
67639 endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
67640 totalAngle = endAngle - startAngle;
67642 // detects looping around -pi/pi
67643 if (totalAngle * sign > 0) {
67644 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
67649 eachAngle = totalAngle / (indexRange + numberNewPoints);
67650 } while (Math.abs(eachAngle) > maxAngle);
67652 // move existing points
67653 for (j = 1; j < indexRange; j++) {
67654 angle = startAngle + j * eachAngle;
67655 loc = projection.invert([
67656 centroid[0] + Math.cos(angle)*radius,
67657 centroid[1] + Math.sin(angle)*radius]);
67659 node = nodes[(j + startNodeIndex) % nodes.length].move(loc);
67660 graph = graph.replace(node);
67663 // add new inbetween nodes if necessary
67664 for (j = 0; j < numberNewPoints; j++) {
67665 angle = startAngle + (indexRange + j) * eachAngle;
67666 loc = projection.invert([
67667 centroid[0] + Math.cos(angle) * radius,
67668 centroid[1] + Math.sin(angle) * radius]);
67670 node = osmNode({loc: loc});
67671 graph = graph.replace(node);
67673 nodes.splice(endNodeIndex + j, 0, node);
67674 inBetweenNodes.push(node.id);
67677 // Check for other ways that share these keyNodes..
67678 // If keyNodes are adjacent in both ways,
67679 // we can add inBetween nodes to that shared way too..
67680 if (indexRange === 1 && inBetweenNodes.length) {
67681 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
67682 endIndex1 = way.nodes.lastIndexOf(endNode.id),
67683 wayDirection1 = (endIndex1 - startIndex1);
67684 if (wayDirection1 < -1) { wayDirection1 = 1; }
67686 /* eslint-disable no-loop-func */
67687 lodash.each(lodash.without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
67688 if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
67689 var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
67690 endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
67691 wayDirection2 = (endIndex2 - startIndex2),
67692 insertAt = endIndex2;
67693 if (wayDirection2 < -1) { wayDirection2 = 1; }
67695 if (wayDirection1 !== wayDirection2) {
67696 inBetweenNodes.reverse();
67697 insertAt = startIndex2;
67699 for (j = 0; j < inBetweenNodes.length; j++) {
67700 sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
67702 graph = graph.replace(sharedWay);
67705 /* eslint-enable no-loop-func */
67710 // update the way to have all the new nodes
67711 ids = nodes.map(function(n) { return n.id; });
67714 way = way.update({nodes: ids});
67715 graph = graph.replace(way);
67721 action.makeConvex = function(graph) {
67722 var way = graph.entity(wayId),
67723 nodes = lodash.uniq(graph.childNodes(way)),
67724 points = nodes.map(function(n) { return projection(n.loc); }),
67725 sign = d3polygonArea(points) > 0 ? 1 : -1,
67726 hull = d3polygonHull(points);
67728 // D3 convex hulls go counterclockwise..
67734 for (var i = 0; i < hull.length - 1; i++) {
67735 var startIndex = points.indexOf(hull[i]),
67736 endIndex = points.indexOf(hull[i+1]),
67737 indexRange = (endIndex - startIndex);
67739 if (indexRange < 0) {
67740 indexRange += nodes.length;
67743 // move interior nodes to the surface of the convex hull..
67744 for (var j = 1; j < indexRange; j++) {
67745 var point = geoInterp(hull[i], hull[i+1], j / indexRange),
67746 node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
67747 graph = graph.replace(node);
67754 action.disabled = function(graph) {
67755 if (!graph.entity(wayId).isClosed())
67756 return 'not_closed';
67763 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
67764 function actionDeleteWay(wayId) {
67767 function canDeleteNode(node, graph) {
67768 return !graph.parentWays(node).length &&
67769 !graph.parentRelations(node).length &&
67770 !node.hasInterestingTags();
67774 var action = function(graph) {
67775 var way = graph.entity(wayId);
67777 graph.parentRelations(way)
67778 .forEach(function(parent) {
67779 parent = parent.removeMembersWithID(wayId);
67780 graph = graph.replace(parent);
67782 if (parent.isDegenerate()) {
67783 graph = actionDeleteRelation(parent.id)(graph);
67787 lodash.uniq(way.nodes).forEach(function(nodeId) {
67788 graph = graph.replace(way.removeNode(nodeId));
67790 var node = graph.entity(nodeId);
67791 if (canDeleteNode(node, graph)) {
67792 graph = graph.remove(node);
67796 return graph.remove(way);
67800 action.disabled = function(graph) {
67801 var disabled = false;
67803 graph.parentRelations(graph.entity(wayId)).forEach(function(parent) {
67804 var type = parent.tags.type,
67805 role = parent.memberById(wayId).role || 'outer';
67806 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
67807 disabled = 'part_of_relation';
67818 function actionDeleteMultiple(ids) {
67820 way: actionDeleteWay,
67821 node: actionDeleteNode,
67822 relation: actionDeleteRelation
67826 var action = function(graph) {
67827 ids.forEach(function(id) {
67828 if (graph.hasEntity(id)) { // It may have been deleted aready.
67829 graph = actions[graph.entity(id).type](id)(graph);
67837 action.disabled = function(graph) {
67838 for (var i = 0; i < ids.length; i++) {
67840 disabled = actions[graph.entity(id).type](id).disabled(graph);
67841 if (disabled) return disabled;
67849 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
67850 function actionDeleteRelation(relationId) {
67853 function canDeleteEntity(entity, graph) {
67854 return !graph.parentWays(entity).length &&
67855 !graph.parentRelations(entity).length &&
67856 !entity.hasInterestingTags();
67860 var action = function(graph) {
67861 var relation = graph.entity(relationId);
67863 graph.parentRelations(relation)
67864 .forEach(function(parent) {
67865 parent = parent.removeMembersWithID(relationId);
67866 graph = graph.replace(parent);
67868 if (parent.isDegenerate()) {
67869 graph = actionDeleteRelation(parent.id)(graph);
67873 lodash.uniq(lodash.map(relation.members, 'id')).forEach(function(memberId) {
67874 graph = graph.replace(relation.removeMembersWithID(memberId));
67876 var entity = graph.entity(memberId);
67877 if (canDeleteEntity(entity, graph)) {
67878 graph = actionDeleteMultiple([memberId])(graph);
67882 return graph.remove(relation);
67886 action.disabled = function(graph) {
67887 if (!graph.entity(relationId).isComplete(graph))
67888 return 'incomplete_relation';
67895 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
67896 function actionDeleteNode(nodeId) {
67897 var action = function(graph) {
67898 var node = graph.entity(nodeId);
67900 graph.parentWays(node)
67901 .forEach(function(parent) {
67902 parent = parent.removeNode(nodeId);
67903 graph = graph.replace(parent);
67905 if (parent.isDegenerate()) {
67906 graph = actionDeleteWay(parent.id)(graph);
67910 graph.parentRelations(node)
67911 .forEach(function(parent) {
67912 parent = parent.removeMembersWithID(nodeId);
67913 graph = graph.replace(parent);
67915 if (parent.isDegenerate()) {
67916 graph = actionDeleteRelation(parent.id)(graph);
67920 return graph.remove(node);
67924 action.disabled = function() {
67932 // Connect the ways at the given nodes.
67934 // The last node will survive. All other nodes will be replaced with
67935 // the surviving node in parent ways, and then removed.
67937 // Tags and relation memberships of of non-surviving nodes are merged
67938 // to the survivor.
67940 // This is the inverse of `iD.actionDisconnect`.
67943 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
67944 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
67946 function actionConnect(nodeIds) {
67947 return function(graph) {
67948 var survivor = graph.entity(lodash.last(nodeIds));
67950 for (var i = 0; i < nodeIds.length - 1; i++) {
67951 var node = graph.entity(nodeIds[i]);
67953 /* eslint-disable no-loop-func */
67954 graph.parentWays(node).forEach(function(parent) {
67955 if (!parent.areAdjacent(node.id, survivor.id)) {
67956 graph = graph.replace(parent.replaceNode(node.id, survivor.id));
67960 graph.parentRelations(node).forEach(function(parent) {
67961 graph = graph.replace(parent.replaceMember(node, survivor));
67963 /* eslint-enable no-loop-func */
67965 survivor = survivor.mergeTags(node.tags);
67966 graph = actionDeleteNode(node.id)(graph);
67969 graph = graph.replace(survivor);
67975 function actionCopyEntities(ids, fromGraph) {
67979 var action = function(graph) {
67980 ids.forEach(function(id) {
67981 fromGraph.entity(id).copy(fromGraph, copies);
67984 for (var id in copies) {
67985 graph = graph.replace(copies[id]);
67992 action.copies = function() {
68000 function actionDeleteMember(relationId, memberIndex) {
68001 return function(graph) {
68002 var relation = graph.entity(relationId)
68003 .removeMember(memberIndex);
68005 graph = graph.replace(relation);
68007 if (relation.isDegenerate())
68008 graph = actionDeleteRelation(relation.id)(graph);
68014 function actionDeprecateTags(entityId) {
68016 return function(graph) {
68017 var entity = graph.entity(entityId),
68018 newtags = lodash.clone(entity.tags),
68022 // This handles dataDeprecated tags with a single condition
68023 for (var i = 0; i < dataDeprecated.length; i++) {
68025 rule = dataDeprecated[i];
68026 var match = lodash.toPairs(rule.old)[0],
68027 replacements = rule.replace ? lodash.toPairs(rule.replace) : null;
68029 if (entity.tags[match[0]] && match[1] === '*') {
68031 var value = entity.tags[match[0]];
68032 if (replacements && !newtags[replacements[0][0]]) {
68033 newtags[replacements[0][0]] = value;
68035 delete newtags[match[0]];
68038 } else if (entity.tags[match[0]] === match[1]) {
68039 newtags = lodash.assign({}, rule.replace || {}, lodash.omit(newtags, match[0]));
68045 return graph.replace(entity.update({tags: newtags}));
68052 function actionDiscardTags(difference) {
68054 return function(graph) {
68055 function discardTags(entity) {
68056 if (!lodash.isEmpty(entity.tags)) {
68058 lodash.each(entity.tags, function(v, k) {
68059 if (v) tags[k] = v;
68062 graph = graph.replace(entity.update({
68063 tags: lodash.omit(tags, dataDiscarded)
68068 difference.modified().forEach(discardTags);
68069 difference.created().forEach(discardTags);
68075 // Disconect the ways at the given node.
68077 // Optionally, disconnect only the given ways.
68079 // For testing convenience, accepts an ID to assign to the (first) new node.
68080 // Normally, this will be undefined and the way will automatically
68081 // be assigned a new ID.
68083 // This is the inverse of `iD.actionConnect`.
68086 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
68087 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
68089 function actionDisconnect(nodeId, newNodeId) {
68093 var action = function(graph) {
68094 var node = graph.entity(nodeId),
68095 connections = action.connections(graph);
68097 connections.forEach(function(connection) {
68098 var way = graph.entity(connection.wayID),
68099 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
68101 graph = graph.replace(newNode);
68102 if (connection.index === 0 && way.isArea()) {
68103 // replace shared node with shared node..
68104 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
68106 // replace shared node with multiple new nodes..
68107 graph = graph.replace(way.updateNode(newNode.id, connection.index));
68115 action.connections = function(graph) {
68116 var candidates = [],
68118 parentWays = graph.parentWays(graph.entity(nodeId));
68120 parentWays.forEach(function(way) {
68121 if (wayIds && wayIds.indexOf(way.id) === -1) {
68125 if (way.isArea() && (way.nodes[0] === nodeId)) {
68126 candidates.push({wayID: way.id, index: 0});
68128 way.nodes.forEach(function(waynode, index) {
68129 if (waynode === nodeId) {
68130 candidates.push({wayID: way.id, index: index});
68136 return keeping ? candidates : candidates.slice(1);
68140 action.disabled = function(graph) {
68141 var connections = action.connections(graph);
68142 if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
68143 return 'not_connected';
68145 var parentWays = graph.parentWays(graph.entity(nodeId)),
68146 seenRelationIds = {},
68149 parentWays.forEach(function(way) {
68150 if (wayIds && wayIds.indexOf(way.id) === -1)
68153 var relations = graph.parentRelations(way);
68154 relations.forEach(function(relation) {
68155 if (relation.id in seenRelationIds) {
68156 sharedRelation = relation;
68158 seenRelationIds[relation.id] = true;
68163 if (sharedRelation)
68168 action.limitWays = function(_) {
68169 if (!arguments.length) return wayIds;
68178 // Join ways at the end node they share.
68180 // This is the inverse of `iD.actionSplit`.
68183 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
68184 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
68186 function actionJoin(ids) {
68188 function groupEntitiesByGeometry(graph) {
68189 var entities = ids.map(function(id) { return graph.entity(id); });
68190 return lodash.extend({line: []}, lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
68194 var action = function(graph) {
68195 var ways = ids.map(graph.entity, graph),
68196 survivor = ways[0];
68198 // Prefer to keep an existing way.
68199 for (var i = 0; i < ways.length; i++) {
68200 if (!ways[i].isNew()) {
68201 survivor = ways[i];
68206 var joined = osmJoinWays(ways, graph)[0];
68208 survivor = survivor.update({nodes: lodash.map(joined.nodes, 'id')});
68209 graph = graph.replace(survivor);
68211 joined.forEach(function(way) {
68212 if (way.id === survivor.id)
68215 graph.parentRelations(way).forEach(function(parent) {
68216 graph = graph.replace(parent.replaceMember(way, survivor));
68219 survivor = survivor.mergeTags(way.tags);
68221 graph = graph.replace(survivor);
68222 graph = actionDeleteWay(way.id)(graph);
68229 action.disabled = function(graph) {
68230 var geometries = groupEntitiesByGeometry(graph);
68231 if (ids.length < 2 || ids.length !== geometries.line.length)
68232 return 'not_eligible';
68234 var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
68235 if (joined.length > 1)
68236 return 'not_adjacent';
68238 var nodeIds = lodash.map(joined[0].nodes, 'id').slice(1, -1),
68241 conflicting = false;
68243 joined[0].forEach(function(way) {
68244 var parents = graph.parentRelations(way);
68245 parents.forEach(function(parent) {
68246 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
68250 for (var k in way.tags) {
68251 if (!(k in tags)) {
68252 tags[k] = way.tags[k];
68253 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
68254 conflicting = true;
68260 return 'restriction';
68263 return 'conflicting_tags';
68270 function actionMerge(ids) {
68272 function groupEntitiesByGeometry(graph) {
68273 var entities = ids.map(function(id) { return graph.entity(id); });
68274 return lodash.extend({point: [], area: [], line: [], relation: []},
68275 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
68279 var action = function(graph) {
68280 var geometries = groupEntitiesByGeometry(graph),
68281 target = geometries.area[0] || geometries.line[0],
68282 points = geometries.point;
68284 points.forEach(function(point) {
68285 target = target.mergeTags(point.tags);
68287 graph.parentRelations(point).forEach(function(parent) {
68288 graph = graph.replace(parent.replaceMember(point, target));
68291 graph = graph.remove(point);
68294 graph = graph.replace(target);
68300 action.disabled = function(graph) {
68301 var geometries = groupEntitiesByGeometry(graph);
68302 if (geometries.point.length === 0 ||
68303 (geometries.area.length + geometries.line.length) !== 1 ||
68304 geometries.relation.length !== 0)
68305 return 'not_eligible';
68312 function actionMergePolygon(ids, newRelationId) {
68314 function groupEntities(graph) {
68315 var entities = ids.map(function (id) { return graph.entity(id); });
68316 return lodash.extend({
68320 }, lodash.groupBy(entities, function(entity) {
68321 if (entity.type === 'way' && entity.isClosed()) {
68322 return 'closedWay';
68323 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
68324 return 'multipolygon';
68332 var action = function(graph) {
68333 var entities = groupEntities(graph);
68335 // An array representing all the polygons that are part of the multipolygon.
68337 // Each element is itself an array of objects with an id property, and has a
68338 // locs property which is an array of the locations forming the polygon.
68339 var polygons = entities.multipolygon.reduce(function(polygons, m) {
68340 return polygons.concat(osmJoinWays(m.members, graph));
68341 }, []).concat(entities.closedWay.map(function(d) {
68342 var member = [{id: d.id}];
68343 member.nodes = graph.childNodes(d);
68347 // contained is an array of arrays of boolean values,
68348 // where contained[j][k] is true iff the jth way is
68349 // contained by the kth way.
68350 var contained = polygons.map(function(w, i) {
68351 return polygons.map(function(d, n) {
68352 if (i === n) return null;
68353 return geoPolygonContainsPolygon(
68354 lodash.map(d.nodes, 'loc'),
68355 lodash.map(w.nodes, 'loc'));
68359 // Sort all polygons as either outer or inner ways
68363 while (polygons.length) {
68364 extractUncontained(polygons);
68365 polygons = polygons.filter(isContained);
68366 contained = contained.filter(isContained).map(filterContained);
68369 function isContained(d, i) {
68370 return lodash.some(contained[i]);
68373 function filterContained(d) {
68374 return d.filter(isContained);
68377 function extractUncontained(polygons) {
68378 polygons.forEach(function(d, i) {
68379 if (!isContained(d, i)) {
68380 d.forEach(function(member) {
68384 role: outer ? 'outer' : 'inner'
68392 // Move all tags to one relation
68393 var relation = entities.multipolygon[0] ||
68394 osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
68396 entities.multipolygon.slice(1).forEach(function(m) {
68397 relation = relation.mergeTags(m.tags);
68398 graph = graph.remove(m);
68401 entities.closedWay.forEach(function(way) {
68402 function isThisOuter(m) {
68403 return m.id === way.id && m.role !== 'inner';
68405 if (members.some(isThisOuter)) {
68406 relation = relation.mergeTags(way.tags);
68407 graph = graph.replace(way.update({ tags: {} }));
68411 return graph.replace(relation.update({
68413 tags: lodash.omit(relation.tags, 'area')
68418 action.disabled = function(graph) {
68419 var entities = groupEntities(graph);
68420 if (entities.other.length > 0 ||
68421 entities.closedWay.length + entities.multipolygon.length < 2)
68422 return 'not_eligible';
68423 if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
68424 return 'incomplete_relation';
68431 // Copyright (c) 2006, 2008 Tony Garnock-Jones <tonyg@lshift.net>
68432 // Copyright (c) 2006, 2008 LShift Ltd. <query@lshift.net>
68434 // Permission is hereby granted, free of charge, to any person
68435 // obtaining a copy of this software and associated documentation files
68436 // (the "Software"), to deal in the Software without restriction,
68437 // including without limitation the rights to use, copy, modify, merge,
68438 // publish, distribute, sublicense, and/or sell copies of the Software,
68439 // and to permit persons to whom the Software is furnished to do so,
68440 // subject to the following conditions:
68442 // The above copyright notice and this permission notice shall be
68443 // included in all copies or substantial portions of the Software.
68445 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
68446 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
68447 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
68448 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
68449 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
68450 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
68451 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
68454 // source: https://bitbucket.org/lshift/synchrotron/src
68455 function longest_common_subsequence(file1, file2) {
68456 /* Text diff algorithm following Hunt and McIlroy 1976.
68457 * J. W. Hunt and M. D. McIlroy, An algorithm for differential file
68458 * comparison, Bell Telephone Laboratories CSTR #41 (1976)
68459 * http://www.cs.dartmouth.edu/~doug/
68461 * Expects two arrays of strings.
68463 var equivalenceClasses;
68468 var c, i, j, jX, r, s;
68470 equivalenceClasses = {};
68471 for (j = 0; j < file2.length; j++) {
68473 if (equivalenceClasses[line]) {
68474 equivalenceClasses[line].push(j);
68476 equivalenceClasses[line] = [j];
68480 candidates = [{file1index: -1,
68484 for (i = 0; i < file1.length; i++) {
68486 file2indices = equivalenceClasses[line] || [];
68491 for (jX = 0; jX < file2indices.length; jX++) {
68492 j = file2indices[jX];
68494 for (s = 0; s < candidates.length; s++) {
68495 if ((candidates[s].file2index < j) &&
68496 ((s === candidates.length - 1) ||
68497 (candidates[s + 1].file2index > j)))
68501 if (s < candidates.length) {
68502 newCandidate = {file1index: i,
68504 chain: candidates[s]};
68505 if (r === candidates.length) {
68506 candidates.push(c);
68512 if (r === candidates.length) {
68513 break; // no point in examining further (j)s
68521 // At this point, we know the LCS: it's in the reverse of the
68522 // linked-list through .chain of
68523 // candidates[candidates.length - 1].
68525 return candidates[candidates.length - 1];
68538 function diff_indices(file1, file2) {
68539 // We apply the LCS to give a simple representation of the
68540 // offsets and lengths of mismatched chunks in the input
68541 // files. This is used by diff3_merge_indices below.
68544 var tail1 = file1.length;
68545 var tail2 = file2.length;
68547 for (var candidate = longest_common_subsequence(file1, file2);
68548 candidate !== null;
68549 candidate = candidate.chain)
68551 var mismatchLength1 = tail1 - candidate.file1index - 1;
68552 var mismatchLength2 = tail2 - candidate.file2index - 1;
68553 tail1 = candidate.file1index;
68554 tail2 = candidate.file2index;
68556 if (mismatchLength1 || mismatchLength2) {
68557 result.push({file1: [tail1 + 1, mismatchLength1],
68558 file2: [tail2 + 1, mismatchLength2]});
68566 function diff3_merge_indices (a, o, b) {
68567 // Given three files, A, O, and B, where both A and B are
68568 // independently derived from O, returns a fairly complicated
68569 // internal representation of merge decisions it's taken. The
68570 // interested reader may wish to consult
68572 // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. "A
68573 // Formal Investigation of Diff3." In Arvind and Prasad,
68574 // editors, Foundations of Software Technology and Theoretical
68575 // Computer Science (FSTTCS), December 2007.
68577 // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
68580 var m1 = diff_indices(o, a);
68581 var m2 = diff_indices(o, b);
68584 function addHunk(h, side) {
68585 hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
68587 for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
68588 for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
68592 var commonOffset = 0;
68593 function copyCommon(targetOffset) {
68594 if (targetOffset > commonOffset) {
68595 result.push([1, commonOffset, targetOffset - commonOffset]);
68596 commonOffset = targetOffset;
68600 for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
68601 var firstHunkIndex = hunkIndex;
68602 var hunk = hunks[hunkIndex];
68603 var regionLhs = hunk[0];
68604 var regionRhs = regionLhs + hunk[2];
68605 while (hunkIndex < hunks.length - 1) {
68606 var maybeOverlapping = hunks[hunkIndex + 1];
68607 var maybeLhs = maybeOverlapping[0];
68608 if (maybeLhs > regionRhs) break;
68609 regionRhs = maybeLhs + maybeOverlapping[2];
68613 copyCommon(regionLhs);
68614 if (firstHunkIndex === hunkIndex) {
68615 // The "overlap" was only one hunk long, meaning that
68616 // there's no conflict here. Either a and o were the
68617 // same, or b and o were the same.
68619 result.push([hunk[1], hunk[3], hunk[4]]);
68622 // A proper conflict. Determine the extents of the
68623 // regions involved from a, o and b. Effectively merge
68624 // all the hunks on the left into one giant hunk, and
68625 // do the same for the right; then, correct for skew
68626 // in the regions of o that each side changed, and
68627 // report appropriate spans for the three sides.
68629 0: [a.length, -1, o.length, -1],
68630 2: [b.length, -1, o.length, -1]
68632 for (i = firstHunkIndex; i <= hunkIndex; i++) {
68634 var side = hunk[1];
68635 var r = regions[side];
68636 var oLhs = hunk[0];
68637 var oRhs = oLhs + hunk[2];
68638 var abLhs = hunk[3];
68639 var abRhs = abLhs + hunk[4];
68640 r[0] = Math.min(abLhs, r[0]);
68641 r[1] = Math.max(abRhs, r[1]);
68642 r[2] = Math.min(oLhs, r[2]);
68643 r[3] = Math.max(oRhs, r[3]);
68645 var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
68646 var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
68647 var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
68648 var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
68651 regionLhs, regionRhs - regionLhs,
68652 bLhs, bRhs - bLhs]);
68654 commonOffset = regionRhs;
68657 copyCommon(o.length);
68661 function diff3_merge (a, o, b, excludeFalseConflicts) {
68662 // Applies the output of Diff3.diff3_merge_indices to actually
68663 // construct the merged file; the returned result alternates
68664 // between "ok" and "conflict" blocks.
68667 var files = [a, o, b];
68668 var indices = diff3_merge_indices(a, o, b);
68671 function flushOk() {
68672 if (okLines.length) {
68673 result.push({ok: okLines});
68677 function pushOk(xs) {
68678 for (var j = 0; j < xs.length; j++) {
68679 okLines.push(xs[j]);
68683 function isTrueConflict(rec) {
68684 if (rec[2] !== rec[6]) return true;
68687 for (var j = 0; j < rec[2]; j++) {
68688 if (a[j + aoff] !== b[j + boff]) return true;
68693 for (var i = 0; i < indices.length; i++) {
68694 var x = indices[i];
68697 if (excludeFalseConflicts && !isTrueConflict(x)) {
68698 pushOk(files[0].slice(x[1], x[1] + x[2]));
68701 result.push({conflict: {a: a.slice(x[1], x[1] + x[2]),
68703 o: o.slice(x[3], x[3] + x[4]),
68705 b: b.slice(x[5], x[5] + x[6]),
68709 pushOk(files[side].slice(x[1], x[1] + x[2]));
68717 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
68718 var option = 'safe', // 'safe', 'force_local', 'force_remote'
68723 return lodash.isFunction(formatUser) ? formatUser(d) : d;
68727 function mergeLocation(remote, target) {
68728 function pointEqual(a, b) {
68729 var epsilon = 1e-6;
68730 return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
68733 if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
68736 if (option === 'force_remote') {
68737 return target.update({loc: remote.loc});
68740 conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
68745 function mergeNodes(base, remote, target) {
68746 if (option === 'force_local' || lodash.isEqual(target.nodes, remote.nodes)) {
68749 if (option === 'force_remote') {
68750 return target.update({nodes: remote.nodes});
68753 var ccount = conflicts.length,
68754 o = base.nodes || [],
68755 a = target.nodes || [],
68756 b = remote.nodes || [],
68758 hunks = diff3_merge(a, o, b, true);
68760 for (var i = 0; i < hunks.length; i++) {
68761 var hunk = hunks[i];
68763 nodes.push.apply(nodes, hunk.ok);
68765 // for all conflicts, we can assume c.a !== c.b
68766 // because `diff3_merge` called with `true` option to exclude false conflicts..
68767 var c = hunk.conflict;
68768 if (lodash.isEqual(c.o, c.a)) { // only changed remotely
68769 nodes.push.apply(nodes, c.b);
68770 } else if (lodash.isEqual(c.o, c.b)) { // only changed locally
68771 nodes.push.apply(nodes, c.a);
68772 } else { // changed both locally and remotely
68773 conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
68779 return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
68783 function mergeChildren(targetWay, children, updates, graph) {
68784 function isUsed(node, targetWay) {
68785 var parentWays = lodash.map(graph.parentWays(node), 'id');
68786 return node.hasInterestingTags() ||
68787 lodash.without(parentWays, targetWay.id).length > 0 ||
68788 graph.parentRelations(node).length > 0;
68791 var ccount = conflicts.length;
68793 for (var i = 0; i < children.length; i++) {
68794 var id = children[i],
68795 node = graph.hasEntity(id);
68797 // remove unused childNodes..
68798 if (targetWay.nodes.indexOf(id) === -1) {
68799 if (node && !isUsed(node, targetWay)) {
68800 updates.removeIds.push(id);
68805 // restore used childNodes..
68806 var local = localGraph.hasEntity(id),
68807 remote = remoteGraph.hasEntity(id),
68810 if (option === 'force_remote' && remote && remote.visible) {
68811 updates.replacements.push(remote);
68813 } else if (option === 'force_local' && local) {
68814 target = osmEntity$$1(local);
68816 target = target.update({ version: remote.version });
68818 updates.replacements.push(target);
68820 } else if (option === 'safe' && local && remote && local.version !== remote.version) {
68821 target = osmEntity$$1(local, { version: remote.version });
68822 if (remote.visible) {
68823 target = mergeLocation(remote, target);
68825 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
68828 if (conflicts.length !== ccount) break;
68829 updates.replacements.push(target);
68837 function updateChildren(updates, graph) {
68838 for (var i = 0; i < updates.replacements.length; i++) {
68839 graph = graph.replace(updates.replacements[i]);
68841 if (updates.removeIds.length) {
68842 graph = actionDeleteMultiple(updates.removeIds)(graph);
68848 function mergeMembers(remote, target) {
68849 if (option === 'force_local' || lodash.isEqual(target.members, remote.members)) {
68852 if (option === 'force_remote') {
68853 return target.update({members: remote.members});
68856 conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
68861 function mergeTags(base, remote, target) {
68862 function ignoreKey(k) {
68863 return lodash.includes(dataDiscarded, k);
68866 if (option === 'force_local' || lodash.isEqual(target.tags, remote.tags)) {
68869 if (option === 'force_remote') {
68870 return target.update({tags: remote.tags});
68873 var ccount = conflicts.length,
68874 o = base.tags || {},
68875 a = target.tags || {},
68876 b = remote.tags || {},
68877 keys = lodash.reject(lodash.union(lodash.keys(o), lodash.keys(a), lodash.keys(b)), ignoreKey),
68878 tags = lodash.clone(a),
68881 for (var i = 0; i < keys.length; i++) {
68884 if (o[k] !== b[k] && a[k] !== b[k]) { // changed remotely..
68885 if (o[k] !== a[k]) { // changed locally..
68886 conflicts.push(t('merge_remote_changes.conflict.tags',
68887 { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
68889 } else { // unchanged locally, accept remote change..
68890 if (b.hasOwnProperty(k)) {
68900 return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
68904 // `graph.base()` is the common ancestor of the two graphs.
68905 // `localGraph` contains user's edits up to saving
68906 // `remoteGraph` contains remote edits to modified nodes
68907 // `graph` must be a descendent of `localGraph` and may include
68908 // some conflict resolution actions performed on it.
68910 // --- ... --- `localGraph` -- ... -- `graph`
68912 // `graph.base()` --- ... --- `remoteGraph`
68914 var action = function(graph) {
68915 var updates = { replacements: [], removeIds: [] },
68916 base = graph.base().entities[id],
68917 local = localGraph.entity(id),
68918 remote = remoteGraph.entity(id),
68919 target = osmEntity$$1(local, { version: remote.version });
68922 if (!remote.visible) {
68923 if (option === 'force_remote') {
68924 return actionDeleteMultiple([id])(graph);
68926 } else if (option === 'force_local') {
68927 if (target.type === 'way') {
68928 target = mergeChildren(target, lodash.uniq(local.nodes), updates, graph);
68929 graph = updateChildren(updates, graph);
68931 return graph.replace(target);
68934 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
68935 return graph; // do nothing
68940 if (target.type === 'node') {
68941 target = mergeLocation(remote, target);
68943 } else if (target.type === 'way') {
68944 // pull in any child nodes that may not be present locally..
68945 graph.rebase(remoteGraph.childNodes(remote), [graph], false);
68946 target = mergeNodes(base, remote, target);
68947 target = mergeChildren(target, lodash.union(local.nodes, remote.nodes), updates, graph);
68949 } else if (target.type === 'relation') {
68950 target = mergeMembers(remote, target);
68953 target = mergeTags(base, remote, target);
68955 if (!conflicts.length) {
68956 graph = updateChildren(updates, graph).replace(target);
68963 action.withOption = function(opt) {
68969 action.conflicts = function() {
68977 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
68978 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
68979 function actionMove(moveIds, tryDelta, projection, cache) {
68980 var delta = tryDelta;
68982 function vecAdd(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
68983 function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
68985 function setupCache(graph) {
68986 function canMove(nodeId) {
68987 // Allow movement of any node that is in the selectedIDs list..
68988 if (moveIds.indexOf(nodeId) !== -1) return true;
68990 // Allow movement of a vertex where 2 ways meet..
68991 var parents = lodash.map(graph.parentWays(graph.entity(nodeId)), 'id');
68992 if (parents.length < 3) return true;
68994 // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
68995 var parentsMoving = lodash.every(parents, function(id) { return cache.moving[id]; });
68996 if (!parentsMoving) delete cache.moving[nodeId];
68998 return parentsMoving;
69001 function cacheEntities(ids) {
69002 ids.forEach(function(id) {
69003 if (cache.moving[id]) return;
69004 cache.moving[id] = true;
69006 var entity = graph.hasEntity(id);
69007 if (!entity) return;
69009 if (entity.type === 'node') {
69010 cache.nodes.push(id);
69011 cache.startLoc[id] = entity.loc;
69012 } else if (entity.type === 'way') {
69013 cache.ways.push(id);
69014 cacheEntities(entity.nodes);
69016 cacheEntities(entity.members.map(function(member) {
69023 function cacheIntersections(ids) {
69024 function isEndpoint(way, id) { return !way.isClosed() && !!way.affix(id); }
69026 ids.forEach(function(id) {
69027 // consider only intersections with 1 moved and 1 unmoved way.
69028 var childNodes = graph.childNodes(graph.entity(id));
69029 childNodes.forEach(function(node) {
69030 var parents = graph.parentWays(node);
69031 if (parents.length !== 2) return;
69033 var moved = graph.entity(id),
69034 unmoved = lodash.find(parents, function(way) { return !cache.moving[way.id]; });
69035 if (!unmoved) return;
69037 // exclude ways that are overly connected..
69038 if (lodash.intersection(moved.nodes, unmoved.nodes).length > 2) return;
69040 if (moved.isArea() || unmoved.isArea()) return;
69042 cache.intersection[node.id] = {
69045 unmovedId: unmoved.id,
69046 movedIsEP: isEndpoint(moved, node.id),
69047 unmovedIsEP: isEndpoint(unmoved, node.id)
69059 cache.intersection = {};
69060 cache.replacedVertex = {};
69061 cache.startLoc = {};
69065 cacheEntities(moveIds);
69066 cacheIntersections(cache.ways);
69067 cache.nodes = lodash.filter(cache.nodes, canMove);
69074 // Place a vertex where the moved vertex used to be, to preserve way shape..
69075 function replaceMovedVertex(nodeId, wayId, graph, delta) {
69076 var way = graph.entity(wayId),
69077 moved = graph.entity(nodeId),
69078 movedIndex = way.nodes.indexOf(nodeId),
69079 len, prevIndex, nextIndex;
69081 if (way.isClosed()) {
69082 len = way.nodes.length - 1;
69083 prevIndex = (movedIndex + len - 1) % len;
69084 nextIndex = (movedIndex + len + 1) % len;
69086 len = way.nodes.length;
69087 prevIndex = movedIndex - 1;
69088 nextIndex = movedIndex + 1;
69091 var prev = graph.hasEntity(way.nodes[prevIndex]),
69092 next = graph.hasEntity(way.nodes[nextIndex]);
69094 // Don't add orig vertex at endpoint..
69095 if (!prev || !next) return graph;
69097 var key = wayId + '_' + nodeId,
69098 orig = cache.replacedVertex[key];
69101 cache.replacedVertex[key] = orig;
69102 cache.startLoc[orig.id] = cache.startLoc[nodeId];
69107 start = projection(cache.startLoc[nodeId]);
69108 end = projection.invert(vecAdd(start, delta));
69110 end = cache.startLoc[nodeId];
69112 orig = orig.move(end);
69114 var angle = Math.abs(geoAngle(orig, prev, projection) -
69115 geoAngle(orig, next, projection)) * 180 / Math.PI;
69117 // Don't add orig vertex if it would just make a straight line..
69118 if (angle > 175 && angle < 185) return graph;
69120 // Don't add orig vertex if another point is already nearby (within 10m)
69121 if (geoSphericalDistance(prev.loc, orig.loc) < 10 ||
69122 geoSphericalDistance(orig.loc, next.loc) < 10) return graph;
69124 // moving forward or backward along way?
69125 var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
69126 p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
69127 d1 = geoPathLength(p1),
69128 d2 = geoPathLength(p2),
69129 insertAt = (d1 < d2) ? movedIndex : nextIndex;
69131 // moving around closed loop?
69132 if (way.isClosed() && insertAt === 0) insertAt = len;
69134 way = way.addNode(orig.id, insertAt);
69135 return graph.replace(orig).replace(way);
69139 // Reorder nodes around intersections that have moved..
69140 function unZorroIntersection(intersection, graph) {
69141 var vertex = graph.entity(intersection.nodeId),
69142 way1 = graph.entity(intersection.movedId),
69143 way2 = graph.entity(intersection.unmovedId),
69144 isEP1 = intersection.movedIsEP,
69145 isEP2 = intersection.unmovedIsEP;
69147 // don't move the vertex if it is the endpoint of both ways.
69148 if (isEP1 && isEP2) return graph;
69150 var nodes1 = lodash.without(graph.childNodes(way1), vertex),
69151 nodes2 = lodash.without(graph.childNodes(way2), vertex);
69153 if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
69154 if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
69156 var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection),
69157 edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection),
69160 // snap vertex to nearest edge (or some point between them)..
69161 if (!isEP1 && !isEP2) {
69162 var epsilon = 1e-4, maxIter = 10;
69163 for (var i = 0; i < maxIter; i++) {
69164 loc = geoInterp(edge1.loc, edge2.loc, 0.5);
69165 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
69166 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
69167 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
69169 } else if (!isEP1) {
69175 graph = graph.replace(vertex.move(loc));
69177 // if zorro happened, reorder nodes..
69178 if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
69179 way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
69180 graph = graph.replace(way1);
69182 if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
69183 way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
69184 graph = graph.replace(way2);
69191 function cleanupIntersections(graph) {
69192 lodash.each(cache.intersection, function(obj) {
69193 graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, delta);
69194 graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
69195 graph = unZorroIntersection(obj, graph);
69202 // check if moving way endpoint can cross an unmoved way, if so limit delta..
69203 function limitDelta(graph) {
69204 lodash.each(cache.intersection, function(obj) {
69205 // Don't limit movement if this is vertex joins 2 endpoints..
69206 if (obj.movedIsEP && obj.unmovedIsEP) return;
69207 // Don't limit movement if this vertex is not an endpoint anyway..
69208 if (!obj.movedIsEP) return;
69210 var node = graph.entity(obj.nodeId),
69211 start = projection(node.loc),
69212 end = vecAdd(start, delta),
69213 movedNodes = graph.childNodes(graph.entity(obj.movedId)),
69214 movedPath = lodash.map(lodash.map(movedNodes, 'loc'),
69215 function(loc) { return vecAdd(projection(loc), delta); }),
69216 unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)),
69217 unmovedPath = lodash.map(lodash.map(unmovedNodes, 'loc'), projection),
69218 hits = geoPathIntersections(movedPath, unmovedPath);
69220 for (var i = 0; i < hits.length; i++) {
69221 if (lodash.isEqual(hits[i], end)) continue;
69222 var edge = geoChooseEdge(unmovedNodes, end, projection);
69223 delta = vecSub(projection(edge.loc), start);
69229 var action = function(graph) {
69230 if (delta[0] === 0 && delta[1] === 0) return graph;
69234 if (!lodash.isEmpty(cache.intersection)) {
69238 lodash.each(cache.nodes, function(id) {
69239 var node = graph.entity(id),
69240 start = projection(node.loc),
69241 end = vecAdd(start, delta);
69242 graph = graph.replace(node.move(projection.invert(end)));
69245 if (!lodash.isEmpty(cache.intersection)) {
69246 graph = cleanupIntersections(graph);
69253 action.disabled = function(graph) {
69254 function incompleteRelation(id) {
69255 var entity = graph.entity(id);
69256 return entity.type === 'relation' && !entity.isComplete(graph);
69259 if (lodash.some(moveIds, incompleteRelation))
69260 return 'incomplete_relation';
69264 action.delta = function() {
69272 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
69273 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
69274 function actionMoveNode(nodeId, loc) {
69275 return function(graph) {
69276 return graph.replace(graph.entity(nodeId).move(loc));
69280 function actionNoop() {
69281 return function(graph) {
69287 * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
69289 function actionOrthogonalize(wayId, projection) {
69290 var threshold = 12, // degrees within right or straight to alter
69291 lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
69292 upperThreshold = Math.cos(threshold * Math.PI / 180);
69295 var action = function(graph) {
69296 var way = graph.entity(wayId),
69297 nodes = graph.childNodes(way),
69298 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); }),
69299 corner = {i: 0, dotp: 1},
69301 i, j, score, motions;
69303 if (nodes.length === 4) {
69304 for (i = 0; i < 1000; i++) {
69305 motions = points.map(calcMotion);
69306 points[corner.i] = addPoints(points[corner.i],motions[corner.i]);
69307 score = corner.dotp;
69308 if (score < epsilon) {
69313 graph = graph.replace(graph.entity(nodes[corner.i].id)
69314 .move(projection.invert(points[corner.i])));
69318 originalPoints = lodash.clone(points);
69321 for (i = 0; i < 1000; i++) {
69322 motions = points.map(calcMotion);
69323 for (j = 0; j < motions.length; j++) {
69324 points[j] = addPoints(points[j],motions[j]);
69326 var newScore = squareness(points);
69327 if (newScore < score) {
69328 best = lodash.clone(points);
69331 if (score < epsilon) {
69338 for (i = 0; i < points.length; i++) {
69339 // only move the points that actually moved
69340 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
69341 graph = graph.replace(graph.entity(nodes[i].id)
69342 .move(projection.invert(points[i])));
69346 // remove empty nodes on straight sections
69347 for (i = 0; i < points.length; i++) {
69348 var node = nodes[i];
69350 if (graph.parentWays(node).length > 1 ||
69351 graph.parentRelations(node).length ||
69352 node.hasInterestingTags()) {
69357 var dotp = normalizedDotProduct(i, points);
69358 if (dotp < -1 + epsilon) {
69359 graph = actionDeleteNode(nodes[i].id)(graph);
69367 function calcMotion(b, i, array) {
69368 var a = array[(i - 1 + array.length) % array.length],
69369 c = array[(i + 1) % array.length],
69370 p = subtractPoints(a, b),
69371 q = subtractPoints(c, b),
69374 scale = 2 * Math.min(geoEuclideanDistance(p, [0, 0]), geoEuclideanDistance(q, [0, 0]));
69375 p = normalizePoint(p, 1.0);
69376 q = normalizePoint(q, 1.0);
69378 dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
69380 // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
69381 if (array.length > 3) {
69382 if (dotp < -0.707106781186547) {
69385 } else if (dotp && Math.abs(dotp) < corner.dotp) {
69387 corner.dotp = Math.abs(dotp);
69390 return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
69395 function squareness(points) {
69396 return points.reduce(function(sum, val, i, array) {
69397 var dotp = normalizedDotProduct(i, array);
69399 dotp = filterDotProduct(dotp);
69400 return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
69405 function normalizedDotProduct(i, points) {
69406 var a = points[(i - 1 + points.length) % points.length],
69408 c = points[(i + 1) % points.length],
69409 p = subtractPoints(a, b),
69410 q = subtractPoints(c, b);
69412 p = normalizePoint(p, 1.0);
69413 q = normalizePoint(q, 1.0);
69415 return p[0] * q[0] + p[1] * q[1];
69419 function subtractPoints(a, b) {
69420 return [a[0] - b[0], a[1] - b[1]];
69424 function addPoints(a, b) {
69425 return [a[0] + b[0], a[1] + b[1]];
69429 function normalizePoint(point, scale) {
69430 var vector = [0, 0];
69431 var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
69432 if (length !== 0) {
69433 vector[0] = point[0] / length;
69434 vector[1] = point[1] / length;
69437 vector[0] *= scale;
69438 vector[1] *= scale;
69444 function filterDotProduct(dotp) {
69445 if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
69453 action.disabled = function(graph) {
69454 var way = graph.entity(wayId),
69455 nodes = graph.childNodes(way),
69456 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); });
69458 if (squareness(points)) {
69462 return 'not_squarish';
69469 // Split a way at the given node.
69471 // Optionally, split only the given ways, if multiple ways share
69474 // This is the inverse of `iD.actionJoin`.
69476 // For testing convenience, accepts an ID to assign to the new way.
69477 // Normally, this will be undefined and the way will automatically
69478 // be assigned a new ID.
69481 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
69483 function actionSplit(nodeId, newWayIds) {
69486 // if the way is closed, we need to search for a partner node
69487 // to split the way at.
69489 // The following looks for a node that is both far away from
69490 // the initial node in terms of way segment length and nearby
69491 // in terms of beeline-distance. This assures that areas get
69492 // split on the most "natural" points (independent of the number
69494 // For example: bone-shaped areas get split across their waist
69495 // line, circles across the diameter.
69496 function splitArea(nodes, idxA, graph) {
69497 var lengths = new Array(nodes.length),
69503 function wrap(index) {
69504 return utilWrap(index, nodes.length);
69507 function dist(nA, nB) {
69508 return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
69511 // calculate lengths
69513 for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
69514 length += dist(nodes[i], nodes[wrap(i-1)]);
69515 lengths[i] = length;
69519 for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
69520 length += dist(nodes[i], nodes[wrap(i+1)]);
69521 if (length < lengths[i])
69522 lengths[i] = length;
69525 // determine best opposite node to split
69526 for (i = 0; i < nodes.length; i++) {
69527 var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
69538 function split(graph, wayA, newWayId) {
69539 var wayB = osmWay({id: newWayId, tags: wayA.tags}),
69542 isArea = wayA.isArea(),
69543 isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
69545 if (wayA.isClosed()) {
69546 var nodes = wayA.nodes.slice(0, -1),
69547 idxA = lodash.indexOf(nodes, nodeId),
69548 idxB = splitArea(nodes, idxA, graph);
69551 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
69552 nodesB = nodes.slice(idxB, idxA + 1);
69554 nodesA = nodes.slice(idxA, idxB + 1);
69555 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
69558 var idx = lodash.indexOf(wayA.nodes, nodeId, 1);
69559 nodesA = wayA.nodes.slice(0, idx + 1);
69560 nodesB = wayA.nodes.slice(idx);
69563 wayA = wayA.update({nodes: nodesA});
69564 wayB = wayB.update({nodes: nodesB});
69566 graph = graph.replace(wayA);
69567 graph = graph.replace(wayB);
69569 graph.parentRelations(wayA).forEach(function(relation) {
69570 if (relation.isRestriction()) {
69571 var via = relation.memberByRole('via');
69572 if (via && wayB.contains(via.id)) {
69573 relation = relation.updateMember({id: wayB.id}, relation.memberById(wayA.id).index);
69574 graph = graph.replace(relation);
69577 if (relation === isOuter) {
69578 graph = graph.replace(relation.mergeTags(wayA.tags));
69579 graph = graph.replace(wayA.update({tags: {}}));
69580 graph = graph.replace(wayB.update({tags: {}}));
69586 role: relation.memberById(wayA.id).role
69589 graph = actionAddMember(relation.id, member)(graph);
69593 if (!isOuter && isArea) {
69594 var multipolygon = osmRelation({
69595 tags: lodash.extend({}, wayA.tags, {type: 'multipolygon'}),
69597 {id: wayA.id, role: 'outer', type: 'way'},
69598 {id: wayB.id, role: 'outer', type: 'way'}
69601 graph = graph.replace(multipolygon);
69602 graph = graph.replace(wayA.update({tags: {}}));
69603 graph = graph.replace(wayB.update({tags: {}}));
69610 var action = function(graph) {
69611 var candidates = action.ways(graph);
69612 for (var i = 0; i < candidates.length; i++) {
69613 graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
69619 action.ways = function(graph) {
69620 var node = graph.entity(nodeId),
69621 parents = graph.parentWays(node),
69622 hasLines = lodash.some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
69624 return parents.filter(function(parent) {
69625 if (wayIds && wayIds.indexOf(parent.id) === -1)
69628 if (!wayIds && hasLines && parent.geometry(graph) !== 'line')
69631 if (parent.isClosed()) {
69635 for (var i = 1; i < parent.nodes.length - 1; i++) {
69636 if (parent.nodes[i] === nodeId) {
69646 action.disabled = function(graph) {
69647 var candidates = action.ways(graph);
69648 if (candidates.length === 0 || (wayIds && wayIds.length !== candidates.length))
69649 return 'not_eligible';
69653 action.limitWays = function(_) {
69654 if (!arguments.length) return wayIds;
69663 // Create a restriction relation for `turn`, which must have the following structure:
69666 // from: { node: <node ID>, way: <way ID> },
69667 // via: { node: <node ID> },
69668 // to: { node: <node ID>, way: <way ID> },
69669 // restriction: <'no_right_turn', 'no_left_turn', etc.>
69672 // This specifies a restriction of type `restriction` when traveling from
69673 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
69674 // (The action does not check that these entities form a valid intersection.)
69676 // If `restriction` is not provided, it is automatically determined by
69677 // osmInferRestriction.
69679 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
69680 // and `to.node` are used to determine which portion of the split ways become
69681 // members of the restriction.
69683 // For testing convenience, accepts an ID to assign to the new relation.
69684 // Normally, this will be undefined and the relation will automatically
69685 // be assigned a new ID.
69687 function actionRestrictTurn(turn, projection, restrictionId) {
69689 return function(graph) {
69690 var from = graph.entity(turn.from.way),
69691 via = graph.entity(turn.via.node),
69692 to = graph.entity(turn.to.way);
69694 function isClosingNode(way, nodeId) {
69695 return nodeId === way.first() && nodeId === way.last();
69698 function split(toOrFrom) {
69699 var newID = toOrFrom.newID || osmWay().id;
69700 graph = actionSplit(via.id, [newID])
69701 .limitWays([toOrFrom.way])(graph);
69703 var a = graph.entity(newID),
69704 b = graph.entity(toOrFrom.way);
69706 if (a.nodes.indexOf(toOrFrom.node) !== -1) {
69713 if (!from.affix(via.id) || isClosingNode(from, via.id)) {
69714 if (turn.from.node === turn.to.node) {
69716 from = to = split(turn.from)[0];
69717 } else if (turn.from.way === turn.to.way) {
69718 // Straight-on or circular
69719 var s = split(turn.from);
69724 from = split(turn.from)[0];
69728 if (!to.affix(via.id) || isClosingNode(to, via.id)) {
69729 to = split(turn.to)[0];
69732 return graph.replace(osmRelation({
69735 type: 'restriction',
69736 restriction: turn.restriction ||
69737 osmInferRestriction(
69745 {id: from.id, type: 'way', role: 'from'},
69746 {id: via.id, type: 'node', role: 'via'},
69747 {id: to.id, type: 'way', role: 'to'}
69753 function actionRevert(id) {
69754 var action = function(graph) {
69755 var entity = graph.hasEntity(id),
69756 base = graph.base().entities[id];
69758 if (entity && !base) { // entity will be removed..
69759 if (entity.type === 'node') {
69760 graph.parentWays(entity)
69761 .forEach(function(parent) {
69762 parent = parent.removeNode(id);
69763 graph = graph.replace(parent);
69765 if (parent.isDegenerate()) {
69766 graph = actionDeleteWay(parent.id)(graph);
69771 graph.parentRelations(entity)
69772 .forEach(function(parent) {
69773 parent = parent.removeMembersWithID(id);
69774 graph = graph.replace(parent);
69776 if (parent.isDegenerate()) {
69777 graph = actionDeleteRelation(parent.id)(graph);
69782 return graph.revert(id);
69788 function actionRotateWay(wayId, pivot, angle, projection) {
69789 return function(graph) {
69790 return graph.update(function(graph) {
69791 var way = graph.entity(wayId);
69793 lodash.uniq(way.nodes).forEach(function(id) {
69795 var node = graph.entity(id),
69796 point = projection(node.loc),
69799 radial[0] = point[0] - pivot[0];
69800 radial[1] = point[1] - pivot[1];
69803 radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + pivot[0],
69804 radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + pivot[1]
69807 graph = graph.replace(node.move(projection.invert(point)));
69816 * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
69818 function actionStraighten(wayId, projection) {
69820 function positionAlongWay(n, s, e) {
69821 return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1]))/
69822 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
69826 var action = function(graph) {
69827 var way = graph.entity(wayId),
69828 nodes = graph.childNodes(way),
69829 points = nodes.map(function(n) { return projection(n.loc); }),
69830 startPoint = points[0],
69831 endPoint = points[points.length-1],
69835 for (i = 1; i < points.length-1; i++) {
69836 var node = nodes[i],
69839 if (graph.parentWays(node).length > 1 ||
69840 graph.parentRelations(node).length ||
69841 node.hasInterestingTags()) {
69843 var u = positionAlongWay(point, startPoint, endPoint),
69844 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
69845 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]);
69848 .replace(graph.entity(node.id)
69849 .move(projection.invert([p0, p1])));
69853 if (toDelete.indexOf(node) === -1) {
69854 toDelete.push(node);
69859 for (i = 0; i < toDelete.length; i++) {
69860 graph = actionDeleteNode(toDelete[i].id)(graph);
69867 action.disabled = function(graph) {
69868 // check way isn't too bendy
69869 var way = graph.entity(wayId),
69870 nodes = graph.childNodes(way),
69871 points = nodes.map(function(n) { return projection(n.loc); }),
69872 startPoint = points[0],
69873 endPoint = points[points.length-1],
69874 threshold = 0.2 * geoEuclideanDistance(startPoint, endPoint),
69877 if (threshold === 0) {
69878 return 'too_bendy';
69881 for (i = 1; i < points.length-1; i++) {
69882 var point = points[i],
69883 u = positionAlongWay(point, startPoint, endPoint),
69884 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
69885 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
69886 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
69888 // to bendy if point is off by 20% of total start/end distance in projected space
69889 if (isNaN(dist) || dist > threshold) {
69890 return 'too_bendy';
69899 // Remove the effects of `turn.restriction` on `turn`, which must have the
69900 // following structure:
69903 // from: { node: <node ID>, way: <way ID> },
69904 // via: { node: <node ID> },
69905 // to: { node: <node ID>, way: <way ID> },
69906 // restriction: <relation ID>
69909 // In the simple case, `restriction` is a reference to a `no_*` restriction
69910 // on the turn itself. In this case, it is simply deleted.
69912 // The more complex case is where `restriction` references an `only_*`
69913 // restriction on a different turn in the same intersection. In that case,
69914 // that restriction is also deleted, but at the same time restrictions on
69915 // the turns other than the first two are created.
69917 function actionUnrestrictTurn(turn) {
69918 return function(graph) {
69919 return actionDeleteRelation(turn.restriction)(graph);
69925 var index$16 = Object.freeze({
69926 d3combobox: d3combobox,
69927 d3geoTile: d3geoTile,
69928 d3keybinding: d3keybinding
69931 /* export some legacy symbols: */
69932 var Connection = services.osm;
69938 var iD = Object.freeze({
69939 Connection: Connection,
69943 Context: coreContext,
69944 setAreaKeys: setAreaKeys,
69945 Difference: coreDifference,
69946 Graph: coreGraph$$1,
69947 History: coreHistory,
69949 Entity: osmEntity$$1,
69951 Relation: osmRelation,
69953 BackgroundSource: rendererBackgroundSource,
69954 Background: rendererBackground,
69955 Features: rendererFeatures,
69957 TileLayer: rendererTileLayer,
69958 Detect: utilDetect,
69959 actionAddEntity: actionAddEntity,
69960 actionAddMember: actionAddMember,
69961 actionAddMidpoint: actionAddMidpoint,
69962 actionAddVertex: actionAddVertex,
69963 actionChangeMember: actionChangeMember,
69964 actionChangePreset: actionChangePreset,
69965 actionChangeTags: actionChangeTags,
69966 actionCircularize: actionCircularize,
69967 actionConnect: actionConnect,
69968 actionCopyEntities: actionCopyEntities,
69969 actionDeleteMember: actionDeleteMember,
69970 actionDeleteMultiple: actionDeleteMultiple,
69971 actionDeleteNode: actionDeleteNode,
69972 actionDeleteRelation: actionDeleteRelation,
69973 actionDeleteWay: actionDeleteWay,
69974 actionDeprecateTags: actionDeprecateTags,
69975 actionDiscardTags: actionDiscardTags,
69976 actionDisconnect: actionDisconnect,
69977 actionJoin: actionJoin,
69978 actionMerge: actionMerge,
69979 actionMergePolygon: actionMergePolygon,
69980 actionMergeRemoteChanges: actionMergeRemoteChanges,
69981 actionMove: actionMove,
69982 actionMoveNode: actionMoveNode,
69983 actionNoop: actionNoop,
69984 actionOrthogonalize: actionOrthogonalize,
69985 actionRestrictTurn: actionRestrictTurn,
69986 actionReverse: actionReverse,
69987 actionRevert: actionRevert,
69988 actionRotateWay: actionRotateWay,
69989 actionSplit: actionSplit,
69990 actionStraighten: actionStraighten,
69991 actionUnrestrictTurn: actionUnrestrictTurn,
69992 behaviorAddWay: behaviorAddWay,
69993 behaviorBreathe: behaviorBreathe,
69994 behaviorCopy: behaviorCopy,
69995 behaviorDrag: behaviorDrag,
69996 behaviorDrawWay: behaviorDrawWay,
69997 behaviorDraw: behaviorDraw,
69998 behaviorEdit: behaviorEdit,
69999 behaviorHash: behaviorHash,
70000 behaviorHover: behaviorHover,
70001 behaviorLasso: behaviorLasso,
70002 behaviorPaste: behaviorPaste,
70003 behaviorSelect: behaviorSelect,
70004 behaviorTail: behaviorTail,
70005 coreContext: coreContext,
70006 coreDifference: coreDifference,
70007 coreGraph: coreGraph$$1,
70008 coreHistory: coreHistory,
70009 coreTree: coreTree,
70011 dataWikipedia: dataWikipedia,
70012 dataFeatureIcons: dataFeatureIcons,
70013 dataSuggestions: dataSuggestions,
70014 dataAddressFormats: dataAddressFormats,
70015 dataDeprecated: dataDeprecated,
70016 dataDiscarded: dataDiscarded,
70017 dataLocales: dataLocales,
70018 dataPhoneFormats: dataPhoneFormats,
70019 dataImperial: dataImperial,
70020 dataDriveLeft: dataDriveLeft,
70022 geoRoundCoords: geoRoundCoords,
70023 geoInterp: geoInterp,
70024 geoCross: geoCross,
70025 geoEuclideanDistance: geoEuclideanDistance,
70026 geoLatToMeters: geoLatToMeters,
70027 geoLonToMeters: geoLonToMeters,
70028 geoMetersToLat: geoMetersToLat,
70029 geoMetersToLon: geoMetersToLon,
70030 geoOffsetToMeters: geoOffsetToMeters,
70031 geoMetersToOffset: geoMetersToOffset,
70032 geoSphericalDistance: geoSphericalDistance,
70033 geoEdgeEqual: geoEdgeEqual,
70034 geoAngle: geoAngle,
70035 geoChooseEdge: geoChooseEdge,
70036 geoLineIntersection: geoLineIntersection,
70037 geoPathIntersections: geoPathIntersections,
70038 geoPointInPolygon: geoPointInPolygon,
70039 geoPolygonContainsPolygon: geoPolygonContainsPolygon,
70040 geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
70041 geoPathLength: geoPathLength,
70042 geoExtent: geoExtent$$1,
70043 geoRawMercator: geoRawMercator,
70044 modeAddArea: modeAddArea$$1,
70045 modeAddLine: modeAddLine$$1,
70046 modeAddPoint: modeAddPoint$$1,
70047 modeBrowse: modeBrowse$$1,
70048 modeDragNode: modeDragNode$$1,
70049 modeDrawArea: modeDrawArea,
70050 modeDrawLine: modeDrawLine,
70051 modeMove: modeMove$$1,
70052 modeRotateWay: modeRotateWay$$1,
70053 modeSave: modeSave$$1,
70054 modeSelect: modeSelect,
70055 operationCircularize: operationCircularize,
70056 operationContinue: operationContinue,
70057 operationDelete: operationDelete,
70058 operationDisconnect: operationDisconnect,
70059 operationMerge: operationMerge,
70060 operationMove: operationMove,
70061 operationOrthogonalize: operationOrthogonalize,
70062 operationReverse: operationReverse,
70063 operationRotate: operationRotate,
70064 operationSplit: operationSplit,
70065 operationStraighten: operationStraighten,
70066 osmEntity: osmEntity$$1,
70068 osmRelation: osmRelation,
70070 osmIntersection: osmIntersection,
70072 osmInferRestriction: osmInferRestriction,
70073 osmLanes: osmLanes,
70074 osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
70075 osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
70076 osmJoinWays: osmJoinWays,
70077 osmOneWayTags: osmOneWayTags,
70078 osmPavedTags: osmPavedTags,
70079 osmIsInterestingTag: osmIsInterestingTag,
70080 presetCategory: presetCategory,
70081 presetCollection: presetCollection,
70082 presetField: presetField,
70083 presetPreset: presetPreset,
70084 presetIndex: presetIndex,
70085 rendererBackgroundSource: rendererBackgroundSource,
70086 rendererBackground: rendererBackground,
70087 rendererFeatures: rendererFeatures,
70088 rendererMap: rendererMap,
70089 rendererTileLayer: rendererTileLayer,
70090 services: services,
70091 svgAreas: svgAreas$$1,
70092 svgDebug: svgDebug,
70096 svgLabels: svgLabels,
70097 svgLayers: svgLayers,
70098 svgLines: svgLines$$1,
70099 svgMapillaryImages: svgMapillaryImages,
70100 svgMapillarySigns: svgMapillarySigns,
70101 svgMidpoints: svgMidpoints$$1,
70102 svgOneWaySegments: svgOneWaySegments,
70105 svgPointTransform: svgPointTransform,
70106 svgPoints: svgPoints$$1,
70107 svgRelationMemberTags: svgRelationMemberTags,
70108 svgTagClasses: svgTagClasses,
70109 svgTurns: svgTurns,
70110 svgVertices: svgVertices$$1,
70111 uiFields: uiFields,
70112 uiFieldDefaultcheck: uiFieldCheck,
70113 uiFieldCheck: uiFieldCheck,
70114 uiFieldTypeCombo: uiFieldCombo,
70115 uiFieldMultiCombo: uiFieldCombo,
70116 uiFieldNetworkCombo: uiFieldCombo,
70117 uiFieldCombo: uiFieldCombo,
70118 uiFieldUrl: uiFieldText,
70119 uiFieldNumber: uiFieldText,
70120 uiFieldTel: uiFieldText,
70121 uiFieldEmail: uiFieldText,
70122 uiFieldText: uiFieldText,
70123 uiFieldAccess: uiFieldAccess,
70124 uiFieldAddress: uiFieldAddress,
70125 uiFieldCycleway: uiFieldCycleway,
70126 uiFieldLanes: uiFieldLanes,
70127 uiFieldLocalized: uiFieldLocalized,
70128 uiFieldMaxspeed: uiFieldMaxspeed,
70129 uiFieldRadio: uiFieldRadio,
70130 uiFieldRestrictions: uiFieldRestrictions,
70131 uiFieldTextarea: uiFieldTextarea,
70132 uiFieldWikipedia: uiFieldWikipedia,
70135 uiAccount: uiAccount,
70136 uiAttribution: uiAttribution,
70137 uiBackground: uiBackground,
70139 uiCommit: uiCommit,
70140 uiConfirm: uiConfirm,
70141 uiConflicts: uiConflicts,
70142 uiContributors: uiContributors,
70143 uiDisclosure: uiDisclosure,
70144 uiEntityEditor: uiEntityEditor,
70145 uiFeatureInfo: uiFeatureInfo,
70146 uiFeatureList: uiFeatureList,
70148 uiFullScreen: uiFullScreen,
70149 uiGeolocate: uiGeolocate,
70152 uiInspector: uiInspector,
70154 uiLoading: uiLoading,
70155 uiMapData: uiMapData,
70156 uiMapInMap: uiMapInMap,
70159 uiNotice: uiNotice,
70160 uiPreset: uiPreset,
70161 uiPresetIcon: uiPresetIcon,
70162 uiPresetList: uiPresetList,
70163 uiRadialMenu: uiRadialMenu,
70164 uiRawMemberEditor: uiRawMemberEditor,
70165 uiRawMembershipEditor: uiRawMembershipEditor,
70166 uiRawTagEditor: uiRawTagEditor,
70167 uiRestore: uiRestore,
70170 uiSelectionList: uiSelectionList,
70171 uiSidebar: uiSidebar,
70172 uiSourceSwitch: uiSourceSwitch,
70173 uiSpinner: uiSpinner,
70174 uiSplash: uiSplash,
70175 uiStatus: uiStatus,
70176 uiSuccess: uiSuccess,
70177 uiTagReference: uiTagReference,
70178 uiToggle: uiToggle,
70179 uiTooltipHtml: uiTooltipHtml,
70180 uiUndoRedo: uiUndoRedo,
70181 uiViewOnOSM: uiViewOnOSM,
70183 utilTagText: utilTagText,
70184 utilEntitySelector: utilEntitySelector,
70185 utilEntityOrMemberSelector: utilEntityOrMemberSelector,
70186 utilDisplayName: utilDisplayName,
70187 utilDisplayType: utilDisplayType,
70188 utilStringQs: utilStringQs,
70189 utilQsString: utilQsString,
70190 utilPrefixDOMProperty: utilPrefixDOMProperty,
70191 utilPrefixCSSProperty: utilPrefixCSSProperty,
70192 utilSetTransform: utilSetTransform,
70193 utilEditDistance: utilEditDistance,
70194 utilFastMouse: utilFastMouse,
70195 utilGetPrototypeOf: utilGetPrototypeOf,
70196 utilAsyncMap: utilAsyncMap,
70197 utilWrap: utilWrap,
70198 utilFunctor: utilFunctor,
70199 utilSessionMutex: utilSessionMutex,
70200 utilSuggestNames: utilSuggestNames,
70201 utilTriggerEvent: utilTriggerEvent,
70202 utilGetSetValue: utilGetSetValue,
70203 d3combobox: d3combobox,
70204 d3geoTile: d3geoTile,
70205 d3keybinding: d3keybinding,
70206 validationDeprecatedTag: validationDeprecatedTag,
70207 validationManyDeletions: validationManyDeletions,
70208 validationMissingTag: validationMissingTag,
70209 validationTagSuggestsArea: validationTagSuggestsArea
70215 //# sourceMappingURL=iD.js.map