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.4';
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 = 'object' == 'object' && exports && !exports.nodeType && exports;
448 /** Detect free variable `module`. */
449 var freeModule = freeExports && 'object' == '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 and iteratees accept only
1591 * one argument. The heuristic for whether a section qualifies for shortcut
1592 * 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) as well as ES2015 template strings. Change the
1752 * following template settings to use 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 || (!isRight && arrLength == length && takeCount == length)) {
1900 return baseWrapperValue(array, this.__actions__);
1905 while (length-- && resIndex < takeCount) {
1909 value = array[index];
1911 while (++iterIndex < iterLength) {
1912 var data = iteratees[iterIndex],
1913 iteratee = data.iteratee,
1915 computed = iteratee(value);
1917 if (type == LAZY_MAP_FLAG) {
1919 } else if (!computed) {
1920 if (type == LAZY_FILTER_FLAG) {
1927 result[resIndex++] = value;
1932 // Ensure `LazyWrapper` is an instance of `baseLodash`.
1933 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1934 LazyWrapper.prototype.constructor = LazyWrapper;
1936 /*------------------------------------------------------------------------*/
1939 * Creates a hash object.
1943 * @param {Array} [entries] The key-value pairs to cache.
1945 function Hash(entries) {
1947 length = entries == null ? 0 : entries.length;
1950 while (++index < length) {
1951 var entry = entries[index];
1952 this.set(entry[0], entry[1]);
1957 * Removes all key-value entries from the hash.
1963 function hashClear() {
1964 this.__data__ = nativeCreate ? nativeCreate(null) : {};
1969 * Removes `key` and its value from the hash.
1974 * @param {Object} hash The hash to modify.
1975 * @param {string} key The key of the value to remove.
1976 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1978 function hashDelete(key) {
1979 var result = this.has(key) && delete this.__data__[key];
1980 this.size -= result ? 1 : 0;
1985 * Gets the hash value for `key`.
1990 * @param {string} key The key of the value to get.
1991 * @returns {*} Returns the entry value.
1993 function hashGet(key) {
1994 var data = this.__data__;
1996 var result = data[key];
1997 return result === HASH_UNDEFINED ? undefined : result;
1999 return hasOwnProperty.call(data, key) ? data[key] : undefined;
2003 * Checks if a hash value for `key` exists.
2008 * @param {string} key The key of the entry to check.
2009 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2011 function hashHas(key) {
2012 var data = this.__data__;
2013 return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
2017 * Sets the hash `key` to `value`.
2022 * @param {string} key The key of the value to set.
2023 * @param {*} value The value to set.
2024 * @returns {Object} Returns the hash instance.
2026 function hashSet(key, value) {
2027 var data = this.__data__;
2028 this.size += this.has(key) ? 0 : 1;
2029 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
2033 // Add methods to `Hash`.
2034 Hash.prototype.clear = hashClear;
2035 Hash.prototype['delete'] = hashDelete;
2036 Hash.prototype.get = hashGet;
2037 Hash.prototype.has = hashHas;
2038 Hash.prototype.set = hashSet;
2040 /*------------------------------------------------------------------------*/
2043 * Creates an list cache object.
2047 * @param {Array} [entries] The key-value pairs to cache.
2049 function ListCache(entries) {
2051 length = entries == null ? 0 : entries.length;
2054 while (++index < length) {
2055 var entry = entries[index];
2056 this.set(entry[0], entry[1]);
2061 * Removes all key-value entries from the list cache.
2065 * @memberOf ListCache
2067 function listCacheClear() {
2073 * Removes `key` and its value from the list cache.
2077 * @memberOf ListCache
2078 * @param {string} key The key of the value to remove.
2079 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2081 function listCacheDelete(key) {
2082 var data = this.__data__,
2083 index = assocIndexOf(data, key);
2088 var lastIndex = data.length - 1;
2089 if (index == lastIndex) {
2092 splice.call(data, index, 1);
2099 * Gets the list cache value for `key`.
2103 * @memberOf ListCache
2104 * @param {string} key The key of the value to get.
2105 * @returns {*} Returns the entry value.
2107 function listCacheGet(key) {
2108 var data = this.__data__,
2109 index = assocIndexOf(data, key);
2111 return index < 0 ? undefined : data[index][1];
2115 * Checks if a list cache value for `key` exists.
2119 * @memberOf ListCache
2120 * @param {string} key The key of the entry to check.
2121 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2123 function listCacheHas(key) {
2124 return assocIndexOf(this.__data__, key) > -1;
2128 * Sets the list cache `key` to `value`.
2132 * @memberOf ListCache
2133 * @param {string} key The key of the value to set.
2134 * @param {*} value The value to set.
2135 * @returns {Object} Returns the list cache instance.
2137 function listCacheSet(key, value) {
2138 var data = this.__data__,
2139 index = assocIndexOf(data, key);
2143 data.push([key, value]);
2145 data[index][1] = value;
2150 // Add methods to `ListCache`.
2151 ListCache.prototype.clear = listCacheClear;
2152 ListCache.prototype['delete'] = listCacheDelete;
2153 ListCache.prototype.get = listCacheGet;
2154 ListCache.prototype.has = listCacheHas;
2155 ListCache.prototype.set = listCacheSet;
2157 /*------------------------------------------------------------------------*/
2160 * Creates a map cache object to store key-value pairs.
2164 * @param {Array} [entries] The key-value pairs to cache.
2166 function MapCache(entries) {
2168 length = entries == null ? 0 : entries.length;
2171 while (++index < length) {
2172 var entry = entries[index];
2173 this.set(entry[0], entry[1]);
2178 * Removes all key-value entries from the map.
2182 * @memberOf MapCache
2184 function mapCacheClear() {
2188 'map': new (Map || ListCache),
2194 * Removes `key` and its value from the map.
2198 * @memberOf MapCache
2199 * @param {string} key The key of the value to remove.
2200 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2202 function mapCacheDelete(key) {
2203 var result = getMapData(this, key)['delete'](key);
2204 this.size -= result ? 1 : 0;
2209 * Gets the map value for `key`.
2213 * @memberOf MapCache
2214 * @param {string} key The key of the value to get.
2215 * @returns {*} Returns the entry value.
2217 function mapCacheGet(key) {
2218 return getMapData(this, key).get(key);
2222 * Checks if a map value for `key` exists.
2226 * @memberOf MapCache
2227 * @param {string} key The key of the entry to check.
2228 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2230 function mapCacheHas(key) {
2231 return getMapData(this, key).has(key);
2235 * Sets the map `key` to `value`.
2239 * @memberOf MapCache
2240 * @param {string} key The key of the value to set.
2241 * @param {*} value The value to set.
2242 * @returns {Object} Returns the map cache instance.
2244 function mapCacheSet(key, value) {
2245 var data = getMapData(this, key),
2248 data.set(key, value);
2249 this.size += data.size == size ? 0 : 1;
2253 // Add methods to `MapCache`.
2254 MapCache.prototype.clear = mapCacheClear;
2255 MapCache.prototype['delete'] = mapCacheDelete;
2256 MapCache.prototype.get = mapCacheGet;
2257 MapCache.prototype.has = mapCacheHas;
2258 MapCache.prototype.set = mapCacheSet;
2260 /*------------------------------------------------------------------------*/
2264 * Creates an array cache object to store unique values.
2268 * @param {Array} [values] The values to cache.
2270 function SetCache(values) {
2272 length = values == null ? 0 : values.length;
2274 this.__data__ = new MapCache;
2275 while (++index < length) {
2276 this.add(values[index]);
2281 * Adds `value` to the array cache.
2285 * @memberOf SetCache
2287 * @param {*} value The value to cache.
2288 * @returns {Object} Returns the cache instance.
2290 function setCacheAdd(value) {
2291 this.__data__.set(value, HASH_UNDEFINED);
2296 * Checks if `value` is in the array cache.
2300 * @memberOf SetCache
2301 * @param {*} value The value to search for.
2302 * @returns {number} Returns `true` if `value` is found, else `false`.
2304 function setCacheHas(value) {
2305 return this.__data__.has(value);
2308 // Add methods to `SetCache`.
2309 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2310 SetCache.prototype.has = setCacheHas;
2312 /*------------------------------------------------------------------------*/
2315 * Creates a stack cache object to store key-value pairs.
2319 * @param {Array} [entries] The key-value pairs to cache.
2321 function Stack(entries) {
2322 var data = this.__data__ = new ListCache(entries);
2323 this.size = data.size;
2327 * Removes all key-value entries from the stack.
2333 function stackClear() {
2334 this.__data__ = new ListCache;
2339 * Removes `key` and its value from the stack.
2344 * @param {string} key The key of the value to remove.
2345 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2347 function stackDelete(key) {
2348 var data = this.__data__,
2349 result = data['delete'](key);
2351 this.size = data.size;
2356 * Gets the stack value for `key`.
2361 * @param {string} key The key of the value to get.
2362 * @returns {*} Returns the entry value.
2364 function stackGet(key) {
2365 return this.__data__.get(key);
2369 * Checks if a stack value for `key` exists.
2374 * @param {string} key The key of the entry to check.
2375 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2377 function stackHas(key) {
2378 return this.__data__.has(key);
2382 * Sets the stack `key` to `value`.
2387 * @param {string} key The key of the value to set.
2388 * @param {*} value The value to set.
2389 * @returns {Object} Returns the stack cache instance.
2391 function stackSet(key, value) {
2392 var data = this.__data__;
2393 if (data instanceof ListCache) {
2394 var pairs = data.__data__;
2395 if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2396 pairs.push([key, value]);
2397 this.size = ++data.size;
2400 data = this.__data__ = new MapCache(pairs);
2402 data.set(key, value);
2403 this.size = data.size;
2407 // Add methods to `Stack`.
2408 Stack.prototype.clear = stackClear;
2409 Stack.prototype['delete'] = stackDelete;
2410 Stack.prototype.get = stackGet;
2411 Stack.prototype.has = stackHas;
2412 Stack.prototype.set = stackSet;
2414 /*------------------------------------------------------------------------*/
2417 * Creates an array of the enumerable property names of the array-like `value`.
2420 * @param {*} value The value to query.
2421 * @param {boolean} inherited Specify returning inherited property names.
2422 * @returns {Array} Returns the array of property names.
2424 function arrayLikeKeys(value, inherited) {
2425 var isArr = isArray(value),
2426 isArg = !isArr && isArguments(value),
2427 isBuff = !isArr && !isArg && isBuffer(value),
2428 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2429 skipIndexes = isArr || isArg || isBuff || isType,
2430 result = skipIndexes ? baseTimes(value.length, String) : [],
2431 length = result.length;
2433 for (var key in value) {
2434 if ((inherited || hasOwnProperty.call(value, key)) &&
2436 // Safari 9 has enumerable `arguments.length` in strict mode.
2438 // Node.js 0.10 has enumerable non-index properties on buffers.
2439 (isBuff && (key == 'offset' || key == 'parent')) ||
2440 // PhantomJS 2 has enumerable non-index properties on typed arrays.
2441 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2442 // Skip index properties.
2443 isIndex(key, length)
2452 * A specialized version of `_.sample` for arrays.
2455 * @param {Array} array The array to sample.
2456 * @returns {*} Returns the random element.
2458 function arraySample(array) {
2459 var length = array.length;
2460 return length ? array[baseRandom(0, length - 1)] : undefined;
2464 * A specialized version of `_.sampleSize` for arrays.
2467 * @param {Array} array The array to sample.
2468 * @param {number} n The number of elements to sample.
2469 * @returns {Array} Returns the random elements.
2471 function arraySampleSize(array, n) {
2472 return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
2476 * A specialized version of `_.shuffle` for arrays.
2479 * @param {Array} array The array to shuffle.
2480 * @returns {Array} Returns the new shuffled array.
2482 function arrayShuffle(array) {
2483 return shuffleSelf(copyArray(array));
2487 * This function is like `assignValue` except that it doesn't assign
2488 * `undefined` values.
2491 * @param {Object} object The object to modify.
2492 * @param {string} key The key of the property to assign.
2493 * @param {*} value The value to assign.
2495 function assignMergeValue(object, key, value) {
2496 if ((value !== undefined && !eq(object[key], value)) ||
2497 (value === undefined && !(key in object))) {
2498 baseAssignValue(object, key, value);
2503 * Assigns `value` to `key` of `object` if the existing value is not equivalent
2504 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
2505 * for equality comparisons.
2508 * @param {Object} object The object to modify.
2509 * @param {string} key The key of the property to assign.
2510 * @param {*} value The value to assign.
2512 function assignValue(object, key, value) {
2513 var objValue = object[key];
2514 if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2515 (value === undefined && !(key in object))) {
2516 baseAssignValue(object, key, value);
2521 * Gets the index at which the `key` is found in `array` of key-value pairs.
2524 * @param {Array} array The array to inspect.
2525 * @param {*} key The key to search for.
2526 * @returns {number} Returns the index of the matched value, else `-1`.
2528 function assocIndexOf(array, key) {
2529 var length = array.length;
2531 if (eq(array[length][0], key)) {
2539 * Aggregates elements of `collection` on `accumulator` with keys transformed
2540 * by `iteratee` and values set by `setter`.
2543 * @param {Array|Object} collection The collection to iterate over.
2544 * @param {Function} setter The function to set `accumulator` values.
2545 * @param {Function} iteratee The iteratee to transform keys.
2546 * @param {Object} accumulator The initial aggregated object.
2547 * @returns {Function} Returns `accumulator`.
2549 function baseAggregator(collection, setter, iteratee, accumulator) {
2550 baseEach(collection, function(value, key, collection) {
2551 setter(accumulator, value, iteratee(value), collection);
2557 * The base implementation of `_.assign` without support for multiple sources
2558 * or `customizer` functions.
2561 * @param {Object} object The destination object.
2562 * @param {Object} source The source object.
2563 * @returns {Object} Returns `object`.
2565 function baseAssign(object, source) {
2566 return object && copyObject(source, keys(source), object);
2570 * The base implementation of `_.assignIn` without support for multiple sources
2571 * or `customizer` functions.
2574 * @param {Object} object The destination object.
2575 * @param {Object} source The source object.
2576 * @returns {Object} Returns `object`.
2578 function baseAssignIn(object, source) {
2579 return object && copyObject(source, keysIn(source), object);
2583 * The base implementation of `assignValue` and `assignMergeValue` without
2587 * @param {Object} object The object to modify.
2588 * @param {string} key The key of the property to assign.
2589 * @param {*} value The value to assign.
2591 function baseAssignValue(object, key, value) {
2592 if (key == '__proto__' && defineProperty) {
2593 defineProperty(object, key, {
2594 'configurable': true,
2600 object[key] = value;
2605 * The base implementation of `_.at` without support for individual paths.
2608 * @param {Object} object The object to iterate over.
2609 * @param {string[]} paths The property paths to pick.
2610 * @returns {Array} Returns the picked elements.
2612 function baseAt(object, paths) {
2614 length = paths.length,
2615 result = Array(length),
2616 skip = object == null;
2618 while (++index < length) {
2619 result[index] = skip ? undefined : get(object, paths[index]);
2625 * The base implementation of `_.clamp` which doesn't coerce arguments.
2628 * @param {number} number The number to clamp.
2629 * @param {number} [lower] The lower bound.
2630 * @param {number} upper The upper bound.
2631 * @returns {number} Returns the clamped number.
2633 function baseClamp(number, lower, upper) {
2634 if (number === number) {
2635 if (upper !== undefined) {
2636 number = number <= upper ? number : upper;
2638 if (lower !== undefined) {
2639 number = number >= lower ? number : lower;
2646 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2647 * traversed objects.
2650 * @param {*} value The value to clone.
2651 * @param {boolean} bitmask The bitmask flags.
2653 * 2 - Flatten inherited properties
2655 * @param {Function} [customizer] The function to customize cloning.
2656 * @param {string} [key] The key of `value`.
2657 * @param {Object} [object] The parent object of `value`.
2658 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2659 * @returns {*} Returns the cloned value.
2661 function baseClone(value, bitmask, customizer, key, object, stack) {
2663 isDeep = bitmask & CLONE_DEEP_FLAG,
2664 isFlat = bitmask & CLONE_FLAT_FLAG,
2665 isFull = bitmask & CLONE_SYMBOLS_FLAG;
2668 result = object ? customizer(value, key, object, stack) : customizer(value);
2670 if (result !== undefined) {
2673 if (!isObject(value)) {
2676 var isArr = isArray(value);
2678 result = initCloneArray(value);
2680 return copyArray(value, result);
2683 var tag = getTag(value),
2684 isFunc = tag == funcTag || tag == genTag;
2686 if (isBuffer(value)) {
2687 return cloneBuffer(value, isDeep);
2689 if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2690 result = (isFlat || isFunc) ? {} : initCloneObject(value);
2693 ? copySymbolsIn(value, baseAssignIn(result, value))
2694 : copySymbols(value, baseAssign(result, value));
2697 if (!cloneableTags[tag]) {
2698 return object ? value : {};
2700 result = initCloneByTag(value, tag, baseClone, isDeep);
2703 // Check for circular references and return its corresponding clone.
2704 stack || (stack = new Stack);
2705 var stacked = stack.get(value);
2709 stack.set(value, result);
2711 var keysFunc = isFull
2712 ? (isFlat ? getAllKeysIn : getAllKeys)
2713 : (isFlat ? keysIn : keys);
2715 var props = isArr ? undefined : keysFunc(value);
2716 arrayEach(props || value, function(subValue, key) {
2719 subValue = value[key];
2721 // Recursively populate clone (susceptible to call stack limits).
2722 assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
2728 * The base implementation of `_.conforms` which doesn't clone `source`.
2731 * @param {Object} source The object of property predicates to conform to.
2732 * @returns {Function} Returns the new spec function.
2734 function baseConforms(source) {
2735 var props = keys(source);
2736 return function(object) {
2737 return baseConformsTo(object, source, props);
2742 * The base implementation of `_.conformsTo` which accepts `props` to check.
2745 * @param {Object} object The object to inspect.
2746 * @param {Object} source The object of property predicates to conform to.
2747 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
2749 function baseConformsTo(object, source, props) {
2750 var length = props.length;
2751 if (object == null) {
2754 object = Object(object);
2756 var key = props[length],
2757 predicate = source[key],
2758 value = object[key];
2760 if ((value === undefined && !(key in object)) || !predicate(value)) {
2768 * The base implementation of `_.delay` and `_.defer` which accepts `args`
2769 * to provide to `func`.
2772 * @param {Function} func The function to delay.
2773 * @param {number} wait The number of milliseconds to delay invocation.
2774 * @param {Array} args The arguments to provide to `func`.
2775 * @returns {number|Object} Returns the timer id or timeout object.
2777 function baseDelay(func, wait, args) {
2778 if (typeof func != 'function') {
2779 throw new TypeError(FUNC_ERROR_TEXT);
2781 return setTimeout(function() { func.apply(undefined, args); }, wait);
2785 * The base implementation of methods like `_.difference` without support
2786 * for excluding multiple arrays or iteratee shorthands.
2789 * @param {Array} array The array to inspect.
2790 * @param {Array} values The values to exclude.
2791 * @param {Function} [iteratee] The iteratee invoked per element.
2792 * @param {Function} [comparator] The comparator invoked per element.
2793 * @returns {Array} Returns the new array of filtered values.
2795 function baseDifference(array, values, iteratee, comparator) {
2797 includes = arrayIncludes,
2799 length = array.length,
2801 valuesLength = values.length;
2807 values = arrayMap(values, baseUnary(iteratee));
2810 includes = arrayIncludesWith;
2813 else if (values.length >= LARGE_ARRAY_SIZE) {
2814 includes = cacheHas;
2816 values = new SetCache(values);
2819 while (++index < length) {
2820 var value = array[index],
2821 computed = iteratee == null ? value : iteratee(value);
2823 value = (comparator || value !== 0) ? value : 0;
2824 if (isCommon && computed === computed) {
2825 var valuesIndex = valuesLength;
2826 while (valuesIndex--) {
2827 if (values[valuesIndex] === computed) {
2833 else if (!includes(values, computed, comparator)) {
2841 * The base implementation of `_.forEach` without support for iteratee shorthands.
2844 * @param {Array|Object} collection The collection to iterate over.
2845 * @param {Function} iteratee The function invoked per iteration.
2846 * @returns {Array|Object} Returns `collection`.
2848 var baseEach = createBaseEach(baseForOwn);
2851 * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2854 * @param {Array|Object} collection The collection to iterate over.
2855 * @param {Function} iteratee The function invoked per iteration.
2856 * @returns {Array|Object} Returns `collection`.
2858 var baseEachRight = createBaseEach(baseForOwnRight, true);
2861 * The base implementation of `_.every` without support for iteratee shorthands.
2864 * @param {Array|Object} collection The collection to iterate over.
2865 * @param {Function} predicate The function invoked per iteration.
2866 * @returns {boolean} Returns `true` if all elements pass the predicate check,
2869 function baseEvery(collection, predicate) {
2871 baseEach(collection, function(value, index, collection) {
2872 result = !!predicate(value, index, collection);
2879 * The base implementation of methods like `_.max` and `_.min` which accepts a
2880 * `comparator` to determine the extremum value.
2883 * @param {Array} array The array to iterate over.
2884 * @param {Function} iteratee The iteratee invoked per iteration.
2885 * @param {Function} comparator The comparator used to compare values.
2886 * @returns {*} Returns the extremum value.
2888 function baseExtremum(array, iteratee, comparator) {
2890 length = array.length;
2892 while (++index < length) {
2893 var value = array[index],
2894 current = iteratee(value);
2896 if (current != null && (computed === undefined
2897 ? (current === current && !isSymbol(current))
2898 : comparator(current, computed)
2900 var computed = current,
2908 * The base implementation of `_.fill` without an iteratee call guard.
2911 * @param {Array} array The array to fill.
2912 * @param {*} value The value to fill `array` with.
2913 * @param {number} [start=0] The start position.
2914 * @param {number} [end=array.length] The end position.
2915 * @returns {Array} Returns `array`.
2917 function baseFill(array, value, start, end) {
2918 var length = array.length;
2920 start = toInteger(start);
2922 start = -start > length ? 0 : (length + start);
2924 end = (end === undefined || end > length) ? length : toInteger(end);
2928 end = start > end ? 0 : toLength(end);
2929 while (start < end) {
2930 array[start++] = value;
2936 * The base implementation of `_.filter` without support for iteratee shorthands.
2939 * @param {Array|Object} collection The collection to iterate over.
2940 * @param {Function} predicate The function invoked per iteration.
2941 * @returns {Array} Returns the new filtered array.
2943 function baseFilter(collection, predicate) {
2945 baseEach(collection, function(value, index, collection) {
2946 if (predicate(value, index, collection)) {
2954 * The base implementation of `_.flatten` with support for restricting flattening.
2957 * @param {Array} array The array to flatten.
2958 * @param {number} depth The maximum recursion depth.
2959 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2960 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2961 * @param {Array} [result=[]] The initial result value.
2962 * @returns {Array} Returns the new flattened array.
2964 function baseFlatten(array, depth, predicate, isStrict, result) {
2966 length = array.length;
2968 predicate || (predicate = isFlattenable);
2969 result || (result = []);
2971 while (++index < length) {
2972 var value = array[index];
2973 if (depth > 0 && predicate(value)) {
2975 // Recursively flatten arrays (susceptible to call stack limits).
2976 baseFlatten(value, depth - 1, predicate, isStrict, result);
2978 arrayPush(result, value);
2980 } else if (!isStrict) {
2981 result[result.length] = value;
2988 * The base implementation of `baseForOwn` which iterates over `object`
2989 * properties returned by `keysFunc` and invokes `iteratee` for each property.
2990 * Iteratee functions may exit iteration early by explicitly returning `false`.
2993 * @param {Object} object The object to iterate over.
2994 * @param {Function} iteratee The function invoked per iteration.
2995 * @param {Function} keysFunc The function to get the keys of `object`.
2996 * @returns {Object} Returns `object`.
2998 var baseFor = createBaseFor();
3001 * This function is like `baseFor` except that it iterates over properties
3002 * in the opposite order.
3005 * @param {Object} object The object to iterate over.
3006 * @param {Function} iteratee The function invoked per iteration.
3007 * @param {Function} keysFunc The function to get the keys of `object`.
3008 * @returns {Object} Returns `object`.
3010 var baseForRight = createBaseFor(true);
3013 * The base implementation of `_.forOwn` without support for iteratee shorthands.
3016 * @param {Object} object The object to iterate over.
3017 * @param {Function} iteratee The function invoked per iteration.
3018 * @returns {Object} Returns `object`.
3020 function baseForOwn(object, iteratee) {
3021 return object && baseFor(object, iteratee, keys);
3025 * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
3028 * @param {Object} object The object to iterate over.
3029 * @param {Function} iteratee The function invoked per iteration.
3030 * @returns {Object} Returns `object`.
3032 function baseForOwnRight(object, iteratee) {
3033 return object && baseForRight(object, iteratee, keys);
3037 * The base implementation of `_.functions` which creates an array of
3038 * `object` function property names filtered from `props`.
3041 * @param {Object} object The object to inspect.
3042 * @param {Array} props The property names to filter.
3043 * @returns {Array} Returns the function names.
3045 function baseFunctions(object, props) {
3046 return arrayFilter(props, function(key) {
3047 return isFunction(object[key]);
3052 * The base implementation of `_.get` without support for default values.
3055 * @param {Object} object The object to query.
3056 * @param {Array|string} path The path of the property to get.
3057 * @returns {*} Returns the resolved value.
3059 function baseGet(object, path) {
3060 path = castPath(path, object);
3063 length = path.length;
3065 while (object != null && index < length) {
3066 object = object[toKey(path[index++])];
3068 return (index && index == length) ? object : undefined;
3072 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
3073 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
3074 * symbols of `object`.
3077 * @param {Object} object The object to query.
3078 * @param {Function} keysFunc The function to get the keys of `object`.
3079 * @param {Function} symbolsFunc The function to get the symbols of `object`.
3080 * @returns {Array} Returns the array of property names and symbols.
3082 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
3083 var result = keysFunc(object);
3084 return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
3088 * The base implementation of `getTag` without fallbacks for buggy environments.
3091 * @param {*} value The value to query.
3092 * @returns {string} Returns the `toStringTag`.
3094 function baseGetTag(value) {
3095 if (value == null) {
3096 return value === undefined ? undefinedTag : nullTag;
3098 return (symToStringTag && symToStringTag in Object(value))
3100 : objectToString(value);
3104 * The base implementation of `_.gt` which doesn't coerce arguments.
3107 * @param {*} value The value to compare.
3108 * @param {*} other The other value to compare.
3109 * @returns {boolean} Returns `true` if `value` is greater than `other`,
3112 function baseGt(value, other) {
3113 return value > other;
3117 * The base implementation of `_.has` without support for deep paths.
3120 * @param {Object} [object] The object to query.
3121 * @param {Array|string} key The key to check.
3122 * @returns {boolean} Returns `true` if `key` exists, else `false`.
3124 function baseHas(object, key) {
3125 return object != null && hasOwnProperty.call(object, key);
3129 * The base implementation of `_.hasIn` without support for deep paths.
3132 * @param {Object} [object] The object to query.
3133 * @param {Array|string} key The key to check.
3134 * @returns {boolean} Returns `true` if `key` exists, else `false`.
3136 function baseHasIn(object, key) {
3137 return object != null && key in Object(object);
3141 * The base implementation of `_.inRange` which doesn't coerce arguments.
3144 * @param {number} number The number to check.
3145 * @param {number} start The start of the range.
3146 * @param {number} end The end of the range.
3147 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
3149 function baseInRange(number, start, end) {
3150 return number >= nativeMin(start, end) && number < nativeMax(start, end);
3154 * The base implementation of methods like `_.intersection`, without support
3155 * for iteratee shorthands, that accepts an array of arrays to inspect.
3158 * @param {Array} arrays The arrays to inspect.
3159 * @param {Function} [iteratee] The iteratee invoked per element.
3160 * @param {Function} [comparator] The comparator invoked per element.
3161 * @returns {Array} Returns the new array of shared values.
3163 function baseIntersection(arrays, iteratee, comparator) {
3164 var includes = comparator ? arrayIncludesWith : arrayIncludes,
3165 length = arrays[0].length,
3166 othLength = arrays.length,
3167 othIndex = othLength,
3168 caches = Array(othLength),
3169 maxLength = Infinity,
3172 while (othIndex--) {
3173 var array = arrays[othIndex];
3174 if (othIndex && iteratee) {
3175 array = arrayMap(array, baseUnary(iteratee));
3177 maxLength = nativeMin(array.length, maxLength);
3178 caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
3179 ? new SetCache(othIndex && array)
3188 while (++index < length && result.length < maxLength) {
3189 var value = array[index],
3190 computed = iteratee ? iteratee(value) : value;
3192 value = (comparator || value !== 0) ? value : 0;
3194 ? cacheHas(seen, computed)
3195 : includes(result, computed, comparator)
3197 othIndex = othLength;
3198 while (--othIndex) {
3199 var cache = caches[othIndex];
3201 ? cacheHas(cache, computed)
3202 : includes(arrays[othIndex], computed, comparator))
3208 seen.push(computed);
3217 * The base implementation of `_.invert` and `_.invertBy` which inverts
3218 * `object` with values transformed by `iteratee` and set by `setter`.
3221 * @param {Object} object The object to iterate over.
3222 * @param {Function} setter The function to set `accumulator` values.
3223 * @param {Function} iteratee The iteratee to transform values.
3224 * @param {Object} accumulator The initial inverted object.
3225 * @returns {Function} Returns `accumulator`.
3227 function baseInverter(object, setter, iteratee, accumulator) {
3228 baseForOwn(object, function(value, key, object) {
3229 setter(accumulator, iteratee(value), key, object);
3235 * The base implementation of `_.invoke` without support for individual
3239 * @param {Object} object The object to query.
3240 * @param {Array|string} path The path of the method to invoke.
3241 * @param {Array} args The arguments to invoke the method with.
3242 * @returns {*} Returns the result of the invoked method.
3244 function baseInvoke(object, path, args) {
3245 path = castPath(path, object);
3246 object = parent(object, path);
3247 var func = object == null ? object : object[toKey(last(path))];
3248 return func == null ? undefined : apply(func, object, args);
3252 * The base implementation of `_.isArguments`.
3255 * @param {*} value The value to check.
3256 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3258 function baseIsArguments(value) {
3259 return isObjectLike(value) && baseGetTag(value) == argsTag;
3263 * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
3266 * @param {*} value The value to check.
3267 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
3269 function baseIsArrayBuffer(value) {
3270 return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
3274 * The base implementation of `_.isDate` without Node.js optimizations.
3277 * @param {*} value The value to check.
3278 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
3280 function baseIsDate(value) {
3281 return isObjectLike(value) && baseGetTag(value) == dateTag;
3285 * The base implementation of `_.isEqual` which supports partial comparisons
3286 * and tracks traversed objects.
3289 * @param {*} value The value to compare.
3290 * @param {*} other The other value to compare.
3291 * @param {boolean} bitmask The bitmask flags.
3292 * 1 - Unordered comparison
3293 * 2 - Partial comparison
3294 * @param {Function} [customizer] The function to customize comparisons.
3295 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
3296 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3298 function baseIsEqual(value, other, bitmask, customizer, stack) {
3299 if (value === other) {
3302 if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
3303 return value !== value && other !== other;
3305 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
3309 * A specialized version of `baseIsEqual` for arrays and objects which performs
3310 * deep comparisons and tracks traversed objects enabling objects with circular
3311 * references to be compared.
3314 * @param {Object} object The object to compare.
3315 * @param {Object} other The other object to compare.
3316 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
3317 * @param {Function} customizer The function to customize comparisons.
3318 * @param {Function} equalFunc The function to determine equivalents of values.
3319 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
3320 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
3322 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
3323 var objIsArr = isArray(object),
3324 othIsArr = isArray(other),
3325 objTag = objIsArr ? arrayTag : getTag(object),
3326 othTag = othIsArr ? arrayTag : getTag(other);
3328 objTag = objTag == argsTag ? objectTag : objTag;
3329 othTag = othTag == argsTag ? objectTag : othTag;
3331 var objIsObj = objTag == objectTag,
3332 othIsObj = othTag == objectTag,
3333 isSameTag = objTag == othTag;
3335 if (isSameTag && isBuffer(object)) {
3336 if (!isBuffer(other)) {
3342 if (isSameTag && !objIsObj) {
3343 stack || (stack = new Stack);
3344 return (objIsArr || isTypedArray(object))
3345 ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
3346 : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
3348 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
3349 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
3350 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
3352 if (objIsWrapped || othIsWrapped) {
3353 var objUnwrapped = objIsWrapped ? object.value() : object,
3354 othUnwrapped = othIsWrapped ? other.value() : other;
3356 stack || (stack = new Stack);
3357 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
3363 stack || (stack = new Stack);
3364 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
3368 * The base implementation of `_.isMap` without Node.js optimizations.
3371 * @param {*} value The value to check.
3372 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
3374 function baseIsMap(value) {
3375 return isObjectLike(value) && getTag(value) == mapTag;
3379 * The base implementation of `_.isMatch` without support for iteratee shorthands.
3382 * @param {Object} object The object to inspect.
3383 * @param {Object} source The object of property values to match.
3384 * @param {Array} matchData The property names, values, and compare flags to match.
3385 * @param {Function} [customizer] The function to customize comparisons.
3386 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
3388 function baseIsMatch(object, source, matchData, customizer) {
3389 var index = matchData.length,
3391 noCustomizer = !customizer;
3393 if (object == null) {
3396 object = Object(object);
3398 var data = matchData[index];
3399 if ((noCustomizer && data[2])
3400 ? data[1] !== object[data[0]]
3401 : !(data[0] in object)
3406 while (++index < length) {
3407 data = matchData[index];
3409 objValue = object[key],
3412 if (noCustomizer && data[2]) {
3413 if (objValue === undefined && !(key in object)) {
3417 var stack = new Stack;
3419 var result = customizer(objValue, srcValue, key, object, source, stack);
3421 if (!(result === undefined
3422 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
3433 * The base implementation of `_.isNative` without bad shim checks.
3436 * @param {*} value The value to check.
3437 * @returns {boolean} Returns `true` if `value` is a native function,
3440 function baseIsNative(value) {
3441 if (!isObject(value) || isMasked(value)) {
3444 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3445 return pattern.test(toSource(value));
3449 * The base implementation of `_.isRegExp` without Node.js optimizations.
3452 * @param {*} value The value to check.
3453 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
3455 function baseIsRegExp(value) {
3456 return isObjectLike(value) && baseGetTag(value) == regexpTag;
3460 * The base implementation of `_.isSet` without Node.js optimizations.
3463 * @param {*} value The value to check.
3464 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
3466 function baseIsSet(value) {
3467 return isObjectLike(value) && getTag(value) == setTag;
3471 * The base implementation of `_.isTypedArray` without Node.js optimizations.
3474 * @param {*} value The value to check.
3475 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3477 function baseIsTypedArray(value) {
3478 return isObjectLike(value) &&
3479 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
3483 * The base implementation of `_.iteratee`.
3486 * @param {*} [value=_.identity] The value to convert to an iteratee.
3487 * @returns {Function} Returns the iteratee.
3489 function baseIteratee(value) {
3490 // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3491 // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3492 if (typeof value == 'function') {
3495 if (value == null) {
3498 if (typeof value == 'object') {
3499 return isArray(value)
3500 ? baseMatchesProperty(value[0], value[1])
3501 : baseMatches(value);
3503 return property(value);
3507 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
3510 * @param {Object} object The object to query.
3511 * @returns {Array} Returns the array of property names.
3513 function baseKeys(object) {
3514 if (!isPrototype(object)) {
3515 return nativeKeys(object);
3518 for (var key in Object(object)) {
3519 if (hasOwnProperty.call(object, key) && key != 'constructor') {
3527 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
3530 * @param {Object} object The object to query.
3531 * @returns {Array} Returns the array of property names.
3533 function baseKeysIn(object) {
3534 if (!isObject(object)) {
3535 return nativeKeysIn(object);
3537 var isProto = isPrototype(object),
3540 for (var key in object) {
3541 if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3549 * The base implementation of `_.lt` which doesn't coerce arguments.
3552 * @param {*} value The value to compare.
3553 * @param {*} other The other value to compare.
3554 * @returns {boolean} Returns `true` if `value` is less than `other`,
3557 function baseLt(value, other) {
3558 return value < other;
3562 * The base implementation of `_.map` without support for iteratee shorthands.
3565 * @param {Array|Object} collection The collection to iterate over.
3566 * @param {Function} iteratee The function invoked per iteration.
3567 * @returns {Array} Returns the new mapped array.
3569 function baseMap(collection, iteratee) {
3571 result = isArrayLike(collection) ? Array(collection.length) : [];
3573 baseEach(collection, function(value, key, collection) {
3574 result[++index] = iteratee(value, key, collection);
3580 * The base implementation of `_.matches` which doesn't clone `source`.
3583 * @param {Object} source The object of property values to match.
3584 * @returns {Function} Returns the new spec function.
3586 function baseMatches(source) {
3587 var matchData = getMatchData(source);
3588 if (matchData.length == 1 && matchData[0][2]) {
3589 return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3591 return function(object) {
3592 return object === source || baseIsMatch(object, source, matchData);
3597 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3600 * @param {string} path The path of the property to get.
3601 * @param {*} srcValue The value to match.
3602 * @returns {Function} Returns the new spec function.
3604 function baseMatchesProperty(path, srcValue) {
3605 if (isKey(path) && isStrictComparable(srcValue)) {
3606 return matchesStrictComparable(toKey(path), srcValue);
3608 return function(object) {
3609 var objValue = get(object, path);
3610 return (objValue === undefined && objValue === srcValue)
3611 ? hasIn(object, path)
3612 : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
3617 * The base implementation of `_.merge` without support for multiple sources.
3620 * @param {Object} object The destination object.
3621 * @param {Object} source The source object.
3622 * @param {number} srcIndex The index of `source`.
3623 * @param {Function} [customizer] The function to customize merged values.
3624 * @param {Object} [stack] Tracks traversed source values and their merged
3627 function baseMerge(object, source, srcIndex, customizer, stack) {
3628 if (object === source) {
3631 baseFor(source, function(srcValue, key) {
3632 if (isObject(srcValue)) {
3633 stack || (stack = new Stack);
3634 baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3637 var newValue = customizer
3638 ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3641 if (newValue === undefined) {
3642 newValue = srcValue;
3644 assignMergeValue(object, key, newValue);
3650 * A specialized version of `baseMerge` for arrays and objects which performs
3651 * deep merges and tracks traversed objects enabling objects with circular
3652 * references to be merged.
3655 * @param {Object} object The destination object.
3656 * @param {Object} source The source object.
3657 * @param {string} key The key of the value to merge.
3658 * @param {number} srcIndex The index of `source`.
3659 * @param {Function} mergeFunc The function to merge values.
3660 * @param {Function} [customizer] The function to customize assigned values.
3661 * @param {Object} [stack] Tracks traversed source values and their merged
3664 function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3665 var objValue = object[key],
3666 srcValue = source[key],
3667 stacked = stack.get(srcValue);
3670 assignMergeValue(object, key, stacked);
3673 var newValue = customizer
3674 ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3677 var isCommon = newValue === undefined;
3680 var isArr = isArray(srcValue),
3681 isBuff = !isArr && isBuffer(srcValue),
3682 isTyped = !isArr && !isBuff && isTypedArray(srcValue);
3684 newValue = srcValue;
3685 if (isArr || isBuff || isTyped) {
3686 if (isArray(objValue)) {
3687 newValue = objValue;
3689 else if (isArrayLikeObject(objValue)) {
3690 newValue = copyArray(objValue);
3694 newValue = cloneBuffer(srcValue, true);
3698 newValue = cloneTypedArray(srcValue, true);
3704 else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3705 newValue = objValue;
3706 if (isArguments(objValue)) {
3707 newValue = toPlainObject(objValue);
3709 else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3710 newValue = initCloneObject(srcValue);
3718 // Recursively merge objects and arrays (susceptible to call stack limits).
3719 stack.set(srcValue, newValue);
3720 mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3721 stack['delete'](srcValue);
3723 assignMergeValue(object, key, newValue);
3727 * The base implementation of `_.nth` which doesn't coerce arguments.
3730 * @param {Array} array The array to query.
3731 * @param {number} n The index of the element to return.
3732 * @returns {*} Returns the nth element of `array`.
3734 function baseNth(array, n) {
3735 var length = array.length;
3739 n += n < 0 ? length : 0;
3740 return isIndex(n, length) ? array[n] : undefined;
3744 * The base implementation of `_.orderBy` without param guards.
3747 * @param {Array|Object} collection The collection to iterate over.
3748 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3749 * @param {string[]} orders The sort orders of `iteratees`.
3750 * @returns {Array} Returns the new sorted array.
3752 function baseOrderBy(collection, iteratees, orders) {
3754 iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
3756 var result = baseMap(collection, function(value, key, collection) {
3757 var criteria = arrayMap(iteratees, function(iteratee) {
3758 return iteratee(value);
3760 return { 'criteria': criteria, 'index': ++index, 'value': value };
3763 return baseSortBy(result, function(object, other) {
3764 return compareMultiple(object, other, orders);
3769 * The base implementation of `_.pick` without support for individual
3770 * property identifiers.
3773 * @param {Object} object The source object.
3774 * @param {string[]} paths The property paths to pick.
3775 * @returns {Object} Returns the new object.
3777 function basePick(object, paths) {
3778 return basePickBy(object, paths, function(value, path) {
3779 return hasIn(object, path);
3784 * The base implementation of `_.pickBy` without support for iteratee shorthands.
3787 * @param {Object} object The source object.
3788 * @param {string[]} paths The property paths to pick.
3789 * @param {Function} predicate The function invoked per property.
3790 * @returns {Object} Returns the new object.
3792 function basePickBy(object, paths, predicate) {
3794 length = paths.length,
3797 while (++index < length) {
3798 var path = paths[index],
3799 value = baseGet(object, path);
3801 if (predicate(value, path)) {
3802 baseSet(result, castPath(path, object), value);
3809 * A specialized version of `baseProperty` which supports deep paths.
3812 * @param {Array|string} path The path of the property to get.
3813 * @returns {Function} Returns the new accessor function.
3815 function basePropertyDeep(path) {
3816 return function(object) {
3817 return baseGet(object, path);
3822 * The base implementation of `_.pullAllBy` without support for iteratee
3826 * @param {Array} array The array to modify.
3827 * @param {Array} values The values to remove.
3828 * @param {Function} [iteratee] The iteratee invoked per element.
3829 * @param {Function} [comparator] The comparator invoked per element.
3830 * @returns {Array} Returns `array`.
3832 function basePullAll(array, values, iteratee, comparator) {
3833 var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3835 length = values.length,
3838 if (array === values) {
3839 values = copyArray(values);
3842 seen = arrayMap(array, baseUnary(iteratee));
3844 while (++index < length) {
3846 value = values[index],
3847 computed = iteratee ? iteratee(value) : value;
3849 while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3850 if (seen !== array) {
3851 splice.call(seen, fromIndex, 1);
3853 splice.call(array, fromIndex, 1);
3860 * The base implementation of `_.pullAt` without support for individual
3861 * indexes or capturing the removed elements.
3864 * @param {Array} array The array to modify.
3865 * @param {number[]} indexes The indexes of elements to remove.
3866 * @returns {Array} Returns `array`.
3868 function basePullAt(array, indexes) {
3869 var length = array ? indexes.length : 0,
3870 lastIndex = length - 1;
3873 var index = indexes[length];
3874 if (length == lastIndex || index !== previous) {
3875 var previous = index;
3876 if (isIndex(index)) {
3877 splice.call(array, index, 1);
3879 baseUnset(array, index);
3887 * The base implementation of `_.random` without support for returning
3888 * floating-point numbers.
3891 * @param {number} lower The lower bound.
3892 * @param {number} upper The upper bound.
3893 * @returns {number} Returns the random number.
3895 function baseRandom(lower, upper) {
3896 return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3900 * The base implementation of `_.range` and `_.rangeRight` which doesn't
3904 * @param {number} start The start of the range.
3905 * @param {number} end The end of the range.
3906 * @param {number} step The value to increment or decrement by.
3907 * @param {boolean} [fromRight] Specify iterating from right to left.
3908 * @returns {Array} Returns the range of numbers.
3910 function baseRange(start, end, step, fromRight) {
3912 length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3913 result = Array(length);
3916 result[fromRight ? length : ++index] = start;
3923 * The base implementation of `_.repeat` which doesn't coerce arguments.
3926 * @param {string} string The string to repeat.
3927 * @param {number} n The number of times to repeat the string.
3928 * @returns {string} Returns the repeated string.
3930 function baseRepeat(string, n) {
3932 if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3935 // Leverage the exponentiation by squaring algorithm for a faster repeat.
3936 // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3941 n = nativeFloor(n / 2);
3951 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
3954 * @param {Function} func The function to apply a rest parameter to.
3955 * @param {number} [start=func.length-1] The start position of the rest parameter.
3956 * @returns {Function} Returns the new function.
3958 function baseRest(func, start) {
3959 return setToString(overRest(func, start, identity), func + '');
3963 * The base implementation of `_.sample`.
3966 * @param {Array|Object} collection The collection to sample.
3967 * @returns {*} Returns the random element.
3969 function baseSample(collection) {
3970 return arraySample(values(collection));
3974 * The base implementation of `_.sampleSize` without param guards.
3977 * @param {Array|Object} collection The collection to sample.
3978 * @param {number} n The number of elements to sample.
3979 * @returns {Array} Returns the random elements.
3981 function baseSampleSize(collection, n) {
3982 var array = values(collection);
3983 return shuffleSelf(array, baseClamp(n, 0, array.length));
3987 * The base implementation of `_.set`.
3990 * @param {Object} object The object to modify.
3991 * @param {Array|string} path The path of the property to set.
3992 * @param {*} value The value to set.
3993 * @param {Function} [customizer] The function to customize path creation.
3994 * @returns {Object} Returns `object`.
3996 function baseSet(object, path, value, customizer) {
3997 if (!isObject(object)) {
4000 path = castPath(path, object);
4003 length = path.length,
4004 lastIndex = length - 1,
4007 while (nested != null && ++index < length) {
4008 var key = toKey(path[index]),
4011 if (index != lastIndex) {
4012 var objValue = nested[key];
4013 newValue = customizer ? customizer(objValue, key, nested) : undefined;
4014 if (newValue === undefined) {
4015 newValue = isObject(objValue)
4017 : (isIndex(path[index + 1]) ? [] : {});
4020 assignValue(nested, key, newValue);
4021 nested = nested[key];
4027 * The base implementation of `setData` without support for hot loop shorting.
4030 * @param {Function} func The function to associate metadata with.
4031 * @param {*} data The metadata.
4032 * @returns {Function} Returns `func`.
4034 var baseSetData = !metaMap ? identity : function(func, data) {
4035 metaMap.set(func, data);
4040 * The base implementation of `setToString` without support for hot loop shorting.
4043 * @param {Function} func The function to modify.
4044 * @param {Function} string The `toString` result.
4045 * @returns {Function} Returns `func`.
4047 var baseSetToString = !defineProperty ? identity : function(func, string) {
4048 return defineProperty(func, 'toString', {
4049 'configurable': true,
4050 'enumerable': false,
4051 'value': constant(string),
4057 * The base implementation of `_.shuffle`.
4060 * @param {Array|Object} collection The collection to shuffle.
4061 * @returns {Array} Returns the new shuffled array.
4063 function baseShuffle(collection) {
4064 return shuffleSelf(values(collection));
4068 * The base implementation of `_.slice` without an iteratee call guard.
4071 * @param {Array} array The array to slice.
4072 * @param {number} [start=0] The start position.
4073 * @param {number} [end=array.length] The end position.
4074 * @returns {Array} Returns the slice of `array`.
4076 function baseSlice(array, start, end) {
4078 length = array.length;
4081 start = -start > length ? 0 : (length + start);
4083 end = end > length ? length : end;
4087 length = start > end ? 0 : ((end - start) >>> 0);
4090 var result = Array(length);
4091 while (++index < length) {
4092 result[index] = array[index + start];
4098 * The base implementation of `_.some` without support for iteratee shorthands.
4101 * @param {Array|Object} collection The collection to iterate over.
4102 * @param {Function} predicate The function invoked per iteration.
4103 * @returns {boolean} Returns `true` if any element passes the predicate check,
4106 function baseSome(collection, predicate) {
4109 baseEach(collection, function(value, index, collection) {
4110 result = predicate(value, index, collection);
4117 * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
4118 * performs a binary search of `array` to determine the index at which `value`
4119 * should be inserted into `array` in order to maintain its sort order.
4122 * @param {Array} array The sorted array to inspect.
4123 * @param {*} value The value to evaluate.
4124 * @param {boolean} [retHighest] Specify returning the highest qualified index.
4125 * @returns {number} Returns the index at which `value` should be inserted
4128 function baseSortedIndex(array, value, retHighest) {
4130 high = array == null ? low : array.length;
4132 if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
4133 while (low < high) {
4134 var mid = (low + high) >>> 1,
4135 computed = array[mid];
4137 if (computed !== null && !isSymbol(computed) &&
4138 (retHighest ? (computed <= value) : (computed < value))) {
4146 return baseSortedIndexBy(array, value, identity, retHighest);
4150 * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
4151 * which invokes `iteratee` for `value` and each element of `array` to compute
4152 * their sort ranking. The iteratee is invoked with one argument; (value).
4155 * @param {Array} array The sorted array to inspect.
4156 * @param {*} value The value to evaluate.
4157 * @param {Function} iteratee The iteratee invoked per element.
4158 * @param {boolean} [retHighest] Specify returning the highest qualified index.
4159 * @returns {number} Returns the index at which `value` should be inserted
4162 function baseSortedIndexBy(array, value, iteratee, retHighest) {
4163 value = iteratee(value);
4166 high = array == null ? 0 : array.length,
4167 valIsNaN = value !== value,
4168 valIsNull = value === null,
4169 valIsSymbol = isSymbol(value),
4170 valIsUndefined = value === undefined;
4172 while (low < high) {
4173 var mid = nativeFloor((low + high) / 2),
4174 computed = iteratee(array[mid]),
4175 othIsDefined = computed !== undefined,
4176 othIsNull = computed === null,
4177 othIsReflexive = computed === computed,
4178 othIsSymbol = isSymbol(computed);
4181 var setLow = retHighest || othIsReflexive;
4182 } else if (valIsUndefined) {
4183 setLow = othIsReflexive && (retHighest || othIsDefined);
4184 } else if (valIsNull) {
4185 setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
4186 } else if (valIsSymbol) {
4187 setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
4188 } else if (othIsNull || othIsSymbol) {
4191 setLow = retHighest ? (computed <= value) : (computed < value);
4199 return nativeMin(high, MAX_ARRAY_INDEX);
4203 * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
4204 * support for iteratee shorthands.
4207 * @param {Array} array The array to inspect.
4208 * @param {Function} [iteratee] The iteratee invoked per element.
4209 * @returns {Array} Returns the new duplicate free array.
4211 function baseSortedUniq(array, iteratee) {
4213 length = array.length,
4217 while (++index < length) {
4218 var value = array[index],
4219 computed = iteratee ? iteratee(value) : value;
4221 if (!index || !eq(computed, seen)) {
4222 var seen = computed;
4223 result[resIndex++] = value === 0 ? 0 : value;
4230 * The base implementation of `_.toNumber` which doesn't ensure correct
4231 * conversions of binary, hexadecimal, or octal string values.
4234 * @param {*} value The value to process.
4235 * @returns {number} Returns the number.
4237 function baseToNumber(value) {
4238 if (typeof value == 'number') {
4241 if (isSymbol(value)) {
4248 * The base implementation of `_.toString` which doesn't convert nullish
4249 * values to empty strings.
4252 * @param {*} value The value to process.
4253 * @returns {string} Returns the string.
4255 function baseToString(value) {
4256 // Exit early for strings to avoid a performance hit in some environments.
4257 if (typeof value == 'string') {
4260 if (isArray(value)) {
4261 // Recursively convert values (susceptible to call stack limits).
4262 return arrayMap(value, baseToString) + '';
4264 if (isSymbol(value)) {
4265 return symbolToString ? symbolToString.call(value) : '';
4267 var result = (value + '');
4268 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
4272 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
4275 * @param {Array} array The array to inspect.
4276 * @param {Function} [iteratee] The iteratee invoked per element.
4277 * @param {Function} [comparator] The comparator invoked per element.
4278 * @returns {Array} Returns the new duplicate free array.
4280 function baseUniq(array, iteratee, comparator) {
4282 includes = arrayIncludes,
4283 length = array.length,
4290 includes = arrayIncludesWith;
4292 else if (length >= LARGE_ARRAY_SIZE) {
4293 var set = iteratee ? null : createSet(array);
4295 return setToArray(set);
4298 includes = cacheHas;
4299 seen = new SetCache;
4302 seen = iteratee ? [] : result;
4305 while (++index < length) {
4306 var value = array[index],
4307 computed = iteratee ? iteratee(value) : value;
4309 value = (comparator || value !== 0) ? value : 0;
4310 if (isCommon && computed === computed) {
4311 var seenIndex = seen.length;
4312 while (seenIndex--) {
4313 if (seen[seenIndex] === computed) {
4318 seen.push(computed);
4322 else if (!includes(seen, computed, comparator)) {
4323 if (seen !== result) {
4324 seen.push(computed);
4333 * The base implementation of `_.unset`.
4336 * @param {Object} object The object to modify.
4337 * @param {Array|string} path The property path to unset.
4338 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
4340 function baseUnset(object, path) {
4341 path = castPath(path, object);
4342 object = parent(object, path);
4343 return object == null || delete object[toKey(last(path))];
4347 * The base implementation of `_.update`.
4350 * @param {Object} object The object to modify.
4351 * @param {Array|string} path The path of the property to update.
4352 * @param {Function} updater The function to produce the updated value.
4353 * @param {Function} [customizer] The function to customize path creation.
4354 * @returns {Object} Returns `object`.
4356 function baseUpdate(object, path, updater, customizer) {
4357 return baseSet(object, path, updater(baseGet(object, path)), customizer);
4361 * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
4362 * without support for iteratee shorthands.
4365 * @param {Array} array The array to query.
4366 * @param {Function} predicate The function invoked per iteration.
4367 * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
4368 * @param {boolean} [fromRight] Specify iterating from right to left.
4369 * @returns {Array} Returns the slice of `array`.
4371 function baseWhile(array, predicate, isDrop, fromRight) {
4372 var length = array.length,
4373 index = fromRight ? length : -1;
4375 while ((fromRight ? index-- : ++index < length) &&
4376 predicate(array[index], index, array)) {}
4379 ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
4380 : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
4384 * The base implementation of `wrapperValue` which returns the result of
4385 * performing a sequence of actions on the unwrapped `value`, where each
4386 * successive action is supplied the return value of the previous.
4389 * @param {*} value The unwrapped value.
4390 * @param {Array} actions Actions to perform to resolve the unwrapped value.
4391 * @returns {*} Returns the resolved value.
4393 function baseWrapperValue(value, actions) {
4395 if (result instanceof LazyWrapper) {
4396 result = result.value();
4398 return arrayReduce(actions, function(result, action) {
4399 return action.func.apply(action.thisArg, arrayPush([result], action.args));
4404 * The base implementation of methods like `_.xor`, without support for
4405 * iteratee shorthands, that accepts an array of arrays to inspect.
4408 * @param {Array} arrays The arrays to inspect.
4409 * @param {Function} [iteratee] The iteratee invoked per element.
4410 * @param {Function} [comparator] The comparator invoked per element.
4411 * @returns {Array} Returns the new array of values.
4413 function baseXor(arrays, iteratee, comparator) {
4414 var length = arrays.length;
4416 return length ? baseUniq(arrays[0]) : [];
4419 result = Array(length);
4421 while (++index < length) {
4422 var array = arrays[index],
4425 while (++othIndex < length) {
4426 if (othIndex != index) {
4427 result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
4431 return baseUniq(baseFlatten(result, 1), iteratee, comparator);
4435 * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
4438 * @param {Array} props The property identifiers.
4439 * @param {Array} values The property values.
4440 * @param {Function} assignFunc The function to assign values.
4441 * @returns {Object} Returns the new object.
4443 function baseZipObject(props, values, assignFunc) {
4445 length = props.length,
4446 valsLength = values.length,
4449 while (++index < length) {
4450 var value = index < valsLength ? values[index] : undefined;
4451 assignFunc(result, props[index], value);
4457 * Casts `value` to an empty array if it's not an array like object.
4460 * @param {*} value The value to inspect.
4461 * @returns {Array|Object} Returns the cast array-like object.
4463 function castArrayLikeObject(value) {
4464 return isArrayLikeObject(value) ? value : [];
4468 * Casts `value` to `identity` if it's not a function.
4471 * @param {*} value The value to inspect.
4472 * @returns {Function} Returns cast function.
4474 function castFunction(value) {
4475 return typeof value == 'function' ? value : identity;
4479 * Casts `value` to a path array if it's not one.
4482 * @param {*} value The value to inspect.
4483 * @param {Object} [object] The object to query keys on.
4484 * @returns {Array} Returns the cast property path array.
4486 function castPath(value, object) {
4487 if (isArray(value)) {
4490 return isKey(value, object) ? [value] : stringToPath(toString(value));
4494 * A `baseRest` alias which can be replaced with `identity` by module
4495 * replacement plugins.
4499 * @param {Function} func The function to apply a rest parameter to.
4500 * @returns {Function} Returns the new function.
4502 var castRest = baseRest;
4505 * Casts `array` to a slice if it's needed.
4508 * @param {Array} array The array to inspect.
4509 * @param {number} start The start position.
4510 * @param {number} [end=array.length] The end position.
4511 * @returns {Array} Returns the cast slice.
4513 function castSlice(array, start, end) {
4514 var length = array.length;
4515 end = end === undefined ? length : end;
4516 return (!start && end >= length) ? array : baseSlice(array, start, end);
4520 * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
4523 * @param {number|Object} id The timer id or timeout object of the timer to clear.
4525 var clearTimeout = ctxClearTimeout || function(id) {
4526 return root.clearTimeout(id);
4530 * Creates a clone of `buffer`.
4533 * @param {Buffer} buffer The buffer to clone.
4534 * @param {boolean} [isDeep] Specify a deep clone.
4535 * @returns {Buffer} Returns the cloned buffer.
4537 function cloneBuffer(buffer, isDeep) {
4539 return buffer.slice();
4541 var length = buffer.length,
4542 result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
4544 buffer.copy(result);
4549 * Creates a clone of `arrayBuffer`.
4552 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4553 * @returns {ArrayBuffer} Returns the cloned array buffer.
4555 function cloneArrayBuffer(arrayBuffer) {
4556 var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4557 new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4562 * Creates a clone of `dataView`.
4565 * @param {Object} dataView The data view to clone.
4566 * @param {boolean} [isDeep] Specify a deep clone.
4567 * @returns {Object} Returns the cloned data view.
4569 function cloneDataView(dataView, isDeep) {
4570 var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4571 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4575 * Creates a clone of `map`.
4578 * @param {Object} map The map to clone.
4579 * @param {Function} cloneFunc The function to clone values.
4580 * @param {boolean} [isDeep] Specify a deep clone.
4581 * @returns {Object} Returns the cloned map.
4583 function cloneMap(map, isDeep, cloneFunc) {
4584 var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
4585 return arrayReduce(array, addMapEntry, new map.constructor);
4589 * Creates a clone of `regexp`.
4592 * @param {Object} regexp The regexp to clone.
4593 * @returns {Object} Returns the cloned regexp.
4595 function cloneRegExp(regexp) {
4596 var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4597 result.lastIndex = regexp.lastIndex;
4602 * Creates a clone of `set`.
4605 * @param {Object} set The set to clone.
4606 * @param {Function} cloneFunc The function to clone values.
4607 * @param {boolean} [isDeep] Specify a deep clone.
4608 * @returns {Object} Returns the cloned set.
4610 function cloneSet(set, isDeep, cloneFunc) {
4611 var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
4612 return arrayReduce(array, addSetEntry, new set.constructor);
4616 * Creates a clone of the `symbol` object.
4619 * @param {Object} symbol The symbol object to clone.
4620 * @returns {Object} Returns the cloned symbol object.
4622 function cloneSymbol(symbol) {
4623 return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4627 * Creates a clone of `typedArray`.
4630 * @param {Object} typedArray The typed array to clone.
4631 * @param {boolean} [isDeep] Specify a deep clone.
4632 * @returns {Object} Returns the cloned typed array.
4634 function cloneTypedArray(typedArray, isDeep) {
4635 var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4636 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4640 * Compares values to sort them in ascending order.
4643 * @param {*} value The value to compare.
4644 * @param {*} other The other value to compare.
4645 * @returns {number} Returns the sort order indicator for `value`.
4647 function compareAscending(value, other) {
4648 if (value !== other) {
4649 var valIsDefined = value !== undefined,
4650 valIsNull = value === null,
4651 valIsReflexive = value === value,
4652 valIsSymbol = isSymbol(value);
4654 var othIsDefined = other !== undefined,
4655 othIsNull = other === null,
4656 othIsReflexive = other === other,
4657 othIsSymbol = isSymbol(other);
4659 if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4660 (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4661 (valIsNull && othIsDefined && othIsReflexive) ||
4662 (!valIsDefined && othIsReflexive) ||
4666 if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4667 (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4668 (othIsNull && valIsDefined && valIsReflexive) ||
4669 (!othIsDefined && valIsReflexive) ||
4678 * Used by `_.orderBy` to compare multiple properties of a value to another
4679 * and stable sort them.
4681 * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4682 * specify an order of "desc" for descending or "asc" for ascending sort order
4683 * of corresponding values.
4686 * @param {Object} object The object to compare.
4687 * @param {Object} other The other object to compare.
4688 * @param {boolean[]|string[]} orders The order to sort by for each property.
4689 * @returns {number} Returns the sort order indicator for `object`.
4691 function compareMultiple(object, other, orders) {
4693 objCriteria = object.criteria,
4694 othCriteria = other.criteria,
4695 length = objCriteria.length,
4696 ordersLength = orders.length;
4698 while (++index < length) {
4699 var result = compareAscending(objCriteria[index], othCriteria[index]);
4701 if (index >= ordersLength) {
4704 var order = orders[index];
4705 return result * (order == 'desc' ? -1 : 1);
4708 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4709 // that causes it, under certain circumstances, to provide the same value for
4710 // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4711 // for more details.
4713 // This also ensures a stable sort in V8 and other engines.
4714 // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4715 return object.index - other.index;
4719 * Creates an array that is the composition of partially applied arguments,
4720 * placeholders, and provided arguments into a single array of arguments.
4723 * @param {Array} args The provided arguments.
4724 * @param {Array} partials The arguments to prepend to those provided.
4725 * @param {Array} holders The `partials` placeholder indexes.
4726 * @params {boolean} [isCurried] Specify composing for a curried function.
4727 * @returns {Array} Returns the new array of composed arguments.
4729 function composeArgs(args, partials, holders, isCurried) {
4731 argsLength = args.length,
4732 holdersLength = holders.length,
4734 leftLength = partials.length,
4735 rangeLength = nativeMax(argsLength - holdersLength, 0),
4736 result = Array(leftLength + rangeLength),
4737 isUncurried = !isCurried;
4739 while (++leftIndex < leftLength) {
4740 result[leftIndex] = partials[leftIndex];
4742 while (++argsIndex < holdersLength) {
4743 if (isUncurried || argsIndex < argsLength) {
4744 result[holders[argsIndex]] = args[argsIndex];
4747 while (rangeLength--) {
4748 result[leftIndex++] = args[argsIndex++];
4754 * This function is like `composeArgs` except that the arguments composition
4755 * is tailored for `_.partialRight`.
4758 * @param {Array} args The provided arguments.
4759 * @param {Array} partials The arguments to append to those provided.
4760 * @param {Array} holders The `partials` placeholder indexes.
4761 * @params {boolean} [isCurried] Specify composing for a curried function.
4762 * @returns {Array} Returns the new array of composed arguments.
4764 function composeArgsRight(args, partials, holders, isCurried) {
4766 argsLength = args.length,
4768 holdersLength = holders.length,
4770 rightLength = partials.length,
4771 rangeLength = nativeMax(argsLength - holdersLength, 0),
4772 result = Array(rangeLength + rightLength),
4773 isUncurried = !isCurried;
4775 while (++argsIndex < rangeLength) {
4776 result[argsIndex] = args[argsIndex];
4778 var offset = argsIndex;
4779 while (++rightIndex < rightLength) {
4780 result[offset + rightIndex] = partials[rightIndex];
4782 while (++holdersIndex < holdersLength) {
4783 if (isUncurried || argsIndex < argsLength) {
4784 result[offset + holders[holdersIndex]] = args[argsIndex++];
4791 * Copies the values of `source` to `array`.
4794 * @param {Array} source The array to copy values from.
4795 * @param {Array} [array=[]] The array to copy values to.
4796 * @returns {Array} Returns `array`.
4798 function copyArray(source, array) {
4800 length = source.length;
4802 array || (array = Array(length));
4803 while (++index < length) {
4804 array[index] = source[index];
4810 * Copies properties of `source` to `object`.
4813 * @param {Object} source The object to copy properties from.
4814 * @param {Array} props The property identifiers to copy.
4815 * @param {Object} [object={}] The object to copy properties to.
4816 * @param {Function} [customizer] The function to customize copied values.
4817 * @returns {Object} Returns `object`.
4819 function copyObject(source, props, object, customizer) {
4820 var isNew = !object;
4821 object || (object = {});
4824 length = props.length;
4826 while (++index < length) {
4827 var key = props[index];
4829 var newValue = customizer
4830 ? customizer(object[key], source[key], key, object, source)
4833 if (newValue === undefined) {
4834 newValue = source[key];
4837 baseAssignValue(object, key, newValue);
4839 assignValue(object, key, newValue);
4846 * Copies own symbols of `source` to `object`.
4849 * @param {Object} source The object to copy symbols from.
4850 * @param {Object} [object={}] The object to copy symbols to.
4851 * @returns {Object} Returns `object`.
4853 function copySymbols(source, object) {
4854 return copyObject(source, getSymbols(source), object);
4858 * Copies own and inherited symbols of `source` to `object`.
4861 * @param {Object} source The object to copy symbols from.
4862 * @param {Object} [object={}] The object to copy symbols to.
4863 * @returns {Object} Returns `object`.
4865 function copySymbolsIn(source, object) {
4866 return copyObject(source, getSymbolsIn(source), object);
4870 * Creates a function like `_.groupBy`.
4873 * @param {Function} setter The function to set accumulator values.
4874 * @param {Function} [initializer] The accumulator object initializer.
4875 * @returns {Function} Returns the new aggregator function.
4877 function createAggregator(setter, initializer) {
4878 return function(collection, iteratee) {
4879 var func = isArray(collection) ? arrayAggregator : baseAggregator,
4880 accumulator = initializer ? initializer() : {};
4882 return func(collection, setter, getIteratee(iteratee, 2), accumulator);
4887 * Creates a function like `_.assign`.
4890 * @param {Function} assigner The function to assign values.
4891 * @returns {Function} Returns the new assigner function.
4893 function createAssigner(assigner) {
4894 return baseRest(function(object, sources) {
4896 length = sources.length,
4897 customizer = length > 1 ? sources[length - 1] : undefined,
4898 guard = length > 2 ? sources[2] : undefined;
4900 customizer = (assigner.length > 3 && typeof customizer == 'function')
4901 ? (length--, customizer)
4904 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4905 customizer = length < 3 ? undefined : customizer;
4908 object = Object(object);
4909 while (++index < length) {
4910 var source = sources[index];
4912 assigner(object, source, index, customizer);
4920 * Creates a `baseEach` or `baseEachRight` function.
4923 * @param {Function} eachFunc The function to iterate over a collection.
4924 * @param {boolean} [fromRight] Specify iterating from right to left.
4925 * @returns {Function} Returns the new base function.
4927 function createBaseEach(eachFunc, fromRight) {
4928 return function(collection, iteratee) {
4929 if (collection == null) {
4932 if (!isArrayLike(collection)) {
4933 return eachFunc(collection, iteratee);
4935 var length = collection.length,
4936 index = fromRight ? length : -1,
4937 iterable = Object(collection);
4939 while ((fromRight ? index-- : ++index < length)) {
4940 if (iteratee(iterable[index], index, iterable) === false) {
4949 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4952 * @param {boolean} [fromRight] Specify iterating from right to left.
4953 * @returns {Function} Returns the new base function.
4955 function createBaseFor(fromRight) {
4956 return function(object, iteratee, keysFunc) {
4958 iterable = Object(object),
4959 props = keysFunc(object),
4960 length = props.length;
4963 var key = props[fromRight ? length : ++index];
4964 if (iteratee(iterable[key], key, iterable) === false) {
4973 * Creates a function that wraps `func` to invoke it with the optional `this`
4974 * binding of `thisArg`.
4977 * @param {Function} func The function to wrap.
4978 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
4979 * @param {*} [thisArg] The `this` binding of `func`.
4980 * @returns {Function} Returns the new wrapped function.
4982 function createBind(func, bitmask, thisArg) {
4983 var isBind = bitmask & WRAP_BIND_FLAG,
4984 Ctor = createCtor(func);
4986 function wrapper() {
4987 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4988 return fn.apply(isBind ? thisArg : this, arguments);
4994 * Creates a function like `_.lowerFirst`.
4997 * @param {string} methodName The name of the `String` case method to use.
4998 * @returns {Function} Returns the new case function.
5000 function createCaseFirst(methodName) {
5001 return function(string) {
5002 string = toString(string);
5004 var strSymbols = hasUnicode(string)
5005 ? stringToArray(string)
5008 var chr = strSymbols
5012 var trailing = strSymbols
5013 ? castSlice(strSymbols, 1).join('')
5016 return chr[methodName]() + trailing;
5021 * Creates a function like `_.camelCase`.
5024 * @param {Function} callback The function to combine each word.
5025 * @returns {Function} Returns the new compounder function.
5027 function createCompounder(callback) {
5028 return function(string) {
5029 return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
5034 * Creates a function that produces an instance of `Ctor` regardless of
5035 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5038 * @param {Function} Ctor The constructor to wrap.
5039 * @returns {Function} Returns the new wrapped function.
5041 function createCtor(Ctor) {
5043 // Use a `switch` statement to work with class constructors. See
5044 // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5045 // for more details.
5046 var args = arguments;
5047 switch (args.length) {
5048 case 0: return new Ctor;
5049 case 1: return new Ctor(args[0]);
5050 case 2: return new Ctor(args[0], args[1]);
5051 case 3: return new Ctor(args[0], args[1], args[2]);
5052 case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5053 case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5054 case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5055 case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5057 var thisBinding = baseCreate(Ctor.prototype),
5058 result = Ctor.apply(thisBinding, args);
5060 // Mimic the constructor's `return` behavior.
5061 // See https://es5.github.io/#x13.2.2 for more details.
5062 return isObject(result) ? result : thisBinding;
5067 * Creates a function that wraps `func` to enable currying.
5070 * @param {Function} func The function to wrap.
5071 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5072 * @param {number} arity The arity of `func`.
5073 * @returns {Function} Returns the new wrapped function.
5075 function createCurry(func, bitmask, arity) {
5076 var Ctor = createCtor(func);
5078 function wrapper() {
5079 var length = arguments.length,
5080 args = Array(length),
5082 placeholder = getHolder(wrapper);
5085 args[index] = arguments[index];
5087 var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5089 : replaceHolders(args, placeholder);
5091 length -= holders.length;
5092 if (length < arity) {
5093 return createRecurry(
5094 func, bitmask, createHybrid, wrapper.placeholder, undefined,
5095 args, holders, undefined, undefined, arity - length);
5097 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5098 return apply(fn, this, args);
5104 * Creates a `_.find` or `_.findLast` function.
5107 * @param {Function} findIndexFunc The function to find the collection index.
5108 * @returns {Function} Returns the new find function.
5110 function createFind(findIndexFunc) {
5111 return function(collection, predicate, fromIndex) {
5112 var iterable = Object(collection);
5113 if (!isArrayLike(collection)) {
5114 var iteratee = getIteratee(predicate, 3);
5115 collection = keys(collection);
5116 predicate = function(key) { return iteratee(iterable[key], key, iterable); };
5118 var index = findIndexFunc(collection, predicate, fromIndex);
5119 return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
5124 * Creates a `_.flow` or `_.flowRight` function.
5127 * @param {boolean} [fromRight] Specify iterating from right to left.
5128 * @returns {Function} Returns the new flow function.
5130 function createFlow(fromRight) {
5131 return flatRest(function(funcs) {
5132 var length = funcs.length,
5134 prereq = LodashWrapper.prototype.thru;
5140 var func = funcs[index];
5141 if (typeof func != 'function') {
5142 throw new TypeError(FUNC_ERROR_TEXT);
5144 if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
5145 var wrapper = new LodashWrapper([], true);
5148 index = wrapper ? index : length;
5149 while (++index < length) {
5150 func = funcs[index];
5152 var funcName = getFuncName(func),
5153 data = funcName == 'wrapper' ? getData(func) : undefined;
5155 if (data && isLaziable(data[0]) &&
5156 data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
5157 !data[4].length && data[9] == 1
5159 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
5161 wrapper = (func.length == 1 && isLaziable(func))
5162 ? wrapper[funcName]()
5163 : wrapper.thru(func);
5167 var args = arguments,
5170 if (wrapper && args.length == 1 && isArray(value)) {
5171 return wrapper.plant(value).value();
5174 result = length ? funcs[index].apply(this, args) : value;
5176 while (++index < length) {
5177 result = funcs[index].call(this, result);
5185 * Creates a function that wraps `func` to invoke it with optional `this`
5186 * binding of `thisArg`, partial application, and currying.
5189 * @param {Function|string} func The function or method name to wrap.
5190 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5191 * @param {*} [thisArg] The `this` binding of `func`.
5192 * @param {Array} [partials] The arguments to prepend to those provided to
5194 * @param {Array} [holders] The `partials` placeholder indexes.
5195 * @param {Array} [partialsRight] The arguments to append to those provided
5196 * to the new function.
5197 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5198 * @param {Array} [argPos] The argument positions of the new function.
5199 * @param {number} [ary] The arity cap of `func`.
5200 * @param {number} [arity] The arity of `func`.
5201 * @returns {Function} Returns the new wrapped function.
5203 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5204 var isAry = bitmask & WRAP_ARY_FLAG,
5205 isBind = bitmask & WRAP_BIND_FLAG,
5206 isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
5207 isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
5208 isFlip = bitmask & WRAP_FLIP_FLAG,
5209 Ctor = isBindKey ? undefined : createCtor(func);
5211 function wrapper() {
5212 var length = arguments.length,
5213 args = Array(length),
5217 args[index] = arguments[index];
5220 var placeholder = getHolder(wrapper),
5221 holdersCount = countHolders(args, placeholder);
5224 args = composeArgs(args, partials, holders, isCurried);
5226 if (partialsRight) {
5227 args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
5229 length -= holdersCount;
5230 if (isCurried && length < arity) {
5231 var newHolders = replaceHolders(args, placeholder);
5232 return createRecurry(
5233 func, bitmask, createHybrid, wrapper.placeholder, thisArg,
5234 args, newHolders, argPos, ary, arity - length
5237 var thisBinding = isBind ? thisArg : this,
5238 fn = isBindKey ? thisBinding[func] : func;
5240 length = args.length;
5242 args = reorder(args, argPos);
5243 } else if (isFlip && length > 1) {
5246 if (isAry && ary < length) {
5249 if (this && this !== root && this instanceof wrapper) {
5250 fn = Ctor || createCtor(fn);
5252 return fn.apply(thisBinding, args);
5258 * Creates a function like `_.invertBy`.
5261 * @param {Function} setter The function to set accumulator values.
5262 * @param {Function} toIteratee The function to resolve iteratees.
5263 * @returns {Function} Returns the new inverter function.
5265 function createInverter(setter, toIteratee) {
5266 return function(object, iteratee) {
5267 return baseInverter(object, setter, toIteratee(iteratee), {});
5272 * Creates a function that performs a mathematical operation on two values.
5275 * @param {Function} operator The function to perform the operation.
5276 * @param {number} [defaultValue] The value used for `undefined` arguments.
5277 * @returns {Function} Returns the new mathematical operation function.
5279 function createMathOperation(operator, defaultValue) {
5280 return function(value, other) {
5282 if (value === undefined && other === undefined) {
5283 return defaultValue;
5285 if (value !== undefined) {
5288 if (other !== undefined) {
5289 if (result === undefined) {
5292 if (typeof value == 'string' || typeof other == 'string') {
5293 value = baseToString(value);
5294 other = baseToString(other);
5296 value = baseToNumber(value);
5297 other = baseToNumber(other);
5299 result = operator(value, other);
5306 * Creates a function like `_.over`.
5309 * @param {Function} arrayFunc The function to iterate over iteratees.
5310 * @returns {Function} Returns the new over function.
5312 function createOver(arrayFunc) {
5313 return flatRest(function(iteratees) {
5314 iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
5315 return baseRest(function(args) {
5317 return arrayFunc(iteratees, function(iteratee) {
5318 return apply(iteratee, thisArg, args);
5325 * Creates the padding for `string` based on `length`. The `chars` string
5326 * is truncated if the number of characters exceeds `length`.
5329 * @param {number} length The padding length.
5330 * @param {string} [chars=' '] The string used as padding.
5331 * @returns {string} Returns the padding for `string`.
5333 function createPadding(length, chars) {
5334 chars = chars === undefined ? ' ' : baseToString(chars);
5336 var charsLength = chars.length;
5337 if (charsLength < 2) {
5338 return charsLength ? baseRepeat(chars, length) : chars;
5340 var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
5341 return hasUnicode(chars)
5342 ? castSlice(stringToArray(result), 0, length).join('')
5343 : result.slice(0, length);
5347 * Creates a function that wraps `func` to invoke it with the `this` binding
5348 * of `thisArg` and `partials` prepended to the arguments it receives.
5351 * @param {Function} func The function to wrap.
5352 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5353 * @param {*} thisArg The `this` binding of `func`.
5354 * @param {Array} partials The arguments to prepend to those provided to
5356 * @returns {Function} Returns the new wrapped function.
5358 function createPartial(func, bitmask, thisArg, partials) {
5359 var isBind = bitmask & WRAP_BIND_FLAG,
5360 Ctor = createCtor(func);
5362 function wrapper() {
5364 argsLength = arguments.length,
5366 leftLength = partials.length,
5367 args = Array(leftLength + argsLength),
5368 fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5370 while (++leftIndex < leftLength) {
5371 args[leftIndex] = partials[leftIndex];
5373 while (argsLength--) {
5374 args[leftIndex++] = arguments[++argsIndex];
5376 return apply(fn, isBind ? thisArg : this, args);
5382 * Creates a `_.range` or `_.rangeRight` function.
5385 * @param {boolean} [fromRight] Specify iterating from right to left.
5386 * @returns {Function} Returns the new range function.
5388 function createRange(fromRight) {
5389 return function(start, end, step) {
5390 if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
5391 end = step = undefined;
5393 // Ensure the sign of `-0` is preserved.
5394 start = toFinite(start);
5395 if (end === undefined) {
5399 end = toFinite(end);
5401 step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
5402 return baseRange(start, end, step, fromRight);
5407 * Creates a function that performs a relational operation on two values.
5410 * @param {Function} operator The function to perform the operation.
5411 * @returns {Function} Returns the new relational operation function.
5413 function createRelationalOperation(operator) {
5414 return function(value, other) {
5415 if (!(typeof value == 'string' && typeof other == 'string')) {
5416 value = toNumber(value);
5417 other = toNumber(other);
5419 return operator(value, other);
5424 * Creates a function that wraps `func` to continue currying.
5427 * @param {Function} func The function to wrap.
5428 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5429 * @param {Function} wrapFunc The function to create the `func` wrapper.
5430 * @param {*} placeholder The placeholder value.
5431 * @param {*} [thisArg] The `this` binding of `func`.
5432 * @param {Array} [partials] The arguments to prepend to those provided to
5434 * @param {Array} [holders] The `partials` placeholder indexes.
5435 * @param {Array} [argPos] The argument positions of the new function.
5436 * @param {number} [ary] The arity cap of `func`.
5437 * @param {number} [arity] The arity of `func`.
5438 * @returns {Function} Returns the new wrapped function.
5440 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5441 var isCurry = bitmask & WRAP_CURRY_FLAG,
5442 newHolders = isCurry ? holders : undefined,
5443 newHoldersRight = isCurry ? undefined : holders,
5444 newPartials = isCurry ? partials : undefined,
5445 newPartialsRight = isCurry ? undefined : partials;
5447 bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
5448 bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
5450 if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
5451 bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
5454 func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
5455 newHoldersRight, argPos, ary, arity
5458 var result = wrapFunc.apply(undefined, newData);
5459 if (isLaziable(func)) {
5460 setData(result, newData);
5462 result.placeholder = placeholder;
5463 return setWrapToString(result, func, bitmask);
5467 * Creates a function like `_.round`.
5470 * @param {string} methodName The name of the `Math` method to use when rounding.
5471 * @returns {Function} Returns the new round function.
5473 function createRound(methodName) {
5474 var func = Math[methodName];
5475 return function(number, precision) {
5476 number = toNumber(number);
5477 precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
5479 // Shift with exponential notation to avoid floating-point issues.
5480 // See [MDN](https://mdn.io/round#Examples) for more details.
5481 var pair = (toString(number) + 'e').split('e'),
5482 value = func(pair[0] + 'e' + (+pair[1] + precision));
5484 pair = (toString(value) + 'e').split('e');
5485 return +(pair[0] + 'e' + (+pair[1] - precision));
5487 return func(number);
5492 * Creates a set object of `values`.
5495 * @param {Array} values The values to add to the set.
5496 * @returns {Object} Returns the new set.
5498 var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
5499 return new Set(values);
5503 * Creates a `_.toPairs` or `_.toPairsIn` function.
5506 * @param {Function} keysFunc The function to get the keys of a given object.
5507 * @returns {Function} Returns the new pairs function.
5509 function createToPairs(keysFunc) {
5510 return function(object) {
5511 var tag = getTag(object);
5512 if (tag == mapTag) {
5513 return mapToArray(object);
5515 if (tag == setTag) {
5516 return setToPairs(object);
5518 return baseToPairs(object, keysFunc(object));
5523 * Creates a function that either curries or invokes `func` with optional
5524 * `this` binding and partially applied arguments.
5527 * @param {Function|string} func The function or method name to wrap.
5528 * @param {number} bitmask The bitmask flags.
5531 * 4 - `_.curry` or `_.curryRight` of a bound function
5533 * 16 - `_.curryRight`
5535 * 64 - `_.partialRight`
5539 * @param {*} [thisArg] The `this` binding of `func`.
5540 * @param {Array} [partials] The arguments to be partially applied.
5541 * @param {Array} [holders] The `partials` placeholder indexes.
5542 * @param {Array} [argPos] The argument positions of the new function.
5543 * @param {number} [ary] The arity cap of `func`.
5544 * @param {number} [arity] The arity of `func`.
5545 * @returns {Function} Returns the new wrapped function.
5547 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5548 var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
5549 if (!isBindKey && typeof func != 'function') {
5550 throw new TypeError(FUNC_ERROR_TEXT);
5552 var length = partials ? partials.length : 0;
5554 bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
5555 partials = holders = undefined;
5557 ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5558 arity = arity === undefined ? arity : toInteger(arity);
5559 length -= holders ? holders.length : 0;
5561 if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
5562 var partialsRight = partials,
5563 holdersRight = holders;
5565 partials = holders = undefined;
5567 var data = isBindKey ? undefined : getData(func);
5570 func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5575 mergeData(newData, data);
5578 bitmask = newData[1];
5579 thisArg = newData[2];
5580 partials = newData[3];
5581 holders = newData[4];
5582 arity = newData[9] = newData[9] === undefined
5583 ? (isBindKey ? 0 : func.length)
5584 : nativeMax(newData[9] - length, 0);
5586 if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
5587 bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
5589 if (!bitmask || bitmask == WRAP_BIND_FLAG) {
5590 var result = createBind(func, bitmask, thisArg);
5591 } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
5592 result = createCurry(func, bitmask, arity);
5593 } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
5594 result = createPartial(func, bitmask, thisArg, partials);
5596 result = createHybrid.apply(undefined, newData);
5598 var setter = data ? baseSetData : setData;
5599 return setWrapToString(setter(result, newData), func, bitmask);
5603 * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
5604 * of source objects to the destination object for all destination properties
5605 * that resolve to `undefined`.
5608 * @param {*} objValue The destination value.
5609 * @param {*} srcValue The source value.
5610 * @param {string} key The key of the property to assign.
5611 * @param {Object} object The parent object of `objValue`.
5612 * @returns {*} Returns the value to assign.
5614 function customDefaultsAssignIn(objValue, srcValue, key, object) {
5615 if (objValue === undefined ||
5616 (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
5623 * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
5624 * objects into destination objects that are passed thru.
5627 * @param {*} objValue The destination value.
5628 * @param {*} srcValue The source value.
5629 * @param {string} key The key of the property to merge.
5630 * @param {Object} object The parent object of `objValue`.
5631 * @param {Object} source The parent object of `srcValue`.
5632 * @param {Object} [stack] Tracks traversed source values and their merged
5634 * @returns {*} Returns the value to assign.
5636 function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
5637 if (isObject(objValue) && isObject(srcValue)) {
5638 // Recursively merge objects and arrays (susceptible to call stack limits).
5639 stack.set(srcValue, objValue);
5640 baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
5641 stack['delete'](srcValue);
5647 * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
5651 * @param {*} value The value to inspect.
5652 * @param {string} key The key of the property to inspect.
5653 * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
5655 function customOmitClone(value) {
5656 return isPlainObject(value) ? undefined : value;
5660 * A specialized version of `baseIsEqualDeep` for arrays with support for
5661 * partial deep comparisons.
5664 * @param {Array} array The array to compare.
5665 * @param {Array} other The other array to compare.
5666 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5667 * @param {Function} customizer The function to customize comparisons.
5668 * @param {Function} equalFunc The function to determine equivalents of values.
5669 * @param {Object} stack Tracks traversed `array` and `other` objects.
5670 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5672 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
5673 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5674 arrLength = array.length,
5675 othLength = other.length;
5677 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5680 // Assume cyclic values are equal.
5681 var stacked = stack.get(array);
5682 if (stacked && stack.get(other)) {
5683 return stacked == other;
5687 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
5689 stack.set(array, other);
5690 stack.set(other, array);
5692 // Ignore non-index properties.
5693 while (++index < arrLength) {
5694 var arrValue = array[index],
5695 othValue = other[index];
5698 var compared = isPartial
5699 ? customizer(othValue, arrValue, index, other, array, stack)
5700 : customizer(arrValue, othValue, index, array, other, stack);
5702 if (compared !== undefined) {
5709 // Recursively compare arrays (susceptible to call stack limits).
5711 if (!arraySome(other, function(othValue, othIndex) {
5712 if (!cacheHas(seen, othIndex) &&
5713 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
5714 return seen.push(othIndex);
5721 arrValue === othValue ||
5722 equalFunc(arrValue, othValue, bitmask, customizer, stack)
5728 stack['delete'](array);
5729 stack['delete'](other);
5734 * A specialized version of `baseIsEqualDeep` for comparing objects of
5735 * the same `toStringTag`.
5737 * **Note:** This function only supports comparing values with tags of
5738 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5741 * @param {Object} object The object to compare.
5742 * @param {Object} other The other object to compare.
5743 * @param {string} tag The `toStringTag` of the objects to compare.
5744 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5745 * @param {Function} customizer The function to customize comparisons.
5746 * @param {Function} equalFunc The function to determine equivalents of values.
5747 * @param {Object} stack Tracks traversed `object` and `other` objects.
5748 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5750 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
5753 if ((object.byteLength != other.byteLength) ||
5754 (object.byteOffset != other.byteOffset)) {
5757 object = object.buffer;
5758 other = other.buffer;
5760 case arrayBufferTag:
5761 if ((object.byteLength != other.byteLength) ||
5762 !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5770 // Coerce booleans to `1` or `0` and dates to milliseconds.
5771 // Invalid dates are coerced to `NaN`.
5772 return eq(+object, +other);
5775 return object.name == other.name && object.message == other.message;
5779 // Coerce regexes to strings and treat strings, primitives and objects,
5780 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
5781 // for more details.
5782 return object == (other + '');
5785 var convert = mapToArray;
5788 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
5789 convert || (convert = setToArray);
5791 if (object.size != other.size && !isPartial) {
5794 // Assume cyclic values are equal.
5795 var stacked = stack.get(object);
5797 return stacked == other;
5799 bitmask |= COMPARE_UNORDERED_FLAG;
5801 // Recursively compare objects (susceptible to call stack limits).
5802 stack.set(object, other);
5803 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
5804 stack['delete'](object);
5808 if (symbolValueOf) {
5809 return symbolValueOf.call(object) == symbolValueOf.call(other);
5816 * A specialized version of `baseIsEqualDeep` for objects with support for
5817 * partial deep comparisons.
5820 * @param {Object} object The object to compare.
5821 * @param {Object} other The other object to compare.
5822 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5823 * @param {Function} customizer The function to customize comparisons.
5824 * @param {Function} equalFunc The function to determine equivalents of values.
5825 * @param {Object} stack Tracks traversed `object` and `other` objects.
5826 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5828 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
5829 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5830 objProps = getAllKeys(object),
5831 objLength = objProps.length,
5832 othProps = getAllKeys(other),
5833 othLength = othProps.length;
5835 if (objLength != othLength && !isPartial) {
5838 var index = objLength;
5840 var key = objProps[index];
5841 if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
5845 // Assume cyclic values are equal.
5846 var stacked = stack.get(object);
5847 if (stacked && stack.get(other)) {
5848 return stacked == other;
5851 stack.set(object, other);
5852 stack.set(other, object);
5854 var skipCtor = isPartial;
5855 while (++index < objLength) {
5856 key = objProps[index];
5857 var objValue = object[key],
5858 othValue = other[key];
5861 var compared = isPartial
5862 ? customizer(othValue, objValue, key, other, object, stack)
5863 : customizer(objValue, othValue, key, object, other, stack);
5865 // Recursively compare objects (susceptible to call stack limits).
5866 if (!(compared === undefined
5867 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
5873 skipCtor || (skipCtor = key == 'constructor');
5875 if (result && !skipCtor) {
5876 var objCtor = object.constructor,
5877 othCtor = other.constructor;
5879 // Non `Object` object instances with different constructors are not equal.
5880 if (objCtor != othCtor &&
5881 ('constructor' in object && 'constructor' in other) &&
5882 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5883 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5887 stack['delete'](object);
5888 stack['delete'](other);
5893 * A specialized version of `baseRest` which flattens the rest array.
5896 * @param {Function} func The function to apply a rest parameter to.
5897 * @returns {Function} Returns the new function.
5899 function flatRest(func) {
5900 return setToString(overRest(func, undefined, flatten), func + '');
5904 * Creates an array of own enumerable property names and symbols of `object`.
5907 * @param {Object} object The object to query.
5908 * @returns {Array} Returns the array of property names and symbols.
5910 function getAllKeys(object) {
5911 return baseGetAllKeys(object, keys, getSymbols);
5915 * Creates an array of own and inherited enumerable property names and
5916 * symbols of `object`.
5919 * @param {Object} object The object to query.
5920 * @returns {Array} Returns the array of property names and symbols.
5922 function getAllKeysIn(object) {
5923 return baseGetAllKeys(object, keysIn, getSymbolsIn);
5927 * Gets metadata for `func`.
5930 * @param {Function} func The function to query.
5931 * @returns {*} Returns the metadata for `func`.
5933 var getData = !metaMap ? noop : function(func) {
5934 return metaMap.get(func);
5938 * Gets the name of `func`.
5941 * @param {Function} func The function to query.
5942 * @returns {string} Returns the function name.
5944 function getFuncName(func) {
5945 var result = (func.name + ''),
5946 array = realNames[result],
5947 length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5950 var data = array[length],
5951 otherFunc = data.func;
5952 if (otherFunc == null || otherFunc == func) {
5960 * Gets the argument placeholder value for `func`.
5963 * @param {Function} func The function to inspect.
5964 * @returns {*} Returns the placeholder value.
5966 function getHolder(func) {
5967 var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5968 return object.placeholder;
5972 * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5973 * this function returns the custom method, otherwise it returns `baseIteratee`.
5974 * If arguments are provided, the chosen function is invoked with them and
5975 * its result is returned.
5978 * @param {*} [value] The value to convert to an iteratee.
5979 * @param {number} [arity] The arity of the created iteratee.
5980 * @returns {Function} Returns the chosen function or its result.
5982 function getIteratee() {
5983 var result = lodash.iteratee || iteratee;
5984 result = result === iteratee ? baseIteratee : result;
5985 return arguments.length ? result(arguments[0], arguments[1]) : result;
5989 * Gets the data for `map`.
5992 * @param {Object} map The map to query.
5993 * @param {string} key The reference key.
5994 * @returns {*} Returns the map data.
5996 function getMapData(map, key) {
5997 var data = map.__data__;
5998 return isKeyable(key)
5999 ? data[typeof key == 'string' ? 'string' : 'hash']
6004 * Gets the property names, values, and compare flags of `object`.
6007 * @param {Object} object The object to query.
6008 * @returns {Array} Returns the match data of `object`.
6010 function getMatchData(object) {
6011 var result = keys(object),
6012 length = result.length;
6015 var key = result[length],
6016 value = object[key];
6018 result[length] = [key, value, isStrictComparable(value)];
6024 * Gets the native function at `key` of `object`.
6027 * @param {Object} object The object to query.
6028 * @param {string} key The key of the method to get.
6029 * @returns {*} Returns the function if it's native, else `undefined`.
6031 function getNative(object, key) {
6032 var value = getValue(object, key);
6033 return baseIsNative(value) ? value : undefined;
6037 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6040 * @param {*} value The value to query.
6041 * @returns {string} Returns the raw `toStringTag`.
6043 function getRawTag(value) {
6044 var isOwn = hasOwnProperty.call(value, symToStringTag),
6045 tag = value[symToStringTag];
6048 value[symToStringTag] = undefined;
6049 var unmasked = true;
6052 var result = nativeObjectToString.call(value);
6055 value[symToStringTag] = tag;
6057 delete value[symToStringTag];
6064 * Creates an array of the own enumerable symbols of `object`.
6067 * @param {Object} object The object to query.
6068 * @returns {Array} Returns the array of symbols.
6070 var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
6071 if (object == null) {
6074 object = Object(object);
6075 return arrayFilter(nativeGetSymbols(object), function(symbol) {
6076 return propertyIsEnumerable.call(object, symbol);
6081 * Creates an array of the own and inherited enumerable symbols of `object`.
6084 * @param {Object} object The object to query.
6085 * @returns {Array} Returns the array of symbols.
6087 var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
6090 arrayPush(result, getSymbols(object));
6091 object = getPrototype(object);
6097 * Gets the `toStringTag` of `value`.
6100 * @param {*} value The value to query.
6101 * @returns {string} Returns the `toStringTag`.
6103 var getTag = baseGetTag;
6105 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
6106 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
6107 (Map && getTag(new Map) != mapTag) ||
6108 (Promise && getTag(Promise.resolve()) != promiseTag) ||
6109 (Set && getTag(new Set) != setTag) ||
6110 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
6111 getTag = function(value) {
6112 var result = baseGetTag(value),
6113 Ctor = result == objectTag ? value.constructor : undefined,
6114 ctorString = Ctor ? toSource(Ctor) : '';
6117 switch (ctorString) {
6118 case dataViewCtorString: return dataViewTag;
6119 case mapCtorString: return mapTag;
6120 case promiseCtorString: return promiseTag;
6121 case setCtorString: return setTag;
6122 case weakMapCtorString: return weakMapTag;
6130 * Gets the view, applying any `transforms` to the `start` and `end` positions.
6133 * @param {number} start The start of the view.
6134 * @param {number} end The end of the view.
6135 * @param {Array} transforms The transformations to apply to the view.
6136 * @returns {Object} Returns an object containing the `start` and `end`
6137 * positions of the view.
6139 function getView(start, end, transforms) {
6141 length = transforms.length;
6143 while (++index < length) {
6144 var data = transforms[index],
6147 switch (data.type) {
6148 case 'drop': start += size; break;
6149 case 'dropRight': end -= size; break;
6150 case 'take': end = nativeMin(end, start + size); break;
6151 case 'takeRight': start = nativeMax(start, end - size); break;
6154 return { 'start': start, 'end': end };
6158 * Extracts wrapper details from the `source` body comment.
6161 * @param {string} source The source to inspect.
6162 * @returns {Array} Returns the wrapper details.
6164 function getWrapDetails(source) {
6165 var match = source.match(reWrapDetails);
6166 return match ? match[1].split(reSplitDetails) : [];
6170 * Checks if `path` exists on `object`.
6173 * @param {Object} object The object to query.
6174 * @param {Array|string} path The path to check.
6175 * @param {Function} hasFunc The function to check properties.
6176 * @returns {boolean} Returns `true` if `path` exists, else `false`.
6178 function hasPath(object, path, hasFunc) {
6179 path = castPath(path, object);
6182 length = path.length,
6185 while (++index < length) {
6186 var key = toKey(path[index]);
6187 if (!(result = object != null && hasFunc(object, key))) {
6190 object = object[key];
6192 if (result || ++index != length) {
6195 length = object == null ? 0 : object.length;
6196 return !!length && isLength(length) && isIndex(key, length) &&
6197 (isArray(object) || isArguments(object));
6201 * Initializes an array clone.
6204 * @param {Array} array The array to clone.
6205 * @returns {Array} Returns the initialized clone.
6207 function initCloneArray(array) {
6208 var length = array.length,
6209 result = array.constructor(length);
6211 // Add properties assigned by `RegExp#exec`.
6212 if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
6213 result.index = array.index;
6214 result.input = array.input;
6220 * Initializes an object clone.
6223 * @param {Object} object The object to clone.
6224 * @returns {Object} Returns the initialized clone.
6226 function initCloneObject(object) {
6227 return (typeof object.constructor == 'function' && !isPrototype(object))
6228 ? baseCreate(getPrototype(object))
6233 * Initializes an object clone based on its `toStringTag`.
6235 * **Note:** This function only supports cloning values with tags of
6236 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6239 * @param {Object} object The object to clone.
6240 * @param {string} tag The `toStringTag` of the object to clone.
6241 * @param {Function} cloneFunc The function to clone values.
6242 * @param {boolean} [isDeep] Specify a deep clone.
6243 * @returns {Object} Returns the initialized clone.
6245 function initCloneByTag(object, tag, cloneFunc, isDeep) {
6246 var Ctor = object.constructor;
6248 case arrayBufferTag:
6249 return cloneArrayBuffer(object);
6253 return new Ctor(+object);
6256 return cloneDataView(object, isDeep);
6258 case float32Tag: case float64Tag:
6259 case int8Tag: case int16Tag: case int32Tag:
6260 case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
6261 return cloneTypedArray(object, isDeep);
6264 return cloneMap(object, isDeep, cloneFunc);
6268 return new Ctor(object);
6271 return cloneRegExp(object);
6274 return cloneSet(object, isDeep, cloneFunc);
6277 return cloneSymbol(object);
6282 * Inserts wrapper `details` in a comment at the top of the `source` body.
6285 * @param {string} source The source to modify.
6286 * @returns {Array} details The details to insert.
6287 * @returns {string} Returns the modified source.
6289 function insertWrapDetails(source, details) {
6290 var length = details.length;
6294 var lastIndex = length - 1;
6295 details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
6296 details = details.join(length > 2 ? ', ' : ' ');
6297 return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
6301 * Checks if `value` is a flattenable `arguments` object or array.
6304 * @param {*} value The value to check.
6305 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
6307 function isFlattenable(value) {
6308 return isArray(value) || isArguments(value) ||
6309 !!(spreadableSymbol && value && value[spreadableSymbol]);
6313 * Checks if `value` is a valid array-like index.
6316 * @param {*} value The value to check.
6317 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
6318 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
6320 function isIndex(value, length) {
6321 length = length == null ? MAX_SAFE_INTEGER : length;
6323 (typeof value == 'number' || reIsUint.test(value)) &&
6324 (value > -1 && value % 1 == 0 && value < length);
6328 * Checks if the given arguments are from an iteratee call.
6331 * @param {*} value The potential iteratee value argument.
6332 * @param {*} index The potential iteratee index or key argument.
6333 * @param {*} object The potential iteratee object argument.
6334 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
6337 function isIterateeCall(value, index, object) {
6338 if (!isObject(object)) {
6341 var type = typeof index;
6342 if (type == 'number'
6343 ? (isArrayLike(object) && isIndex(index, object.length))
6344 : (type == 'string' && index in object)
6346 return eq(object[index], value);
6352 * Checks if `value` is a property name and not a property path.
6355 * @param {*} value The value to check.
6356 * @param {Object} [object] The object to query keys on.
6357 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
6359 function isKey(value, object) {
6360 if (isArray(value)) {
6363 var type = typeof value;
6364 if (type == 'number' || type == 'symbol' || type == 'boolean' ||
6365 value == null || isSymbol(value)) {
6368 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
6369 (object != null && value in Object(object));
6373 * Checks if `value` is suitable for use as unique object key.
6376 * @param {*} value The value to check.
6377 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
6379 function isKeyable(value) {
6380 var type = typeof value;
6381 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
6382 ? (value !== '__proto__')
6387 * Checks if `func` has a lazy counterpart.
6390 * @param {Function} func The function to check.
6391 * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
6394 function isLaziable(func) {
6395 var funcName = getFuncName(func),
6396 other = lodash[funcName];
6398 if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
6401 if (func === other) {
6404 var data = getData(other);
6405 return !!data && func === data[0];
6409 * Checks if `func` has its source masked.
6412 * @param {Function} func The function to check.
6413 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
6415 function isMasked(func) {
6416 return !!maskSrcKey && (maskSrcKey in func);
6420 * Checks if `func` is capable of being masked.
6423 * @param {*} value The value to check.
6424 * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
6426 var isMaskable = coreJsData ? isFunction : stubFalse;
6429 * Checks if `value` is likely a prototype object.
6432 * @param {*} value The value to check.
6433 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
6435 function isPrototype(value) {
6436 var Ctor = value && value.constructor,
6437 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
6439 return value === proto;
6443 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
6446 * @param {*} value The value to check.
6447 * @returns {boolean} Returns `true` if `value` if suitable for strict
6448 * equality comparisons, else `false`.
6450 function isStrictComparable(value) {
6451 return value === value && !isObject(value);
6455 * A specialized version of `matchesProperty` for source values suitable
6456 * for strict equality comparisons, i.e. `===`.
6459 * @param {string} key The key of the property to get.
6460 * @param {*} srcValue The value to match.
6461 * @returns {Function} Returns the new spec function.
6463 function matchesStrictComparable(key, srcValue) {
6464 return function(object) {
6465 if (object == null) {
6468 return object[key] === srcValue &&
6469 (srcValue !== undefined || (key in Object(object)));
6474 * A specialized version of `_.memoize` which clears the memoized function's
6475 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
6478 * @param {Function} func The function to have its output memoized.
6479 * @returns {Function} Returns the new memoized function.
6481 function memoizeCapped(func) {
6482 var result = memoize(func, function(key) {
6483 if (cache.size === MAX_MEMOIZE_SIZE) {
6489 var cache = result.cache;
6494 * Merges the function metadata of `source` into `data`.
6496 * Merging metadata reduces the number of wrappers used to invoke a function.
6497 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
6498 * may be applied regardless of execution order. Methods like `_.ary` and
6499 * `_.rearg` modify function arguments, making the order in which they are
6500 * executed important, preventing the merging of metadata. However, we make
6501 * an exception for a safe combined case where curried functions have `_.ary`
6502 * and or `_.rearg` applied.
6505 * @param {Array} data The destination metadata.
6506 * @param {Array} source The source metadata.
6507 * @returns {Array} Returns `data`.
6509 function mergeData(data, source) {
6510 var bitmask = data[1],
6511 srcBitmask = source[1],
6512 newBitmask = bitmask | srcBitmask,
6513 isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
6516 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
6517 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
6518 ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
6520 // Exit early if metadata can't be merged.
6521 if (!(isCommon || isCombo)) {
6524 // Use source `thisArg` if available.
6525 if (srcBitmask & WRAP_BIND_FLAG) {
6526 data[2] = source[2];
6527 // Set when currying a bound function.
6528 newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
6530 // Compose partial arguments.
6531 var value = source[3];
6533 var partials = data[3];
6534 data[3] = partials ? composeArgs(partials, value, source[4]) : value;
6535 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
6537 // Compose partial right arguments.
6541 data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
6542 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
6544 // Use source `argPos` if available.
6549 // Use source `ary` if it's smaller.
6550 if (srcBitmask & WRAP_ARY_FLAG) {
6551 data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
6553 // Use source `arity` if one is not provided.
6554 if (data[9] == null) {
6555 data[9] = source[9];
6557 // Use source `func` and merge bitmasks.
6558 data[0] = source[0];
6559 data[1] = newBitmask;
6565 * This function is like
6566 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
6567 * except that it includes inherited enumerable properties.
6570 * @param {Object} object The object to query.
6571 * @returns {Array} Returns the array of property names.
6573 function nativeKeysIn(object) {
6575 if (object != null) {
6576 for (var key in Object(object)) {
6584 * Converts `value` to a string using `Object.prototype.toString`.
6587 * @param {*} value The value to convert.
6588 * @returns {string} Returns the converted string.
6590 function objectToString(value) {
6591 return nativeObjectToString.call(value);
6595 * A specialized version of `baseRest` which transforms the rest array.
6598 * @param {Function} func The function to apply a rest parameter to.
6599 * @param {number} [start=func.length-1] The start position of the rest parameter.
6600 * @param {Function} transform The rest array transform.
6601 * @returns {Function} Returns the new function.
6603 function overRest(func, start, transform) {
6604 start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
6606 var args = arguments,
6608 length = nativeMax(args.length - start, 0),
6609 array = Array(length);
6611 while (++index < length) {
6612 array[index] = args[start + index];
6615 var otherArgs = Array(start + 1);
6616 while (++index < start) {
6617 otherArgs[index] = args[index];
6619 otherArgs[start] = transform(array);
6620 return apply(func, this, otherArgs);
6625 * Gets the parent value at `path` of `object`.
6628 * @param {Object} object The object to query.
6629 * @param {Array} path The path to get the parent value of.
6630 * @returns {*} Returns the parent value.
6632 function parent(object, path) {
6633 return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
6637 * Reorder `array` according to the specified indexes where the element at
6638 * the first index is assigned as the first element, the element at
6639 * the second index is assigned as the second element, and so on.
6642 * @param {Array} array The array to reorder.
6643 * @param {Array} indexes The arranged array indexes.
6644 * @returns {Array} Returns `array`.
6646 function reorder(array, indexes) {
6647 var arrLength = array.length,
6648 length = nativeMin(indexes.length, arrLength),
6649 oldArray = copyArray(array);
6652 var index = indexes[length];
6653 array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
6659 * Sets metadata for `func`.
6661 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
6662 * period of time, it will trip its breaker and transition to an identity
6663 * function to avoid garbage collection pauses in V8. See
6664 * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6668 * @param {Function} func The function to associate metadata with.
6669 * @param {*} data The metadata.
6670 * @returns {Function} Returns `func`.
6672 var setData = shortOut(baseSetData);
6675 * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
6678 * @param {Function} func The function to delay.
6679 * @param {number} wait The number of milliseconds to delay invocation.
6680 * @returns {number|Object} Returns the timer id or timeout object.
6682 var setTimeout = ctxSetTimeout || function(func, wait) {
6683 return root.setTimeout(func, wait);
6687 * Sets the `toString` method of `func` to return `string`.
6690 * @param {Function} func The function to modify.
6691 * @param {Function} string The `toString` result.
6692 * @returns {Function} Returns `func`.
6694 var setToString = shortOut(baseSetToString);
6697 * Sets the `toString` method of `wrapper` to mimic the source of `reference`
6698 * with wrapper details in a comment at the top of the source body.
6701 * @param {Function} wrapper The function to modify.
6702 * @param {Function} reference The reference function.
6703 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6704 * @returns {Function} Returns `wrapper`.
6706 function setWrapToString(wrapper, reference, bitmask) {
6707 var source = (reference + '');
6708 return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
6712 * Creates a function that'll short out and invoke `identity` instead
6713 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
6717 * @param {Function} func The function to restrict.
6718 * @returns {Function} Returns the new shortable function.
6720 function shortOut(func) {
6725 var stamp = nativeNow(),
6726 remaining = HOT_SPAN - (stamp - lastCalled);
6729 if (remaining > 0) {
6730 if (++count >= HOT_COUNT) {
6731 return arguments[0];
6736 return func.apply(undefined, arguments);
6741 * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
6744 * @param {Array} array The array to shuffle.
6745 * @param {number} [size=array.length] The size of `array`.
6746 * @returns {Array} Returns `array`.
6748 function shuffleSelf(array, size) {
6750 length = array.length,
6751 lastIndex = length - 1;
6753 size = size === undefined ? length : size;
6754 while (++index < size) {
6755 var rand = baseRandom(index, lastIndex),
6756 value = array[rand];
6758 array[rand] = array[index];
6759 array[index] = value;
6761 array.length = size;
6766 * Converts `string` to a property path array.
6769 * @param {string} string The string to convert.
6770 * @returns {Array} Returns the property path array.
6772 var stringToPath = memoizeCapped(function(string) {
6774 if (reLeadingDot.test(string)) {
6777 string.replace(rePropName, function(match, number, quote, string) {
6778 result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
6784 * Converts `value` to a string key if it's not a string or symbol.
6787 * @param {*} value The value to inspect.
6788 * @returns {string|symbol} Returns the key.
6790 function toKey(value) {
6791 if (typeof value == 'string' || isSymbol(value)) {
6794 var result = (value + '');
6795 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6799 * Converts `func` to its source code.
6802 * @param {Function} func The function to convert.
6803 * @returns {string} Returns the source code.
6805 function toSource(func) {
6808 return funcToString.call(func);
6818 * Updates wrapper `details` based on `bitmask` flags.
6821 * @returns {Array} details The details to modify.
6822 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6823 * @returns {Array} Returns `details`.
6825 function updateWrapDetails(details, bitmask) {
6826 arrayEach(wrapFlags, function(pair) {
6827 var value = '_.' + pair[0];
6828 if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
6829 details.push(value);
6832 return details.sort();
6836 * Creates a clone of `wrapper`.
6839 * @param {Object} wrapper The wrapper to clone.
6840 * @returns {Object} Returns the cloned wrapper.
6842 function wrapperClone(wrapper) {
6843 if (wrapper instanceof LazyWrapper) {
6844 return wrapper.clone();
6846 var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6847 result.__actions__ = copyArray(wrapper.__actions__);
6848 result.__index__ = wrapper.__index__;
6849 result.__values__ = wrapper.__values__;
6853 /*------------------------------------------------------------------------*/
6856 * Creates an array of elements split into groups the length of `size`.
6857 * If `array` can't be split evenly, the final chunk will be the remaining
6864 * @param {Array} array The array to process.
6865 * @param {number} [size=1] The length of each chunk
6866 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6867 * @returns {Array} Returns the new array of chunks.
6870 * _.chunk(['a', 'b', 'c', 'd'], 2);
6871 * // => [['a', 'b'], ['c', 'd']]
6873 * _.chunk(['a', 'b', 'c', 'd'], 3);
6874 * // => [['a', 'b', 'c'], ['d']]
6876 function chunk(array, size, guard) {
6877 if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6880 size = nativeMax(toInteger(size), 0);
6882 var length = array == null ? 0 : array.length;
6883 if (!length || size < 1) {
6888 result = Array(nativeCeil(length / size));
6890 while (index < length) {
6891 result[resIndex++] = baseSlice(array, index, (index += size));
6897 * Creates an array with all falsey values removed. The values `false`, `null`,
6898 * `0`, `""`, `undefined`, and `NaN` are falsey.
6904 * @param {Array} array The array to compact.
6905 * @returns {Array} Returns the new array of filtered values.
6908 * _.compact([0, 1, false, 2, '', 3]);
6911 function compact(array) {
6913 length = array == null ? 0 : array.length,
6917 while (++index < length) {
6918 var value = array[index];
6920 result[resIndex++] = value;
6927 * Creates a new array concatenating `array` with any additional arrays
6934 * @param {Array} array The array to concatenate.
6935 * @param {...*} [values] The values to concatenate.
6936 * @returns {Array} Returns the new concatenated array.
6940 * var other = _.concat(array, 2, [3], [[4]]);
6942 * console.log(other);
6943 * // => [1, 2, 3, [4]]
6945 * console.log(array);
6949 var length = arguments.length;
6953 var args = Array(length - 1),
6954 array = arguments[0],
6958 args[index - 1] = arguments[index];
6960 return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
6964 * Creates an array of `array` values not included in the other given arrays
6965 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
6966 * for equality comparisons. The order and references of result values are
6967 * determined by the first array.
6969 * **Note:** Unlike `_.pullAll`, this method returns a new array.
6975 * @param {Array} array The array to inspect.
6976 * @param {...Array} [values] The values to exclude.
6977 * @returns {Array} Returns the new array of filtered values.
6978 * @see _.without, _.xor
6981 * _.difference([2, 1], [2, 3]);
6984 var difference = baseRest(function(array, values) {
6985 return isArrayLikeObject(array)
6986 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6991 * This method is like `_.difference` except that it accepts `iteratee` which
6992 * is invoked for each element of `array` and `values` to generate the criterion
6993 * by which they're compared. The order and references of result values are
6994 * determined by the first array. The iteratee is invoked with one argument:
6997 * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
7003 * @param {Array} array The array to inspect.
7004 * @param {...Array} [values] The values to exclude.
7005 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7006 * @returns {Array} Returns the new array of filtered values.
7009 * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7012 * // The `_.property` iteratee shorthand.
7013 * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
7014 * // => [{ 'x': 2 }]
7016 var differenceBy = baseRest(function(array, values) {
7017 var iteratee = last(values);
7018 if (isArrayLikeObject(iteratee)) {
7019 iteratee = undefined;
7021 return isArrayLikeObject(array)
7022 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
7027 * This method is like `_.difference` except that it accepts `comparator`
7028 * which is invoked to compare elements of `array` to `values`. The order and
7029 * references of result values are determined by the first array. The comparator
7030 * is invoked with two arguments: (arrVal, othVal).
7032 * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
7038 * @param {Array} array The array to inspect.
7039 * @param {...Array} [values] The values to exclude.
7040 * @param {Function} [comparator] The comparator invoked per element.
7041 * @returns {Array} Returns the new array of filtered values.
7044 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7046 * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
7047 * // => [{ 'x': 2, 'y': 1 }]
7049 var differenceWith = baseRest(function(array, values) {
7050 var comparator = last(values);
7051 if (isArrayLikeObject(comparator)) {
7052 comparator = undefined;
7054 return isArrayLikeObject(array)
7055 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
7060 * Creates a slice of `array` with `n` elements dropped from the beginning.
7066 * @param {Array} array The array to query.
7067 * @param {number} [n=1] The number of elements to drop.
7068 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7069 * @returns {Array} Returns the slice of `array`.
7072 * _.drop([1, 2, 3]);
7075 * _.drop([1, 2, 3], 2);
7078 * _.drop([1, 2, 3], 5);
7081 * _.drop([1, 2, 3], 0);
7084 function drop(array, n, guard) {
7085 var length = array == null ? 0 : array.length;
7089 n = (guard || n === undefined) ? 1 : toInteger(n);
7090 return baseSlice(array, n < 0 ? 0 : n, length);
7094 * Creates a slice of `array` with `n` elements dropped from the end.
7100 * @param {Array} array The array to query.
7101 * @param {number} [n=1] The number of elements to drop.
7102 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7103 * @returns {Array} Returns the slice of `array`.
7106 * _.dropRight([1, 2, 3]);
7109 * _.dropRight([1, 2, 3], 2);
7112 * _.dropRight([1, 2, 3], 5);
7115 * _.dropRight([1, 2, 3], 0);
7118 function dropRight(array, n, guard) {
7119 var length = array == null ? 0 : array.length;
7123 n = (guard || n === undefined) ? 1 : toInteger(n);
7125 return baseSlice(array, 0, n < 0 ? 0 : n);
7129 * Creates a slice of `array` excluding elements dropped from the end.
7130 * Elements are dropped until `predicate` returns falsey. The predicate is
7131 * invoked with three arguments: (value, index, array).
7137 * @param {Array} array The array to query.
7138 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7139 * @returns {Array} Returns the slice of `array`.
7143 * { 'user': 'barney', 'active': true },
7144 * { 'user': 'fred', 'active': false },
7145 * { 'user': 'pebbles', 'active': false }
7148 * _.dropRightWhile(users, function(o) { return !o.active; });
7149 * // => objects for ['barney']
7151 * // The `_.matches` iteratee shorthand.
7152 * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
7153 * // => objects for ['barney', 'fred']
7155 * // The `_.matchesProperty` iteratee shorthand.
7156 * _.dropRightWhile(users, ['active', false]);
7157 * // => objects for ['barney']
7159 * // The `_.property` iteratee shorthand.
7160 * _.dropRightWhile(users, 'active');
7161 * // => objects for ['barney', 'fred', 'pebbles']
7163 function dropRightWhile(array, predicate) {
7164 return (array && array.length)
7165 ? baseWhile(array, getIteratee(predicate, 3), true, true)
7170 * Creates a slice of `array` excluding elements dropped from the beginning.
7171 * Elements are dropped until `predicate` returns falsey. The predicate is
7172 * invoked with three arguments: (value, index, array).
7178 * @param {Array} array The array to query.
7179 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7180 * @returns {Array} Returns the slice of `array`.
7184 * { 'user': 'barney', 'active': false },
7185 * { 'user': 'fred', 'active': false },
7186 * { 'user': 'pebbles', 'active': true }
7189 * _.dropWhile(users, function(o) { return !o.active; });
7190 * // => objects for ['pebbles']
7192 * // The `_.matches` iteratee shorthand.
7193 * _.dropWhile(users, { 'user': 'barney', 'active': false });
7194 * // => objects for ['fred', 'pebbles']
7196 * // The `_.matchesProperty` iteratee shorthand.
7197 * _.dropWhile(users, ['active', false]);
7198 * // => objects for ['pebbles']
7200 * // The `_.property` iteratee shorthand.
7201 * _.dropWhile(users, 'active');
7202 * // => objects for ['barney', 'fred', 'pebbles']
7204 function dropWhile(array, predicate) {
7205 return (array && array.length)
7206 ? baseWhile(array, getIteratee(predicate, 3), true)
7211 * Fills elements of `array` with `value` from `start` up to, but not
7214 * **Note:** This method mutates `array`.
7220 * @param {Array} array The array to fill.
7221 * @param {*} value The value to fill `array` with.
7222 * @param {number} [start=0] The start position.
7223 * @param {number} [end=array.length] The end position.
7224 * @returns {Array} Returns `array`.
7227 * var array = [1, 2, 3];
7229 * _.fill(array, 'a');
7230 * console.log(array);
7231 * // => ['a', 'a', 'a']
7233 * _.fill(Array(3), 2);
7236 * _.fill([4, 6, 8, 10], '*', 1, 3);
7237 * // => [4, '*', '*', 10]
7239 function fill(array, value, start, end) {
7240 var length = array == null ? 0 : array.length;
7244 if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
7248 return baseFill(array, value, start, end);
7252 * This method is like `_.find` except that it returns the index of the first
7253 * element `predicate` returns truthy for instead of the element itself.
7259 * @param {Array} array The array to inspect.
7260 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7261 * @param {number} [fromIndex=0] The index to search from.
7262 * @returns {number} Returns the index of the found element, else `-1`.
7266 * { 'user': 'barney', 'active': false },
7267 * { 'user': 'fred', 'active': false },
7268 * { 'user': 'pebbles', 'active': true }
7271 * _.findIndex(users, function(o) { return o.user == 'barney'; });
7274 * // The `_.matches` iteratee shorthand.
7275 * _.findIndex(users, { 'user': 'fred', 'active': false });
7278 * // The `_.matchesProperty` iteratee shorthand.
7279 * _.findIndex(users, ['active', false]);
7282 * // The `_.property` iteratee shorthand.
7283 * _.findIndex(users, 'active');
7286 function findIndex(array, predicate, fromIndex) {
7287 var length = array == null ? 0 : array.length;
7291 var index = fromIndex == null ? 0 : toInteger(fromIndex);
7293 index = nativeMax(length + index, 0);
7295 return baseFindIndex(array, getIteratee(predicate, 3), index);
7299 * This method is like `_.findIndex` except that it iterates over elements
7300 * of `collection` from right to left.
7306 * @param {Array} array The array to inspect.
7307 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7308 * @param {number} [fromIndex=array.length-1] The index to search from.
7309 * @returns {number} Returns the index of the found element, else `-1`.
7313 * { 'user': 'barney', 'active': true },
7314 * { 'user': 'fred', 'active': false },
7315 * { 'user': 'pebbles', 'active': false }
7318 * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
7321 * // The `_.matches` iteratee shorthand.
7322 * _.findLastIndex(users, { 'user': 'barney', 'active': true });
7325 * // The `_.matchesProperty` iteratee shorthand.
7326 * _.findLastIndex(users, ['active', false]);
7329 * // The `_.property` iteratee shorthand.
7330 * _.findLastIndex(users, 'active');
7333 function findLastIndex(array, predicate, fromIndex) {
7334 var length = array == null ? 0 : array.length;
7338 var index = length - 1;
7339 if (fromIndex !== undefined) {
7340 index = toInteger(fromIndex);
7341 index = fromIndex < 0
7342 ? nativeMax(length + index, 0)
7343 : nativeMin(index, length - 1);
7345 return baseFindIndex(array, getIteratee(predicate, 3), index, true);
7349 * Flattens `array` a single level deep.
7355 * @param {Array} array The array to flatten.
7356 * @returns {Array} Returns the new flattened array.
7359 * _.flatten([1, [2, [3, [4]], 5]]);
7360 * // => [1, 2, [3, [4]], 5]
7362 function flatten(array) {
7363 var length = array == null ? 0 : array.length;
7364 return length ? baseFlatten(array, 1) : [];
7368 * Recursively flattens `array`.
7374 * @param {Array} array The array to flatten.
7375 * @returns {Array} Returns the new flattened array.
7378 * _.flattenDeep([1, [2, [3, [4]], 5]]);
7379 * // => [1, 2, 3, 4, 5]
7381 function flattenDeep(array) {
7382 var length = array == null ? 0 : array.length;
7383 return length ? baseFlatten(array, INFINITY) : [];
7387 * Recursively flatten `array` up to `depth` times.
7393 * @param {Array} array The array to flatten.
7394 * @param {number} [depth=1] The maximum recursion depth.
7395 * @returns {Array} Returns the new flattened array.
7398 * var array = [1, [2, [3, [4]], 5]];
7400 * _.flattenDepth(array, 1);
7401 * // => [1, 2, [3, [4]], 5]
7403 * _.flattenDepth(array, 2);
7404 * // => [1, 2, 3, [4], 5]
7406 function flattenDepth(array, depth) {
7407 var length = array == null ? 0 : array.length;
7411 depth = depth === undefined ? 1 : toInteger(depth);
7412 return baseFlatten(array, depth);
7416 * The inverse of `_.toPairs`; this method returns an object composed
7417 * from key-value `pairs`.
7423 * @param {Array} pairs The key-value pairs.
7424 * @returns {Object} Returns the new object.
7427 * _.fromPairs([['a', 1], ['b', 2]]);
7428 * // => { 'a': 1, 'b': 2 }
7430 function fromPairs(pairs) {
7432 length = pairs == null ? 0 : pairs.length,
7435 while (++index < length) {
7436 var pair = pairs[index];
7437 result[pair[0]] = pair[1];
7443 * Gets the first element of `array`.
7450 * @param {Array} array The array to query.
7451 * @returns {*} Returns the first element of `array`.
7454 * _.head([1, 2, 3]);
7460 function head(array) {
7461 return (array && array.length) ? array[0] : undefined;
7465 * Gets the index at which the first occurrence of `value` is found in `array`
7466 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7467 * for equality comparisons. If `fromIndex` is negative, it's used as the
7468 * offset from the end of `array`.
7474 * @param {Array} array The array to inspect.
7475 * @param {*} value The value to search for.
7476 * @param {number} [fromIndex=0] The index to search from.
7477 * @returns {number} Returns the index of the matched value, else `-1`.
7480 * _.indexOf([1, 2, 1, 2], 2);
7483 * // Search from the `fromIndex`.
7484 * _.indexOf([1, 2, 1, 2], 2, 2);
7487 function indexOf(array, value, fromIndex) {
7488 var length = array == null ? 0 : array.length;
7492 var index = fromIndex == null ? 0 : toInteger(fromIndex);
7494 index = nativeMax(length + index, 0);
7496 return baseIndexOf(array, value, index);
7500 * Gets all but the last element of `array`.
7506 * @param {Array} array The array to query.
7507 * @returns {Array} Returns the slice of `array`.
7510 * _.initial([1, 2, 3]);
7513 function initial(array) {
7514 var length = array == null ? 0 : array.length;
7515 return length ? baseSlice(array, 0, -1) : [];
7519 * Creates an array of unique values that are included in all given arrays
7520 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7521 * for equality comparisons. The order and references of result values are
7522 * determined by the first array.
7528 * @param {...Array} [arrays] The arrays to inspect.
7529 * @returns {Array} Returns the new array of intersecting values.
7532 * _.intersection([2, 1], [2, 3]);
7535 var intersection = baseRest(function(arrays) {
7536 var mapped = arrayMap(arrays, castArrayLikeObject);
7537 return (mapped.length && mapped[0] === arrays[0])
7538 ? baseIntersection(mapped)
7543 * This method is like `_.intersection` except that it accepts `iteratee`
7544 * which is invoked for each element of each `arrays` to generate the criterion
7545 * by which they're compared. The order and references of result values are
7546 * determined by the first array. The iteratee is invoked with one argument:
7553 * @param {...Array} [arrays] The arrays to inspect.
7554 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7555 * @returns {Array} Returns the new array of intersecting values.
7558 * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7561 * // The `_.property` iteratee shorthand.
7562 * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7563 * // => [{ 'x': 1 }]
7565 var intersectionBy = baseRest(function(arrays) {
7566 var iteratee = last(arrays),
7567 mapped = arrayMap(arrays, castArrayLikeObject);
7569 if (iteratee === last(mapped)) {
7570 iteratee = undefined;
7574 return (mapped.length && mapped[0] === arrays[0])
7575 ? baseIntersection(mapped, getIteratee(iteratee, 2))
7580 * This method is like `_.intersection` except that it accepts `comparator`
7581 * which is invoked to compare elements of `arrays`. The order and references
7582 * of result values are determined by the first array. The comparator is
7583 * invoked with two arguments: (arrVal, othVal).
7589 * @param {...Array} [arrays] The arrays to inspect.
7590 * @param {Function} [comparator] The comparator invoked per element.
7591 * @returns {Array} Returns the new array of intersecting values.
7594 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7595 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7597 * _.intersectionWith(objects, others, _.isEqual);
7598 * // => [{ 'x': 1, 'y': 2 }]
7600 var intersectionWith = baseRest(function(arrays) {
7601 var comparator = last(arrays),
7602 mapped = arrayMap(arrays, castArrayLikeObject);
7604 comparator = typeof comparator == 'function' ? comparator : undefined;
7608 return (mapped.length && mapped[0] === arrays[0])
7609 ? baseIntersection(mapped, undefined, comparator)
7614 * Converts all elements in `array` into a string separated by `separator`.
7620 * @param {Array} array The array to convert.
7621 * @param {string} [separator=','] The element separator.
7622 * @returns {string} Returns the joined string.
7625 * _.join(['a', 'b', 'c'], '~');
7628 function join(array, separator) {
7629 return array == null ? '' : nativeJoin.call(array, separator);
7633 * Gets the last element of `array`.
7639 * @param {Array} array The array to query.
7640 * @returns {*} Returns the last element of `array`.
7643 * _.last([1, 2, 3]);
7646 function last(array) {
7647 var length = array == null ? 0 : array.length;
7648 return length ? array[length - 1] : undefined;
7652 * This method is like `_.indexOf` except that it iterates over elements of
7653 * `array` from right to left.
7659 * @param {Array} array The array to inspect.
7660 * @param {*} value The value to search for.
7661 * @param {number} [fromIndex=array.length-1] The index to search from.
7662 * @returns {number} Returns the index of the matched value, else `-1`.
7665 * _.lastIndexOf([1, 2, 1, 2], 2);
7668 * // Search from the `fromIndex`.
7669 * _.lastIndexOf([1, 2, 1, 2], 2, 2);
7672 function lastIndexOf(array, value, fromIndex) {
7673 var length = array == null ? 0 : array.length;
7678 if (fromIndex !== undefined) {
7679 index = toInteger(fromIndex);
7680 index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
7682 return value === value
7683 ? strictLastIndexOf(array, value, index)
7684 : baseFindIndex(array, baseIsNaN, index, true);
7688 * Gets the element at index `n` of `array`. If `n` is negative, the nth
7689 * element from the end is returned.
7695 * @param {Array} array The array to query.
7696 * @param {number} [n=0] The index of the element to return.
7697 * @returns {*} Returns the nth element of `array`.
7700 * var array = ['a', 'b', 'c', 'd'];
7708 function nth(array, n) {
7709 return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
7713 * Removes all given values from `array` using
7714 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7715 * for equality comparisons.
7717 * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
7718 * to remove elements from an array by predicate.
7724 * @param {Array} array The array to modify.
7725 * @param {...*} [values] The values to remove.
7726 * @returns {Array} Returns `array`.
7729 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7731 * _.pull(array, 'a', 'c');
7732 * console.log(array);
7735 var pull = baseRest(pullAll);
7738 * This method is like `_.pull` except that it accepts an array of values to remove.
7740 * **Note:** Unlike `_.difference`, this method mutates `array`.
7746 * @param {Array} array The array to modify.
7747 * @param {Array} values The values to remove.
7748 * @returns {Array} Returns `array`.
7751 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7753 * _.pullAll(array, ['a', 'c']);
7754 * console.log(array);
7757 function pullAll(array, values) {
7758 return (array && array.length && values && values.length)
7759 ? basePullAll(array, values)
7764 * This method is like `_.pullAll` except that it accepts `iteratee` which is
7765 * invoked for each element of `array` and `values` to generate the criterion
7766 * by which they're compared. The iteratee is invoked with one argument: (value).
7768 * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7774 * @param {Array} array The array to modify.
7775 * @param {Array} values The values to remove.
7776 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7777 * @returns {Array} Returns `array`.
7780 * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7782 * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7783 * console.log(array);
7784 * // => [{ 'x': 2 }]
7786 function pullAllBy(array, values, iteratee) {
7787 return (array && array.length && values && values.length)
7788 ? basePullAll(array, values, getIteratee(iteratee, 2))
7793 * This method is like `_.pullAll` except that it accepts `comparator` which
7794 * is invoked to compare elements of `array` to `values`. The comparator is
7795 * invoked with two arguments: (arrVal, othVal).
7797 * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7803 * @param {Array} array The array to modify.
7804 * @param {Array} values The values to remove.
7805 * @param {Function} [comparator] The comparator invoked per element.
7806 * @returns {Array} Returns `array`.
7809 * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7811 * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7812 * console.log(array);
7813 * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7815 function pullAllWith(array, values, comparator) {
7816 return (array && array.length && values && values.length)
7817 ? basePullAll(array, values, undefined, comparator)
7822 * Removes elements from `array` corresponding to `indexes` and returns an
7823 * array of removed elements.
7825 * **Note:** Unlike `_.at`, this method mutates `array`.
7831 * @param {Array} array The array to modify.
7832 * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7833 * @returns {Array} Returns the new array of removed elements.
7836 * var array = ['a', 'b', 'c', 'd'];
7837 * var pulled = _.pullAt(array, [1, 3]);
7839 * console.log(array);
7842 * console.log(pulled);
7845 var pullAt = flatRest(function(array, indexes) {
7846 var length = array == null ? 0 : array.length,
7847 result = baseAt(array, indexes);
7849 basePullAt(array, arrayMap(indexes, function(index) {
7850 return isIndex(index, length) ? +index : index;
7851 }).sort(compareAscending));
7857 * Removes all elements from `array` that `predicate` returns truthy for
7858 * and returns an array of the removed elements. The predicate is invoked
7859 * with three arguments: (value, index, array).
7861 * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7862 * to pull elements from an array by value.
7868 * @param {Array} array The array to modify.
7869 * @param {Function} [predicate=_.identity] The function invoked per iteration.
7870 * @returns {Array} Returns the new array of removed elements.
7873 * var array = [1, 2, 3, 4];
7874 * var evens = _.remove(array, function(n) {
7875 * return n % 2 == 0;
7878 * console.log(array);
7881 * console.log(evens);
7884 function remove(array, predicate) {
7886 if (!(array && array.length)) {
7891 length = array.length;
7893 predicate = getIteratee(predicate, 3);
7894 while (++index < length) {
7895 var value = array[index];
7896 if (predicate(value, index, array)) {
7898 indexes.push(index);
7901 basePullAt(array, indexes);
7906 * Reverses `array` so that the first element becomes the last, the second
7907 * element becomes the second to last, and so on.
7909 * **Note:** This method mutates `array` and is based on
7910 * [`Array#reverse`](https://mdn.io/Array/reverse).
7916 * @param {Array} array The array to modify.
7917 * @returns {Array} Returns `array`.
7920 * var array = [1, 2, 3];
7925 * console.log(array);
7928 function reverse(array) {
7929 return array == null ? array : nativeReverse.call(array);
7933 * Creates a slice of `array` from `start` up to, but not including, `end`.
7935 * **Note:** This method is used instead of
7936 * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7943 * @param {Array} array The array to slice.
7944 * @param {number} [start=0] The start position.
7945 * @param {number} [end=array.length] The end position.
7946 * @returns {Array} Returns the slice of `array`.
7948 function slice(array, start, end) {
7949 var length = array == null ? 0 : array.length;
7953 if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7958 start = start == null ? 0 : toInteger(start);
7959 end = end === undefined ? length : toInteger(end);
7961 return baseSlice(array, start, end);
7965 * Uses a binary search to determine the lowest index at which `value`
7966 * should be inserted into `array` in order to maintain its sort order.
7972 * @param {Array} array The sorted array to inspect.
7973 * @param {*} value The value to evaluate.
7974 * @returns {number} Returns the index at which `value` should be inserted
7978 * _.sortedIndex([30, 50], 40);
7981 function sortedIndex(array, value) {
7982 return baseSortedIndex(array, value);
7986 * This method is like `_.sortedIndex` except that it accepts `iteratee`
7987 * which is invoked for `value` and each element of `array` to compute their
7988 * sort ranking. The iteratee is invoked with one argument: (value).
7994 * @param {Array} array The sorted array to inspect.
7995 * @param {*} value The value to evaluate.
7996 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7997 * @returns {number} Returns the index at which `value` should be inserted
8001 * var objects = [{ 'x': 4 }, { 'x': 5 }];
8003 * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8006 * // The `_.property` iteratee shorthand.
8007 * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
8010 function sortedIndexBy(array, value, iteratee) {
8011 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
8015 * This method is like `_.indexOf` except that it performs a binary
8016 * search on a sorted `array`.
8022 * @param {Array} array The array to inspect.
8023 * @param {*} value The value to search for.
8024 * @returns {number} Returns the index of the matched value, else `-1`.
8027 * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
8030 function sortedIndexOf(array, value) {
8031 var length = array == null ? 0 : array.length;
8033 var index = baseSortedIndex(array, value);
8034 if (index < length && eq(array[index], value)) {
8042 * This method is like `_.sortedIndex` except that it returns the highest
8043 * index at which `value` should be inserted into `array` in order to
8044 * maintain its sort order.
8050 * @param {Array} array The sorted array to inspect.
8051 * @param {*} value The value to evaluate.
8052 * @returns {number} Returns the index at which `value` should be inserted
8056 * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
8059 function sortedLastIndex(array, value) {
8060 return baseSortedIndex(array, value, true);
8064 * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
8065 * which is invoked for `value` and each element of `array` to compute their
8066 * sort ranking. The iteratee is invoked with one argument: (value).
8072 * @param {Array} array The sorted array to inspect.
8073 * @param {*} value The value to evaluate.
8074 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8075 * @returns {number} Returns the index at which `value` should be inserted
8079 * var objects = [{ 'x': 4 }, { 'x': 5 }];
8081 * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8084 * // The `_.property` iteratee shorthand.
8085 * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
8088 function sortedLastIndexBy(array, value, iteratee) {
8089 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
8093 * This method is like `_.lastIndexOf` except that it performs a binary
8094 * search on a sorted `array`.
8100 * @param {Array} array The array to inspect.
8101 * @param {*} value The value to search for.
8102 * @returns {number} Returns the index of the matched value, else `-1`.
8105 * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
8108 function sortedLastIndexOf(array, value) {
8109 var length = array == null ? 0 : array.length;
8111 var index = baseSortedIndex(array, value, true) - 1;
8112 if (eq(array[index], value)) {
8120 * This method is like `_.uniq` except that it's designed and optimized
8121 * for sorted arrays.
8127 * @param {Array} array The array to inspect.
8128 * @returns {Array} Returns the new duplicate free array.
8131 * _.sortedUniq([1, 1, 2]);
8134 function sortedUniq(array) {
8135 return (array && array.length)
8136 ? baseSortedUniq(array)
8141 * This method is like `_.uniqBy` except that it's designed and optimized
8142 * for sorted arrays.
8148 * @param {Array} array The array to inspect.
8149 * @param {Function} [iteratee] The iteratee invoked per element.
8150 * @returns {Array} Returns the new duplicate free array.
8153 * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
8156 function sortedUniqBy(array, iteratee) {
8157 return (array && array.length)
8158 ? baseSortedUniq(array, getIteratee(iteratee, 2))
8163 * Gets all but the first element of `array`.
8169 * @param {Array} array The array to query.
8170 * @returns {Array} Returns the slice of `array`.
8173 * _.tail([1, 2, 3]);
8176 function tail(array) {
8177 var length = array == null ? 0 : array.length;
8178 return length ? baseSlice(array, 1, length) : [];
8182 * Creates a slice of `array` with `n` elements taken from the beginning.
8188 * @param {Array} array The array to query.
8189 * @param {number} [n=1] The number of elements to take.
8190 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8191 * @returns {Array} Returns the slice of `array`.
8194 * _.take([1, 2, 3]);
8197 * _.take([1, 2, 3], 2);
8200 * _.take([1, 2, 3], 5);
8203 * _.take([1, 2, 3], 0);
8206 function take(array, n, guard) {
8207 if (!(array && array.length)) {
8210 n = (guard || n === undefined) ? 1 : toInteger(n);
8211 return baseSlice(array, 0, n < 0 ? 0 : n);
8215 * Creates a slice of `array` with `n` elements taken from the end.
8221 * @param {Array} array The array to query.
8222 * @param {number} [n=1] The number of elements to take.
8223 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8224 * @returns {Array} Returns the slice of `array`.
8227 * _.takeRight([1, 2, 3]);
8230 * _.takeRight([1, 2, 3], 2);
8233 * _.takeRight([1, 2, 3], 5);
8236 * _.takeRight([1, 2, 3], 0);
8239 function takeRight(array, n, guard) {
8240 var length = array == null ? 0 : array.length;
8244 n = (guard || n === undefined) ? 1 : toInteger(n);
8246 return baseSlice(array, n < 0 ? 0 : n, length);
8250 * Creates a slice of `array` with elements taken from the end. Elements are
8251 * taken until `predicate` returns falsey. The predicate is invoked with
8252 * three arguments: (value, index, array).
8258 * @param {Array} array The array to query.
8259 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8260 * @returns {Array} Returns the slice of `array`.
8264 * { 'user': 'barney', 'active': true },
8265 * { 'user': 'fred', 'active': false },
8266 * { 'user': 'pebbles', 'active': false }
8269 * _.takeRightWhile(users, function(o) { return !o.active; });
8270 * // => objects for ['fred', 'pebbles']
8272 * // The `_.matches` iteratee shorthand.
8273 * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
8274 * // => objects for ['pebbles']
8276 * // The `_.matchesProperty` iteratee shorthand.
8277 * _.takeRightWhile(users, ['active', false]);
8278 * // => objects for ['fred', 'pebbles']
8280 * // The `_.property` iteratee shorthand.
8281 * _.takeRightWhile(users, 'active');
8284 function takeRightWhile(array, predicate) {
8285 return (array && array.length)
8286 ? baseWhile(array, getIteratee(predicate, 3), false, true)
8291 * Creates a slice of `array` with elements taken from the beginning. Elements
8292 * are taken until `predicate` returns falsey. The predicate is invoked with
8293 * three arguments: (value, index, array).
8299 * @param {Array} array The array to query.
8300 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8301 * @returns {Array} Returns the slice of `array`.
8305 * { 'user': 'barney', 'active': false },
8306 * { 'user': 'fred', 'active': false },
8307 * { 'user': 'pebbles', 'active': true }
8310 * _.takeWhile(users, function(o) { return !o.active; });
8311 * // => objects for ['barney', 'fred']
8313 * // The `_.matches` iteratee shorthand.
8314 * _.takeWhile(users, { 'user': 'barney', 'active': false });
8315 * // => objects for ['barney']
8317 * // The `_.matchesProperty` iteratee shorthand.
8318 * _.takeWhile(users, ['active', false]);
8319 * // => objects for ['barney', 'fred']
8321 * // The `_.property` iteratee shorthand.
8322 * _.takeWhile(users, 'active');
8325 function takeWhile(array, predicate) {
8326 return (array && array.length)
8327 ? baseWhile(array, getIteratee(predicate, 3))
8332 * Creates an array of unique values, in order, from all given arrays using
8333 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8334 * for equality comparisons.
8340 * @param {...Array} [arrays] The arrays to inspect.
8341 * @returns {Array} Returns the new array of combined values.
8344 * _.union([2], [1, 2]);
8347 var union = baseRest(function(arrays) {
8348 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
8352 * This method is like `_.union` except that it accepts `iteratee` which is
8353 * invoked for each element of each `arrays` to generate the criterion by
8354 * which uniqueness is computed. Result values are chosen from the first
8355 * array in which the value occurs. The iteratee is invoked with one argument:
8362 * @param {...Array} [arrays] The arrays to inspect.
8363 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8364 * @returns {Array} Returns the new array of combined values.
8367 * _.unionBy([2.1], [1.2, 2.3], Math.floor);
8370 * // The `_.property` iteratee shorthand.
8371 * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8372 * // => [{ 'x': 1 }, { 'x': 2 }]
8374 var unionBy = baseRest(function(arrays) {
8375 var iteratee = last(arrays);
8376 if (isArrayLikeObject(iteratee)) {
8377 iteratee = undefined;
8379 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
8383 * This method is like `_.union` except that it accepts `comparator` which
8384 * is invoked to compare elements of `arrays`. Result values are chosen from
8385 * the first array in which the value occurs. The comparator is invoked
8386 * with two arguments: (arrVal, othVal).
8392 * @param {...Array} [arrays] The arrays to inspect.
8393 * @param {Function} [comparator] The comparator invoked per element.
8394 * @returns {Array} Returns the new array of combined values.
8397 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8398 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8400 * _.unionWith(objects, others, _.isEqual);
8401 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8403 var unionWith = baseRest(function(arrays) {
8404 var comparator = last(arrays);
8405 comparator = typeof comparator == 'function' ? comparator : undefined;
8406 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
8410 * Creates a duplicate-free version of an array, using
8411 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8412 * for equality comparisons, in which only the first occurrence of each element
8413 * is kept. The order of result values is determined by the order they occur
8420 * @param {Array} array The array to inspect.
8421 * @returns {Array} Returns the new duplicate free array.
8424 * _.uniq([2, 1, 2]);
8427 function uniq(array) {
8428 return (array && array.length) ? baseUniq(array) : [];
8432 * This method is like `_.uniq` except that it accepts `iteratee` which is
8433 * invoked for each element in `array` to generate the criterion by which
8434 * uniqueness is computed. The order of result values is determined by the
8435 * order they occur in the array. The iteratee is invoked with one argument:
8442 * @param {Array} array The array to inspect.
8443 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8444 * @returns {Array} Returns the new duplicate free array.
8447 * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
8450 * // The `_.property` iteratee shorthand.
8451 * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
8452 * // => [{ 'x': 1 }, { 'x': 2 }]
8454 function uniqBy(array, iteratee) {
8455 return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
8459 * This method is like `_.uniq` except that it accepts `comparator` which
8460 * is invoked to compare elements of `array`. The order of result values is
8461 * determined by the order they occur in the array.The comparator is invoked
8462 * with two arguments: (arrVal, othVal).
8468 * @param {Array} array The array to inspect.
8469 * @param {Function} [comparator] The comparator invoked per element.
8470 * @returns {Array} Returns the new duplicate free array.
8473 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
8475 * _.uniqWith(objects, _.isEqual);
8476 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
8478 function uniqWith(array, comparator) {
8479 comparator = typeof comparator == 'function' ? comparator : undefined;
8480 return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
8484 * This method is like `_.zip` except that it accepts an array of grouped
8485 * elements and creates an array regrouping the elements to their pre-zip
8492 * @param {Array} array The array of grouped elements to process.
8493 * @returns {Array} Returns the new array of regrouped elements.
8496 * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
8497 * // => [['a', 1, true], ['b', 2, false]]
8500 * // => [['a', 'b'], [1, 2], [true, false]]
8502 function unzip(array) {
8503 if (!(array && array.length)) {
8507 array = arrayFilter(array, function(group) {
8508 if (isArrayLikeObject(group)) {
8509 length = nativeMax(group.length, length);
8513 return baseTimes(length, function(index) {
8514 return arrayMap(array, baseProperty(index));
8519 * This method is like `_.unzip` except that it accepts `iteratee` to specify
8520 * how regrouped values should be combined. The iteratee is invoked with the
8521 * elements of each group: (...group).
8527 * @param {Array} array The array of grouped elements to process.
8528 * @param {Function} [iteratee=_.identity] The function to combine
8530 * @returns {Array} Returns the new array of regrouped elements.
8533 * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
8534 * // => [[1, 10, 100], [2, 20, 200]]
8536 * _.unzipWith(zipped, _.add);
8537 * // => [3, 30, 300]
8539 function unzipWith(array, iteratee) {
8540 if (!(array && array.length)) {
8543 var result = unzip(array);
8544 if (iteratee == null) {
8547 return arrayMap(result, function(group) {
8548 return apply(iteratee, undefined, group);
8553 * Creates an array excluding all given values using
8554 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8555 * for equality comparisons.
8557 * **Note:** Unlike `_.pull`, this method returns a new array.
8563 * @param {Array} array The array to inspect.
8564 * @param {...*} [values] The values to exclude.
8565 * @returns {Array} Returns the new array of filtered values.
8566 * @see _.difference, _.xor
8569 * _.without([2, 1, 2, 3], 1, 2);
8572 var without = baseRest(function(array, values) {
8573 return isArrayLikeObject(array)
8574 ? baseDifference(array, values)
8579 * Creates an array of unique values that is the
8580 * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
8581 * of the given arrays. The order of result values is determined by the order
8582 * they occur in the arrays.
8588 * @param {...Array} [arrays] The arrays to inspect.
8589 * @returns {Array} Returns the new array of filtered values.
8590 * @see _.difference, _.without
8593 * _.xor([2, 1], [2, 3]);
8596 var xor = baseRest(function(arrays) {
8597 return baseXor(arrayFilter(arrays, isArrayLikeObject));
8601 * This method is like `_.xor` except that it accepts `iteratee` which is
8602 * invoked for each element of each `arrays` to generate the criterion by
8603 * which by which they're compared. The order of result values is determined
8604 * by the order they occur in the arrays. The iteratee is invoked with one
8605 * argument: (value).
8611 * @param {...Array} [arrays] The arrays to inspect.
8612 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8613 * @returns {Array} Returns the new array of filtered values.
8616 * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8619 * // The `_.property` iteratee shorthand.
8620 * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8621 * // => [{ 'x': 2 }]
8623 var xorBy = baseRest(function(arrays) {
8624 var iteratee = last(arrays);
8625 if (isArrayLikeObject(iteratee)) {
8626 iteratee = undefined;
8628 return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
8632 * This method is like `_.xor` except that it accepts `comparator` which is
8633 * invoked to compare elements of `arrays`. The order of result values is
8634 * determined by the order they occur in the arrays. The comparator is invoked
8635 * with two arguments: (arrVal, othVal).
8641 * @param {...Array} [arrays] The arrays to inspect.
8642 * @param {Function} [comparator] The comparator invoked per element.
8643 * @returns {Array} Returns the new array of filtered values.
8646 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8647 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8649 * _.xorWith(objects, others, _.isEqual);
8650 * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8652 var xorWith = baseRest(function(arrays) {
8653 var comparator = last(arrays);
8654 comparator = typeof comparator == 'function' ? comparator : undefined;
8655 return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
8659 * Creates an array of grouped elements, the first of which contains the
8660 * first elements of the given arrays, the second of which contains the
8661 * second elements of the given arrays, and so on.
8667 * @param {...Array} [arrays] The arrays to process.
8668 * @returns {Array} Returns the new array of grouped elements.
8671 * _.zip(['a', 'b'], [1, 2], [true, false]);
8672 * // => [['a', 1, true], ['b', 2, false]]
8674 var zip = baseRest(unzip);
8677 * This method is like `_.fromPairs` except that it accepts two arrays,
8678 * one of property identifiers and one of corresponding values.
8684 * @param {Array} [props=[]] The property identifiers.
8685 * @param {Array} [values=[]] The property values.
8686 * @returns {Object} Returns the new object.
8689 * _.zipObject(['a', 'b'], [1, 2]);
8690 * // => { 'a': 1, 'b': 2 }
8692 function zipObject(props, values) {
8693 return baseZipObject(props || [], values || [], assignValue);
8697 * This method is like `_.zipObject` except that it supports property paths.
8703 * @param {Array} [props=[]] The property identifiers.
8704 * @param {Array} [values=[]] The property values.
8705 * @returns {Object} Returns the new object.
8708 * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
8709 * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
8711 function zipObjectDeep(props, values) {
8712 return baseZipObject(props || [], values || [], baseSet);
8716 * This method is like `_.zip` except that it accepts `iteratee` to specify
8717 * how grouped values should be combined. The iteratee is invoked with the
8718 * elements of each group: (...group).
8724 * @param {...Array} [arrays] The arrays to process.
8725 * @param {Function} [iteratee=_.identity] The function to combine
8727 * @returns {Array} Returns the new array of grouped elements.
8730 * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
8735 var zipWith = baseRest(function(arrays) {
8736 var length = arrays.length,
8737 iteratee = length > 1 ? arrays[length - 1] : undefined;
8739 iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
8740 return unzipWith(arrays, iteratee);
8743 /*------------------------------------------------------------------------*/
8746 * Creates a `lodash` wrapper instance that wraps `value` with explicit method
8747 * chain sequences enabled. The result of such sequences must be unwrapped
8754 * @param {*} value The value to wrap.
8755 * @returns {Object} Returns the new `lodash` wrapper instance.
8759 * { 'user': 'barney', 'age': 36 },
8760 * { 'user': 'fred', 'age': 40 },
8761 * { 'user': 'pebbles', 'age': 1 }
8767 * .map(function(o) {
8768 * return o.user + ' is ' + o.age;
8772 * // => 'pebbles is 1'
8774 function chain(value) {
8775 var result = lodash(value);
8776 result.__chain__ = true;
8781 * This method invokes `interceptor` and returns `value`. The interceptor
8782 * is invoked with one argument; (value). The purpose of this method is to
8783 * "tap into" a method chain sequence in order to modify intermediate results.
8789 * @param {*} value The value to provide to `interceptor`.
8790 * @param {Function} interceptor The function to invoke.
8791 * @returns {*} Returns `value`.
8795 * .tap(function(array) {
8796 * // Mutate input array.
8803 function tap(value, interceptor) {
8809 * This method is like `_.tap` except that it returns the result of `interceptor`.
8810 * The purpose of this method is to "pass thru" values replacing intermediate
8811 * results in a method chain sequence.
8817 * @param {*} value The value to provide to `interceptor`.
8818 * @param {Function} interceptor The function to invoke.
8819 * @returns {*} Returns the result of `interceptor`.
8825 * .thru(function(value) {
8831 function thru(value, interceptor) {
8832 return interceptor(value);
8836 * This method is the wrapper version of `_.at`.
8842 * @param {...(string|string[])} [paths] The property paths to pick.
8843 * @returns {Object} Returns the new `lodash` wrapper instance.
8846 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
8848 * _(object).at(['a[0].b.c', 'a[1]']).value();
8851 var wrapperAt = flatRest(function(paths) {
8852 var length = paths.length,
8853 start = length ? paths[0] : 0,
8854 value = this.__wrapped__,
8855 interceptor = function(object) { return baseAt(object, paths); };
8857 if (length > 1 || this.__actions__.length ||
8858 !(value instanceof LazyWrapper) || !isIndex(start)) {
8859 return this.thru(interceptor);
8861 value = value.slice(start, +start + (length ? 1 : 0));
8862 value.__actions__.push({
8864 'args': [interceptor],
8865 'thisArg': undefined
8867 return new LodashWrapper(value, this.__chain__).thru(function(array) {
8868 if (length && !array.length) {
8869 array.push(undefined);
8876 * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
8882 * @returns {Object} Returns the new `lodash` wrapper instance.
8886 * { 'user': 'barney', 'age': 36 },
8887 * { 'user': 'fred', 'age': 40 }
8890 * // A sequence without explicit chaining.
8892 * // => { 'user': 'barney', 'age': 36 }
8894 * // A sequence with explicit chaining.
8900 * // => { 'user': 'barney' }
8902 function wrapperChain() {
8907 * Executes the chain sequence and returns the wrapped result.
8913 * @returns {Object} Returns the new `lodash` wrapper instance.
8916 * var array = [1, 2];
8917 * var wrapped = _(array).push(3);
8919 * console.log(array);
8922 * wrapped = wrapped.commit();
8923 * console.log(array);
8929 * console.log(array);
8932 function wrapperCommit() {
8933 return new LodashWrapper(this.value(), this.__chain__);
8937 * Gets the next value on a wrapped object following the
8938 * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8944 * @returns {Object} Returns the next iterator value.
8947 * var wrapped = _([1, 2]);
8950 * // => { 'done': false, 'value': 1 }
8953 * // => { 'done': false, 'value': 2 }
8956 * // => { 'done': true, 'value': undefined }
8958 function wrapperNext() {
8959 if (this.__values__ === undefined) {
8960 this.__values__ = toArray(this.value());
8962 var done = this.__index__ >= this.__values__.length,
8963 value = done ? undefined : this.__values__[this.__index__++];
8965 return { 'done': done, 'value': value };
8969 * Enables the wrapper to be iterable.
8971 * @name Symbol.iterator
8975 * @returns {Object} Returns the wrapper object.
8978 * var wrapped = _([1, 2]);
8980 * wrapped[Symbol.iterator]() === wrapped;
8983 * Array.from(wrapped);
8986 function wrapperToIterator() {
8991 * Creates a clone of the chain sequence planting `value` as the wrapped value.
8997 * @param {*} value The value to plant.
8998 * @returns {Object} Returns the new `lodash` wrapper instance.
9001 * function square(n) {
9005 * var wrapped = _([1, 2]).map(square);
9006 * var other = wrapped.plant([3, 4]);
9014 function wrapperPlant(value) {
9018 while (parent instanceof baseLodash) {
9019 var clone = wrapperClone(parent);
9020 clone.__index__ = 0;
9021 clone.__values__ = undefined;
9023 previous.__wrapped__ = clone;
9027 var previous = clone;
9028 parent = parent.__wrapped__;
9030 previous.__wrapped__ = value;
9035 * This method is the wrapper version of `_.reverse`.
9037 * **Note:** This method mutates the wrapped array.
9043 * @returns {Object} Returns the new `lodash` wrapper instance.
9046 * var array = [1, 2, 3];
9048 * _(array).reverse().value()
9051 * console.log(array);
9054 function wrapperReverse() {
9055 var value = this.__wrapped__;
9056 if (value instanceof LazyWrapper) {
9057 var wrapped = value;
9058 if (this.__actions__.length) {
9059 wrapped = new LazyWrapper(this);
9061 wrapped = wrapped.reverse();
9062 wrapped.__actions__.push({
9065 'thisArg': undefined
9067 return new LodashWrapper(wrapped, this.__chain__);
9069 return this.thru(reverse);
9073 * Executes the chain sequence to resolve the unwrapped value.
9078 * @alias toJSON, valueOf
9080 * @returns {*} Returns the resolved unwrapped value.
9083 * _([1, 2, 3]).value();
9086 function wrapperValue() {
9087 return baseWrapperValue(this.__wrapped__, this.__actions__);
9090 /*------------------------------------------------------------------------*/
9093 * Creates an object composed of keys generated from the results of running
9094 * each element of `collection` thru `iteratee`. The corresponding value of
9095 * each key is the number of times the key was returned by `iteratee`. The
9096 * iteratee is invoked with one argument: (value).
9101 * @category Collection
9102 * @param {Array|Object} collection The collection to iterate over.
9103 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9104 * @returns {Object} Returns the composed aggregate object.
9107 * _.countBy([6.1, 4.2, 6.3], Math.floor);
9108 * // => { '4': 1, '6': 2 }
9110 * // The `_.property` iteratee shorthand.
9111 * _.countBy(['one', 'two', 'three'], 'length');
9112 * // => { '3': 2, '5': 1 }
9114 var countBy = createAggregator(function(result, value, key) {
9115 if (hasOwnProperty.call(result, key)) {
9118 baseAssignValue(result, key, 1);
9123 * Checks if `predicate` returns truthy for **all** elements of `collection`.
9124 * Iteration is stopped once `predicate` returns falsey. The predicate is
9125 * invoked with three arguments: (value, index|key, collection).
9127 * **Note:** This method returns `true` for
9128 * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
9129 * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
9130 * elements of empty collections.
9135 * @category Collection
9136 * @param {Array|Object} collection The collection to iterate over.
9137 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9138 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9139 * @returns {boolean} Returns `true` if all elements pass the predicate check,
9143 * _.every([true, 1, null, 'yes'], Boolean);
9147 * { 'user': 'barney', 'age': 36, 'active': false },
9148 * { 'user': 'fred', 'age': 40, 'active': false }
9151 * // The `_.matches` iteratee shorthand.
9152 * _.every(users, { 'user': 'barney', 'active': false });
9155 * // The `_.matchesProperty` iteratee shorthand.
9156 * _.every(users, ['active', false]);
9159 * // The `_.property` iteratee shorthand.
9160 * _.every(users, 'active');
9163 function every(collection, predicate, guard) {
9164 var func = isArray(collection) ? arrayEvery : baseEvery;
9165 if (guard && isIterateeCall(collection, predicate, guard)) {
9166 predicate = undefined;
9168 return func(collection, getIteratee(predicate, 3));
9172 * Iterates over elements of `collection`, returning an array of all elements
9173 * `predicate` returns truthy for. The predicate is invoked with three
9174 * arguments: (value, index|key, collection).
9176 * **Note:** Unlike `_.remove`, this method returns a new array.
9181 * @category Collection
9182 * @param {Array|Object} collection The collection to iterate over.
9183 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9184 * @returns {Array} Returns the new filtered array.
9189 * { 'user': 'barney', 'age': 36, 'active': true },
9190 * { 'user': 'fred', 'age': 40, 'active': false }
9193 * _.filter(users, function(o) { return !o.active; });
9194 * // => objects for ['fred']
9196 * // The `_.matches` iteratee shorthand.
9197 * _.filter(users, { 'age': 36, 'active': true });
9198 * // => objects for ['barney']
9200 * // The `_.matchesProperty` iteratee shorthand.
9201 * _.filter(users, ['active', false]);
9202 * // => objects for ['fred']
9204 * // The `_.property` iteratee shorthand.
9205 * _.filter(users, 'active');
9206 * // => objects for ['barney']
9208 function filter(collection, predicate) {
9209 var func = isArray(collection) ? arrayFilter : baseFilter;
9210 return func(collection, getIteratee(predicate, 3));
9214 * Iterates over elements of `collection`, returning the first element
9215 * `predicate` returns truthy for. The predicate is invoked with three
9216 * arguments: (value, index|key, collection).
9221 * @category Collection
9222 * @param {Array|Object} collection The collection to inspect.
9223 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9224 * @param {number} [fromIndex=0] The index to search from.
9225 * @returns {*} Returns the matched element, else `undefined`.
9229 * { 'user': 'barney', 'age': 36, 'active': true },
9230 * { 'user': 'fred', 'age': 40, 'active': false },
9231 * { 'user': 'pebbles', 'age': 1, 'active': true }
9234 * _.find(users, function(o) { return o.age < 40; });
9235 * // => object for 'barney'
9237 * // The `_.matches` iteratee shorthand.
9238 * _.find(users, { 'age': 1, 'active': true });
9239 * // => object for 'pebbles'
9241 * // The `_.matchesProperty` iteratee shorthand.
9242 * _.find(users, ['active', false]);
9243 * // => object for 'fred'
9245 * // The `_.property` iteratee shorthand.
9246 * _.find(users, 'active');
9247 * // => object for 'barney'
9249 var find = createFind(findIndex);
9252 * This method is like `_.find` except that it iterates over elements of
9253 * `collection` from right to left.
9258 * @category Collection
9259 * @param {Array|Object} collection The collection to inspect.
9260 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9261 * @param {number} [fromIndex=collection.length-1] The index to search from.
9262 * @returns {*} Returns the matched element, else `undefined`.
9265 * _.findLast([1, 2, 3, 4], function(n) {
9266 * return n % 2 == 1;
9270 var findLast = createFind(findLastIndex);
9273 * Creates a flattened array of values by running each element in `collection`
9274 * thru `iteratee` and flattening the mapped results. The iteratee is invoked
9275 * with three arguments: (value, index|key, collection).
9280 * @category Collection
9281 * @param {Array|Object} collection The collection to iterate over.
9282 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9283 * @returns {Array} Returns the new flattened array.
9286 * function duplicate(n) {
9290 * _.flatMap([1, 2], duplicate);
9291 * // => [1, 1, 2, 2]
9293 function flatMap(collection, iteratee) {
9294 return baseFlatten(map(collection, iteratee), 1);
9298 * This method is like `_.flatMap` except that it recursively flattens the
9304 * @category Collection
9305 * @param {Array|Object} collection The collection to iterate over.
9306 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9307 * @returns {Array} Returns the new flattened array.
9310 * function duplicate(n) {
9311 * return [[[n, n]]];
9314 * _.flatMapDeep([1, 2], duplicate);
9315 * // => [1, 1, 2, 2]
9317 function flatMapDeep(collection, iteratee) {
9318 return baseFlatten(map(collection, iteratee), INFINITY);
9322 * This method is like `_.flatMap` except that it recursively flattens the
9323 * mapped results up to `depth` times.
9328 * @category Collection
9329 * @param {Array|Object} collection The collection to iterate over.
9330 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9331 * @param {number} [depth=1] The maximum recursion depth.
9332 * @returns {Array} Returns the new flattened array.
9335 * function duplicate(n) {
9336 * return [[[n, n]]];
9339 * _.flatMapDepth([1, 2], duplicate, 2);
9340 * // => [[1, 1], [2, 2]]
9342 function flatMapDepth(collection, iteratee, depth) {
9343 depth = depth === undefined ? 1 : toInteger(depth);
9344 return baseFlatten(map(collection, iteratee), depth);
9348 * Iterates over elements of `collection` and invokes `iteratee` for each element.
9349 * The iteratee is invoked with three arguments: (value, index|key, collection).
9350 * Iteratee functions may exit iteration early by explicitly returning `false`.
9352 * **Note:** As with other "Collections" methods, objects with a "length"
9353 * property are iterated like arrays. To avoid this behavior use `_.forIn`
9354 * or `_.forOwn` for object iteration.
9360 * @category Collection
9361 * @param {Array|Object} collection The collection to iterate over.
9362 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9363 * @returns {Array|Object} Returns `collection`.
9364 * @see _.forEachRight
9367 * _.forEach([1, 2], function(value) {
9368 * console.log(value);
9370 * // => Logs `1` then `2`.
9372 * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
9375 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
9377 function forEach(collection, iteratee) {
9378 var func = isArray(collection) ? arrayEach : baseEach;
9379 return func(collection, getIteratee(iteratee, 3));
9383 * This method is like `_.forEach` except that it iterates over elements of
9384 * `collection` from right to left.
9390 * @category Collection
9391 * @param {Array|Object} collection The collection to iterate over.
9392 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9393 * @returns {Array|Object} Returns `collection`.
9397 * _.forEachRight([1, 2], function(value) {
9398 * console.log(value);
9400 * // => Logs `2` then `1`.
9402 function forEachRight(collection, iteratee) {
9403 var func = isArray(collection) ? arrayEachRight : baseEachRight;
9404 return func(collection, getIteratee(iteratee, 3));
9408 * Creates an object composed of keys generated from the results of running
9409 * each element of `collection` thru `iteratee`. The order of grouped values
9410 * is determined by the order they occur in `collection`. The corresponding
9411 * value of each key is an array of elements responsible for generating the
9412 * key. The iteratee is invoked with one argument: (value).
9417 * @category Collection
9418 * @param {Array|Object} collection The collection to iterate over.
9419 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9420 * @returns {Object} Returns the composed aggregate object.
9423 * _.groupBy([6.1, 4.2, 6.3], Math.floor);
9424 * // => { '4': [4.2], '6': [6.1, 6.3] }
9426 * // The `_.property` iteratee shorthand.
9427 * _.groupBy(['one', 'two', 'three'], 'length');
9428 * // => { '3': ['one', 'two'], '5': ['three'] }
9430 var groupBy = createAggregator(function(result, value, key) {
9431 if (hasOwnProperty.call(result, key)) {
9432 result[key].push(value);
9434 baseAssignValue(result, key, [value]);
9439 * Checks if `value` is in `collection`. If `collection` is a string, it's
9440 * checked for a substring of `value`, otherwise
9441 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9442 * is used for equality comparisons. If `fromIndex` is negative, it's used as
9443 * the offset from the end of `collection`.
9448 * @category Collection
9449 * @param {Array|Object|string} collection The collection to inspect.
9450 * @param {*} value The value to search for.
9451 * @param {number} [fromIndex=0] The index to search from.
9452 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9453 * @returns {boolean} Returns `true` if `value` is found, else `false`.
9456 * _.includes([1, 2, 3], 1);
9459 * _.includes([1, 2, 3], 1, 2);
9462 * _.includes({ 'a': 1, 'b': 2 }, 1);
9465 * _.includes('abcd', 'bc');
9468 function includes(collection, value, fromIndex, guard) {
9469 collection = isArrayLike(collection) ? collection : values(collection);
9470 fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
9472 var length = collection.length;
9473 if (fromIndex < 0) {
9474 fromIndex = nativeMax(length + fromIndex, 0);
9476 return isString(collection)
9477 ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
9478 : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
9482 * Invokes the method at `path` of each element in `collection`, returning
9483 * an array of the results of each invoked method. Any additional arguments
9484 * are provided to each invoked method. If `path` is a function, it's invoked
9485 * for, and `this` bound to, each element in `collection`.
9490 * @category Collection
9491 * @param {Array|Object} collection The collection to iterate over.
9492 * @param {Array|Function|string} path The path of the method to invoke or
9493 * the function invoked per iteration.
9494 * @param {...*} [args] The arguments to invoke each method with.
9495 * @returns {Array} Returns the array of results.
9498 * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
9499 * // => [[1, 5, 7], [1, 2, 3]]
9501 * _.invokeMap([123, 456], String.prototype.split, '');
9502 * // => [['1', '2', '3'], ['4', '5', '6']]
9504 var invokeMap = baseRest(function(collection, path, args) {
9506 isFunc = typeof path == 'function',
9507 result = isArrayLike(collection) ? Array(collection.length) : [];
9509 baseEach(collection, function(value) {
9510 result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
9516 * Creates an object composed of keys generated from the results of running
9517 * each element of `collection` thru `iteratee`. The corresponding value of
9518 * each key is the last element responsible for generating the key. The
9519 * iteratee is invoked with one argument: (value).
9524 * @category Collection
9525 * @param {Array|Object} collection The collection to iterate over.
9526 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9527 * @returns {Object} Returns the composed aggregate object.
9531 * { 'dir': 'left', 'code': 97 },
9532 * { 'dir': 'right', 'code': 100 }
9535 * _.keyBy(array, function(o) {
9536 * return String.fromCharCode(o.code);
9538 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
9540 * _.keyBy(array, 'dir');
9541 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
9543 var keyBy = createAggregator(function(result, value, key) {
9544 baseAssignValue(result, key, value);
9548 * Creates an array of values by running each element in `collection` thru
9549 * `iteratee`. The iteratee is invoked with three arguments:
9550 * (value, index|key, collection).
9552 * Many lodash methods are guarded to work as iteratees for methods like
9553 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
9555 * The guarded methods are:
9556 * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
9557 * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
9558 * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
9559 * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
9564 * @category Collection
9565 * @param {Array|Object} collection The collection to iterate over.
9566 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9567 * @returns {Array} Returns the new mapped array.
9570 * function square(n) {
9574 * _.map([4, 8], square);
9577 * _.map({ 'a': 4, 'b': 8 }, square);
9578 * // => [16, 64] (iteration order is not guaranteed)
9581 * { 'user': 'barney' },
9582 * { 'user': 'fred' }
9585 * // The `_.property` iteratee shorthand.
9586 * _.map(users, 'user');
9587 * // => ['barney', 'fred']
9589 function map(collection, iteratee) {
9590 var func = isArray(collection) ? arrayMap : baseMap;
9591 return func(collection, getIteratee(iteratee, 3));
9595 * This method is like `_.sortBy` except that it allows specifying the sort
9596 * orders of the iteratees to sort by. If `orders` is unspecified, all values
9597 * are sorted in ascending order. Otherwise, specify an order of "desc" for
9598 * descending or "asc" for ascending sort order of corresponding values.
9603 * @category Collection
9604 * @param {Array|Object} collection The collection to iterate over.
9605 * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
9606 * The iteratees to sort by.
9607 * @param {string[]} [orders] The sort orders of `iteratees`.
9608 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9609 * @returns {Array} Returns the new sorted array.
9613 * { 'user': 'fred', 'age': 48 },
9614 * { 'user': 'barney', 'age': 34 },
9615 * { 'user': 'fred', 'age': 40 },
9616 * { 'user': 'barney', 'age': 36 }
9619 * // Sort by `user` in ascending order and by `age` in descending order.
9620 * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
9621 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9623 function orderBy(collection, iteratees, orders, guard) {
9624 if (collection == null) {
9627 if (!isArray(iteratees)) {
9628 iteratees = iteratees == null ? [] : [iteratees];
9630 orders = guard ? undefined : orders;
9631 if (!isArray(orders)) {
9632 orders = orders == null ? [] : [orders];
9634 return baseOrderBy(collection, iteratees, orders);
9638 * Creates an array of elements split into two groups, the first of which
9639 * contains elements `predicate` returns truthy for, the second of which
9640 * contains elements `predicate` returns falsey for. The predicate is
9641 * invoked with one argument: (value).
9646 * @category Collection
9647 * @param {Array|Object} collection The collection to iterate over.
9648 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9649 * @returns {Array} Returns the array of grouped elements.
9653 * { 'user': 'barney', 'age': 36, 'active': false },
9654 * { 'user': 'fred', 'age': 40, 'active': true },
9655 * { 'user': 'pebbles', 'age': 1, 'active': false }
9658 * _.partition(users, function(o) { return o.active; });
9659 * // => objects for [['fred'], ['barney', 'pebbles']]
9661 * // The `_.matches` iteratee shorthand.
9662 * _.partition(users, { 'age': 1, 'active': false });
9663 * // => objects for [['pebbles'], ['barney', 'fred']]
9665 * // The `_.matchesProperty` iteratee shorthand.
9666 * _.partition(users, ['active', false]);
9667 * // => objects for [['barney', 'pebbles'], ['fred']]
9669 * // The `_.property` iteratee shorthand.
9670 * _.partition(users, 'active');
9671 * // => objects for [['fred'], ['barney', 'pebbles']]
9673 var partition = createAggregator(function(result, value, key) {
9674 result[key ? 0 : 1].push(value);
9675 }, function() { return [[], []]; });
9678 * Reduces `collection` to a value which is the accumulated result of running
9679 * each element in `collection` thru `iteratee`, where each successive
9680 * invocation is supplied the return value of the previous. If `accumulator`
9681 * is not given, the first element of `collection` is used as the initial
9682 * value. The iteratee is invoked with four arguments:
9683 * (accumulator, value, index|key, collection).
9685 * Many lodash methods are guarded to work as iteratees for methods like
9686 * `_.reduce`, `_.reduceRight`, and `_.transform`.
9688 * The guarded methods are:
9689 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
9695 * @category Collection
9696 * @param {Array|Object} collection The collection to iterate over.
9697 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9698 * @param {*} [accumulator] The initial value.
9699 * @returns {*} Returns the accumulated value.
9700 * @see _.reduceRight
9703 * _.reduce([1, 2], function(sum, n) {
9708 * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
9709 * (result[value] || (result[value] = [])).push(key);
9712 * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
9714 function reduce(collection, iteratee, accumulator) {
9715 var func = isArray(collection) ? arrayReduce : baseReduce,
9716 initAccum = arguments.length < 3;
9718 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
9722 * This method is like `_.reduce` except that it iterates over elements of
9723 * `collection` from right to left.
9728 * @category Collection
9729 * @param {Array|Object} collection The collection to iterate over.
9730 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9731 * @param {*} [accumulator] The initial value.
9732 * @returns {*} Returns the accumulated value.
9736 * var array = [[0, 1], [2, 3], [4, 5]];
9738 * _.reduceRight(array, function(flattened, other) {
9739 * return flattened.concat(other);
9741 * // => [4, 5, 2, 3, 0, 1]
9743 function reduceRight(collection, iteratee, accumulator) {
9744 var func = isArray(collection) ? arrayReduceRight : baseReduce,
9745 initAccum = arguments.length < 3;
9747 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
9751 * The opposite of `_.filter`; this method returns the elements of `collection`
9752 * that `predicate` does **not** return truthy for.
9757 * @category Collection
9758 * @param {Array|Object} collection The collection to iterate over.
9759 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9760 * @returns {Array} Returns the new filtered array.
9765 * { 'user': 'barney', 'age': 36, 'active': false },
9766 * { 'user': 'fred', 'age': 40, 'active': true }
9769 * _.reject(users, function(o) { return !o.active; });
9770 * // => objects for ['fred']
9772 * // The `_.matches` iteratee shorthand.
9773 * _.reject(users, { 'age': 40, 'active': true });
9774 * // => objects for ['barney']
9776 * // The `_.matchesProperty` iteratee shorthand.
9777 * _.reject(users, ['active', false]);
9778 * // => objects for ['fred']
9780 * // The `_.property` iteratee shorthand.
9781 * _.reject(users, 'active');
9782 * // => objects for ['barney']
9784 function reject(collection, predicate) {
9785 var func = isArray(collection) ? arrayFilter : baseFilter;
9786 return func(collection, negate(getIteratee(predicate, 3)));
9790 * Gets a random element from `collection`.
9795 * @category Collection
9796 * @param {Array|Object} collection The collection to sample.
9797 * @returns {*} Returns the random element.
9800 * _.sample([1, 2, 3, 4]);
9803 function sample(collection) {
9804 var func = isArray(collection) ? arraySample : baseSample;
9805 return func(collection);
9809 * Gets `n` random elements at unique keys from `collection` up to the
9810 * size of `collection`.
9815 * @category Collection
9816 * @param {Array|Object} collection The collection to sample.
9817 * @param {number} [n=1] The number of elements to sample.
9818 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9819 * @returns {Array} Returns the random elements.
9822 * _.sampleSize([1, 2, 3], 2);
9825 * _.sampleSize([1, 2, 3], 4);
9828 function sampleSize(collection, n, guard) {
9829 if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
9834 var func = isArray(collection) ? arraySampleSize : baseSampleSize;
9835 return func(collection, n);
9839 * Creates an array of shuffled values, using a version of the
9840 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
9845 * @category Collection
9846 * @param {Array|Object} collection The collection to shuffle.
9847 * @returns {Array} Returns the new shuffled array.
9850 * _.shuffle([1, 2, 3, 4]);
9851 * // => [4, 1, 3, 2]
9853 function shuffle(collection) {
9854 var func = isArray(collection) ? arrayShuffle : baseShuffle;
9855 return func(collection);
9859 * Gets the size of `collection` by returning its length for array-like
9860 * values or the number of own enumerable string keyed properties for objects.
9865 * @category Collection
9866 * @param {Array|Object|string} collection The collection to inspect.
9867 * @returns {number} Returns the collection size.
9870 * _.size([1, 2, 3]);
9873 * _.size({ 'a': 1, 'b': 2 });
9876 * _.size('pebbles');
9879 function size(collection) {
9880 if (collection == null) {
9883 if (isArrayLike(collection)) {
9884 return isString(collection) ? stringSize(collection) : collection.length;
9886 var tag = getTag(collection);
9887 if (tag == mapTag || tag == setTag) {
9888 return collection.size;
9890 return baseKeys(collection).length;
9894 * Checks if `predicate` returns truthy for **any** element of `collection`.
9895 * Iteration is stopped once `predicate` returns truthy. The predicate is
9896 * invoked with three arguments: (value, index|key, collection).
9901 * @category Collection
9902 * @param {Array|Object} collection The collection to iterate over.
9903 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9904 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9905 * @returns {boolean} Returns `true` if any element passes the predicate check,
9909 * _.some([null, 0, 'yes', false], Boolean);
9913 * { 'user': 'barney', 'active': true },
9914 * { 'user': 'fred', 'active': false }
9917 * // The `_.matches` iteratee shorthand.
9918 * _.some(users, { 'user': 'barney', 'active': false });
9921 * // The `_.matchesProperty` iteratee shorthand.
9922 * _.some(users, ['active', false]);
9925 * // The `_.property` iteratee shorthand.
9926 * _.some(users, 'active');
9929 function some(collection, predicate, guard) {
9930 var func = isArray(collection) ? arraySome : baseSome;
9931 if (guard && isIterateeCall(collection, predicate, guard)) {
9932 predicate = undefined;
9934 return func(collection, getIteratee(predicate, 3));
9938 * Creates an array of elements, sorted in ascending order by the results of
9939 * running each element in a collection thru each iteratee. This method
9940 * performs a stable sort, that is, it preserves the original sort order of
9941 * equal elements. The iteratees are invoked with one argument: (value).
9946 * @category Collection
9947 * @param {Array|Object} collection The collection to iterate over.
9948 * @param {...(Function|Function[])} [iteratees=[_.identity]]
9949 * The iteratees to sort by.
9950 * @returns {Array} Returns the new sorted array.
9954 * { 'user': 'fred', 'age': 48 },
9955 * { 'user': 'barney', 'age': 36 },
9956 * { 'user': 'fred', 'age': 40 },
9957 * { 'user': 'barney', 'age': 34 }
9960 * _.sortBy(users, [function(o) { return o.user; }]);
9961 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9963 * _.sortBy(users, ['user', 'age']);
9964 * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
9966 var sortBy = baseRest(function(collection, iteratees) {
9967 if (collection == null) {
9970 var length = iteratees.length;
9971 if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
9973 } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
9974 iteratees = [iteratees[0]];
9976 return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
9979 /*------------------------------------------------------------------------*/
9982 * Gets the timestamp of the number of milliseconds that have elapsed since
9983 * the Unix epoch (1 January 1970 00:00:00 UTC).
9989 * @returns {number} Returns the timestamp.
9992 * _.defer(function(stamp) {
9993 * console.log(_.now() - stamp);
9995 * // => Logs the number of milliseconds it took for the deferred invocation.
9997 var now = ctxNow || function() {
9998 return root.Date.now();
10001 /*------------------------------------------------------------------------*/
10004 * The opposite of `_.before`; this method creates a function that invokes
10005 * `func` once it's called `n` or more times.
10010 * @category Function
10011 * @param {number} n The number of calls before `func` is invoked.
10012 * @param {Function} func The function to restrict.
10013 * @returns {Function} Returns the new restricted function.
10016 * var saves = ['profile', 'settings'];
10018 * var done = _.after(saves.length, function() {
10019 * console.log('done saving!');
10022 * _.forEach(saves, function(type) {
10023 * asyncSave({ 'type': type, 'complete': done });
10025 * // => Logs 'done saving!' after the two async saves have completed.
10027 function after(n, func) {
10028 if (typeof func != 'function') {
10029 throw new TypeError(FUNC_ERROR_TEXT);
10032 return function() {
10034 return func.apply(this, arguments);
10040 * Creates a function that invokes `func`, with up to `n` arguments,
10041 * ignoring any additional arguments.
10046 * @category Function
10047 * @param {Function} func The function to cap arguments for.
10048 * @param {number} [n=func.length] The arity cap.
10049 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10050 * @returns {Function} Returns the new capped function.
10053 * _.map(['6', '8', '10'], _.ary(parseInt, 1));
10056 function ary(func, n, guard) {
10057 n = guard ? undefined : n;
10058 n = (func && n == null) ? func.length : n;
10059 return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
10063 * Creates a function that invokes `func`, with the `this` binding and arguments
10064 * of the created function, while it's called less than `n` times. Subsequent
10065 * calls to the created function return the result of the last `func` invocation.
10070 * @category Function
10071 * @param {number} n The number of calls at which `func` is no longer invoked.
10072 * @param {Function} func The function to restrict.
10073 * @returns {Function} Returns the new restricted function.
10076 * jQuery(element).on('click', _.before(5, addContactToList));
10077 * // => Allows adding up to 4 contacts to the list.
10079 function before(n, func) {
10081 if (typeof func != 'function') {
10082 throw new TypeError(FUNC_ERROR_TEXT);
10085 return function() {
10087 result = func.apply(this, arguments);
10097 * Creates a function that invokes `func` with the `this` binding of `thisArg`
10098 * and `partials` prepended to the arguments it receives.
10100 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
10101 * may be used as a placeholder for partially applied arguments.
10103 * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
10104 * property of bound functions.
10109 * @category Function
10110 * @param {Function} func The function to bind.
10111 * @param {*} thisArg The `this` binding of `func`.
10112 * @param {...*} [partials] The arguments to be partially applied.
10113 * @returns {Function} Returns the new bound function.
10116 * function greet(greeting, punctuation) {
10117 * return greeting + ' ' + this.user + punctuation;
10120 * var object = { 'user': 'fred' };
10122 * var bound = _.bind(greet, object, 'hi');
10126 * // Bound with placeholders.
10127 * var bound = _.bind(greet, object, _, '!');
10131 var bind = baseRest(function(func, thisArg, partials) {
10132 var bitmask = WRAP_BIND_FLAG;
10133 if (partials.length) {
10134 var holders = replaceHolders(partials, getHolder(bind));
10135 bitmask |= WRAP_PARTIAL_FLAG;
10137 return createWrap(func, bitmask, thisArg, partials, holders);
10141 * Creates a function that invokes the method at `object[key]` with `partials`
10142 * prepended to the arguments it receives.
10144 * This method differs from `_.bind` by allowing bound functions to reference
10145 * methods that may be redefined or don't yet exist. See
10146 * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
10147 * for more details.
10149 * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
10150 * builds, may be used as a placeholder for partially applied arguments.
10155 * @category Function
10156 * @param {Object} object The object to invoke the method on.
10157 * @param {string} key The key of the method.
10158 * @param {...*} [partials] The arguments to be partially applied.
10159 * @returns {Function} Returns the new bound function.
10164 * 'greet': function(greeting, punctuation) {
10165 * return greeting + ' ' + this.user + punctuation;
10169 * var bound = _.bindKey(object, 'greet', 'hi');
10173 * object.greet = function(greeting, punctuation) {
10174 * return greeting + 'ya ' + this.user + punctuation;
10178 * // => 'hiya fred!'
10180 * // Bound with placeholders.
10181 * var bound = _.bindKey(object, 'greet', _, '!');
10183 * // => 'hiya fred!'
10185 var bindKey = baseRest(function(object, key, partials) {
10186 var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
10187 if (partials.length) {
10188 var holders = replaceHolders(partials, getHolder(bindKey));
10189 bitmask |= WRAP_PARTIAL_FLAG;
10191 return createWrap(key, bitmask, object, partials, holders);
10195 * Creates a function that accepts arguments of `func` and either invokes
10196 * `func` returning its result, if at least `arity` number of arguments have
10197 * been provided, or returns a function that accepts the remaining `func`
10198 * arguments, and so on. The arity of `func` may be specified if `func.length`
10199 * is not sufficient.
10201 * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
10202 * may be used as a placeholder for provided arguments.
10204 * **Note:** This method doesn't set the "length" property of curried functions.
10209 * @category Function
10210 * @param {Function} func The function to curry.
10211 * @param {number} [arity=func.length] The arity of `func`.
10212 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10213 * @returns {Function} Returns the new curried function.
10216 * var abc = function(a, b, c) {
10217 * return [a, b, c];
10220 * var curried = _.curry(abc);
10222 * curried(1)(2)(3);
10225 * curried(1, 2)(3);
10228 * curried(1, 2, 3);
10231 * // Curried with placeholders.
10232 * curried(1)(_, 3)(2);
10235 function curry(func, arity, guard) {
10236 arity = guard ? undefined : arity;
10237 var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10238 result.placeholder = curry.placeholder;
10243 * This method is like `_.curry` except that arguments are applied to `func`
10244 * in the manner of `_.partialRight` instead of `_.partial`.
10246 * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
10247 * builds, may be used as a placeholder for provided arguments.
10249 * **Note:** This method doesn't set the "length" property of curried functions.
10254 * @category Function
10255 * @param {Function} func The function to curry.
10256 * @param {number} [arity=func.length] The arity of `func`.
10257 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10258 * @returns {Function} Returns the new curried function.
10261 * var abc = function(a, b, c) {
10262 * return [a, b, c];
10265 * var curried = _.curryRight(abc);
10267 * curried(3)(2)(1);
10270 * curried(2, 3)(1);
10273 * curried(1, 2, 3);
10276 * // Curried with placeholders.
10277 * curried(3)(1, _)(2);
10280 function curryRight(func, arity, guard) {
10281 arity = guard ? undefined : arity;
10282 var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10283 result.placeholder = curryRight.placeholder;
10288 * Creates a debounced function that delays invoking `func` until after `wait`
10289 * milliseconds have elapsed since the last time the debounced function was
10290 * invoked. The debounced function comes with a `cancel` method to cancel
10291 * delayed `func` invocations and a `flush` method to immediately invoke them.
10292 * Provide `options` to indicate whether `func` should be invoked on the
10293 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
10294 * with the last arguments provided to the debounced function. Subsequent
10295 * calls to the debounced function return the result of the last `func`
10298 * **Note:** If `leading` and `trailing` options are `true`, `func` is
10299 * invoked on the trailing edge of the timeout only if the debounced function
10300 * is invoked more than once during the `wait` timeout.
10302 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10303 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10305 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10306 * for details over the differences between `_.debounce` and `_.throttle`.
10311 * @category Function
10312 * @param {Function} func The function to debounce.
10313 * @param {number} [wait=0] The number of milliseconds to delay.
10314 * @param {Object} [options={}] The options object.
10315 * @param {boolean} [options.leading=false]
10316 * Specify invoking on the leading edge of the timeout.
10317 * @param {number} [options.maxWait]
10318 * The maximum time `func` is allowed to be delayed before it's invoked.
10319 * @param {boolean} [options.trailing=true]
10320 * Specify invoking on the trailing edge of the timeout.
10321 * @returns {Function} Returns the new debounced function.
10324 * // Avoid costly calculations while the window size is in flux.
10325 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
10327 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
10328 * jQuery(element).on('click', _.debounce(sendMail, 300, {
10330 * 'trailing': false
10333 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
10334 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
10335 * var source = new EventSource('/stream');
10336 * jQuery(source).on('message', debounced);
10338 * // Cancel the trailing debounced invocation.
10339 * jQuery(window).on('popstate', debounced.cancel);
10341 function debounce(func, wait, options) {
10348 lastInvokeTime = 0,
10353 if (typeof func != 'function') {
10354 throw new TypeError(FUNC_ERROR_TEXT);
10356 wait = toNumber(wait) || 0;
10357 if (isObject(options)) {
10358 leading = !!options.leading;
10359 maxing = 'maxWait' in options;
10360 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
10361 trailing = 'trailing' in options ? !!options.trailing : trailing;
10364 function invokeFunc(time) {
10365 var args = lastArgs,
10366 thisArg = lastThis;
10368 lastArgs = lastThis = undefined;
10369 lastInvokeTime = time;
10370 result = func.apply(thisArg, args);
10374 function leadingEdge(time) {
10375 // Reset any `maxWait` timer.
10376 lastInvokeTime = time;
10377 // Start the timer for the trailing edge.
10378 timerId = setTimeout(timerExpired, wait);
10379 // Invoke the leading edge.
10380 return leading ? invokeFunc(time) : result;
10383 function remainingWait(time) {
10384 var timeSinceLastCall = time - lastCallTime,
10385 timeSinceLastInvoke = time - lastInvokeTime,
10386 result = wait - timeSinceLastCall;
10388 return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
10391 function shouldInvoke(time) {
10392 var timeSinceLastCall = time - lastCallTime,
10393 timeSinceLastInvoke = time - lastInvokeTime;
10395 // Either this is the first call, activity has stopped and we're at the
10396 // trailing edge, the system time has gone backwards and we're treating
10397 // it as the trailing edge, or we've hit the `maxWait` limit.
10398 return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
10399 (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
10402 function timerExpired() {
10404 if (shouldInvoke(time)) {
10405 return trailingEdge(time);
10407 // Restart the timer.
10408 timerId = setTimeout(timerExpired, remainingWait(time));
10411 function trailingEdge(time) {
10412 timerId = undefined;
10414 // Only invoke if we have `lastArgs` which means `func` has been
10415 // debounced at least once.
10416 if (trailing && lastArgs) {
10417 return invokeFunc(time);
10419 lastArgs = lastThis = undefined;
10423 function cancel() {
10424 if (timerId !== undefined) {
10425 clearTimeout(timerId);
10427 lastInvokeTime = 0;
10428 lastArgs = lastCallTime = lastThis = timerId = undefined;
10432 return timerId === undefined ? result : trailingEdge(now());
10435 function debounced() {
10437 isInvoking = shouldInvoke(time);
10439 lastArgs = arguments;
10441 lastCallTime = time;
10444 if (timerId === undefined) {
10445 return leadingEdge(lastCallTime);
10448 // Handle invocations in a tight loop.
10449 timerId = setTimeout(timerExpired, wait);
10450 return invokeFunc(lastCallTime);
10453 if (timerId === undefined) {
10454 timerId = setTimeout(timerExpired, wait);
10458 debounced.cancel = cancel;
10459 debounced.flush = flush;
10464 * Defers invoking the `func` until the current call stack has cleared. Any
10465 * additional arguments are provided to `func` when it's invoked.
10470 * @category Function
10471 * @param {Function} func The function to defer.
10472 * @param {...*} [args] The arguments to invoke `func` with.
10473 * @returns {number} Returns the timer id.
10476 * _.defer(function(text) {
10477 * console.log(text);
10479 * // => Logs 'deferred' after one millisecond.
10481 var defer = baseRest(function(func, args) {
10482 return baseDelay(func, 1, args);
10486 * Invokes `func` after `wait` milliseconds. Any additional arguments are
10487 * provided to `func` when it's invoked.
10492 * @category Function
10493 * @param {Function} func The function to delay.
10494 * @param {number} wait The number of milliseconds to delay invocation.
10495 * @param {...*} [args] The arguments to invoke `func` with.
10496 * @returns {number} Returns the timer id.
10499 * _.delay(function(text) {
10500 * console.log(text);
10501 * }, 1000, 'later');
10502 * // => Logs 'later' after one second.
10504 var delay = baseRest(function(func, wait, args) {
10505 return baseDelay(func, toNumber(wait) || 0, args);
10509 * Creates a function that invokes `func` with arguments reversed.
10514 * @category Function
10515 * @param {Function} func The function to flip arguments for.
10516 * @returns {Function} Returns the new flipped function.
10519 * var flipped = _.flip(function() {
10520 * return _.toArray(arguments);
10523 * flipped('a', 'b', 'c', 'd');
10524 * // => ['d', 'c', 'b', 'a']
10526 function flip(func) {
10527 return createWrap(func, WRAP_FLIP_FLAG);
10531 * Creates a function that memoizes the result of `func`. If `resolver` is
10532 * provided, it determines the cache key for storing the result based on the
10533 * arguments provided to the memoized function. By default, the first argument
10534 * provided to the memoized function is used as the map cache key. The `func`
10535 * is invoked with the `this` binding of the memoized function.
10537 * **Note:** The cache is exposed as the `cache` property on the memoized
10538 * function. Its creation may be customized by replacing the `_.memoize.Cache`
10539 * constructor with one whose instances implement the
10540 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
10541 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
10546 * @category Function
10547 * @param {Function} func The function to have its output memoized.
10548 * @param {Function} [resolver] The function to resolve the cache key.
10549 * @returns {Function} Returns the new memoized function.
10552 * var object = { 'a': 1, 'b': 2 };
10553 * var other = { 'c': 3, 'd': 4 };
10555 * var values = _.memoize(_.values);
10566 * // Modify the result cache.
10567 * values.cache.set(object, ['a', 'b']);
10571 * // Replace `_.memoize.Cache`.
10572 * _.memoize.Cache = WeakMap;
10574 function memoize(func, resolver) {
10575 if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
10576 throw new TypeError(FUNC_ERROR_TEXT);
10578 var memoized = function() {
10579 var args = arguments,
10580 key = resolver ? resolver.apply(this, args) : args[0],
10581 cache = memoized.cache;
10583 if (cache.has(key)) {
10584 return cache.get(key);
10586 var result = func.apply(this, args);
10587 memoized.cache = cache.set(key, result) || cache;
10590 memoized.cache = new (memoize.Cache || MapCache);
10594 // Expose `MapCache`.
10595 memoize.Cache = MapCache;
10598 * Creates a function that negates the result of the predicate `func`. The
10599 * `func` predicate is invoked with the `this` binding and arguments of the
10600 * created function.
10605 * @category Function
10606 * @param {Function} predicate The predicate to negate.
10607 * @returns {Function} Returns the new negated function.
10610 * function isEven(n) {
10611 * return n % 2 == 0;
10614 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
10617 function negate(predicate) {
10618 if (typeof predicate != 'function') {
10619 throw new TypeError(FUNC_ERROR_TEXT);
10621 return function() {
10622 var args = arguments;
10623 switch (args.length) {
10624 case 0: return !predicate.call(this);
10625 case 1: return !predicate.call(this, args[0]);
10626 case 2: return !predicate.call(this, args[0], args[1]);
10627 case 3: return !predicate.call(this, args[0], args[1], args[2]);
10629 return !predicate.apply(this, args);
10634 * Creates a function that is restricted to invoking `func` once. Repeat calls
10635 * to the function return the value of the first invocation. The `func` is
10636 * invoked with the `this` binding and arguments of the created function.
10641 * @category Function
10642 * @param {Function} func The function to restrict.
10643 * @returns {Function} Returns the new restricted function.
10646 * var initialize = _.once(createApplication);
10649 * // => `createApplication` is invoked once
10651 function once(func) {
10652 return before(2, func);
10656 * Creates a function that invokes `func` with its arguments transformed.
10661 * @category Function
10662 * @param {Function} func The function to wrap.
10663 * @param {...(Function|Function[])} [transforms=[_.identity]]
10664 * The argument transforms.
10665 * @returns {Function} Returns the new function.
10668 * function doubled(n) {
10672 * function square(n) {
10676 * var func = _.overArgs(function(x, y) {
10678 * }, [square, doubled]);
10686 var overArgs = castRest(function(func, transforms) {
10687 transforms = (transforms.length == 1 && isArray(transforms[0]))
10688 ? arrayMap(transforms[0], baseUnary(getIteratee()))
10689 : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
10691 var funcsLength = transforms.length;
10692 return baseRest(function(args) {
10694 length = nativeMin(args.length, funcsLength);
10696 while (++index < length) {
10697 args[index] = transforms[index].call(this, args[index]);
10699 return apply(func, this, args);
10704 * Creates a function that invokes `func` with `partials` prepended to the
10705 * arguments it receives. This method is like `_.bind` except it does **not**
10706 * alter the `this` binding.
10708 * The `_.partial.placeholder` value, which defaults to `_` in monolithic
10709 * builds, may be used as a placeholder for partially applied arguments.
10711 * **Note:** This method doesn't set the "length" property of partially
10712 * applied functions.
10717 * @category Function
10718 * @param {Function} func The function to partially apply arguments to.
10719 * @param {...*} [partials] The arguments to be partially applied.
10720 * @returns {Function} Returns the new partially applied function.
10723 * function greet(greeting, name) {
10724 * return greeting + ' ' + name;
10727 * var sayHelloTo = _.partial(greet, 'hello');
10728 * sayHelloTo('fred');
10729 * // => 'hello fred'
10731 * // Partially applied with placeholders.
10732 * var greetFred = _.partial(greet, _, 'fred');
10736 var partial = baseRest(function(func, partials) {
10737 var holders = replaceHolders(partials, getHolder(partial));
10738 return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
10742 * This method is like `_.partial` except that partially applied arguments
10743 * are appended to the arguments it receives.
10745 * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
10746 * builds, may be used as a placeholder for partially applied arguments.
10748 * **Note:** This method doesn't set the "length" property of partially
10749 * applied functions.
10754 * @category Function
10755 * @param {Function} func The function to partially apply arguments to.
10756 * @param {...*} [partials] The arguments to be partially applied.
10757 * @returns {Function} Returns the new partially applied function.
10760 * function greet(greeting, name) {
10761 * return greeting + ' ' + name;
10764 * var greetFred = _.partialRight(greet, 'fred');
10768 * // Partially applied with placeholders.
10769 * var sayHelloTo = _.partialRight(greet, 'hello', _);
10770 * sayHelloTo('fred');
10771 * // => 'hello fred'
10773 var partialRight = baseRest(function(func, partials) {
10774 var holders = replaceHolders(partials, getHolder(partialRight));
10775 return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
10779 * Creates a function that invokes `func` with arguments arranged according
10780 * to the specified `indexes` where the argument value at the first index is
10781 * provided as the first argument, the argument value at the second index is
10782 * provided as the second argument, and so on.
10787 * @category Function
10788 * @param {Function} func The function to rearrange arguments for.
10789 * @param {...(number|number[])} indexes The arranged argument indexes.
10790 * @returns {Function} Returns the new function.
10793 * var rearged = _.rearg(function(a, b, c) {
10794 * return [a, b, c];
10797 * rearged('b', 'c', 'a')
10798 * // => ['a', 'b', 'c']
10800 var rearg = flatRest(function(func, indexes) {
10801 return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
10805 * Creates a function that invokes `func` with the `this` binding of the
10806 * created function and arguments from `start` and beyond provided as
10809 * **Note:** This method is based on the
10810 * [rest parameter](https://mdn.io/rest_parameters).
10815 * @category Function
10816 * @param {Function} func The function to apply a rest parameter to.
10817 * @param {number} [start=func.length-1] The start position of the rest parameter.
10818 * @returns {Function} Returns the new function.
10821 * var say = _.rest(function(what, names) {
10822 * return what + ' ' + _.initial(names).join(', ') +
10823 * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
10826 * say('hello', 'fred', 'barney', 'pebbles');
10827 * // => 'hello fred, barney, & pebbles'
10829 function rest(func, start) {
10830 if (typeof func != 'function') {
10831 throw new TypeError(FUNC_ERROR_TEXT);
10833 start = start === undefined ? start : toInteger(start);
10834 return baseRest(func, start);
10838 * Creates a function that invokes `func` with the `this` binding of the
10839 * create function and an array of arguments much like
10840 * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
10842 * **Note:** This method is based on the
10843 * [spread operator](https://mdn.io/spread_operator).
10848 * @category Function
10849 * @param {Function} func The function to spread arguments over.
10850 * @param {number} [start=0] The start position of the spread.
10851 * @returns {Function} Returns the new function.
10854 * var say = _.spread(function(who, what) {
10855 * return who + ' says ' + what;
10858 * say(['fred', 'hello']);
10859 * // => 'fred says hello'
10861 * var numbers = Promise.all([
10862 * Promise.resolve(40),
10863 * Promise.resolve(36)
10866 * numbers.then(_.spread(function(x, y) {
10869 * // => a Promise of 76
10871 function spread(func, start) {
10872 if (typeof func != 'function') {
10873 throw new TypeError(FUNC_ERROR_TEXT);
10875 start = start == null ? 0 : nativeMax(toInteger(start), 0);
10876 return baseRest(function(args) {
10877 var array = args[start],
10878 otherArgs = castSlice(args, 0, start);
10881 arrayPush(otherArgs, array);
10883 return apply(func, this, otherArgs);
10888 * Creates a throttled function that only invokes `func` at most once per
10889 * every `wait` milliseconds. The throttled function comes with a `cancel`
10890 * method to cancel delayed `func` invocations and a `flush` method to
10891 * immediately invoke them. Provide `options` to indicate whether `func`
10892 * should be invoked on the leading and/or trailing edge of the `wait`
10893 * timeout. The `func` is invoked with the last arguments provided to the
10894 * throttled function. Subsequent calls to the throttled function return the
10895 * result of the last `func` invocation.
10897 * **Note:** If `leading` and `trailing` options are `true`, `func` is
10898 * invoked on the trailing edge of the timeout only if the throttled function
10899 * is invoked more than once during the `wait` timeout.
10901 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10902 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10904 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10905 * for details over the differences between `_.throttle` and `_.debounce`.
10910 * @category Function
10911 * @param {Function} func The function to throttle.
10912 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10913 * @param {Object} [options={}] The options object.
10914 * @param {boolean} [options.leading=true]
10915 * Specify invoking on the leading edge of the timeout.
10916 * @param {boolean} [options.trailing=true]
10917 * Specify invoking on the trailing edge of the timeout.
10918 * @returns {Function} Returns the new throttled function.
10921 * // Avoid excessively updating the position while scrolling.
10922 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10924 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10925 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10926 * jQuery(element).on('click', throttled);
10928 * // Cancel the trailing throttled invocation.
10929 * jQuery(window).on('popstate', throttled.cancel);
10931 function throttle(func, wait, options) {
10932 var leading = true,
10935 if (typeof func != 'function') {
10936 throw new TypeError(FUNC_ERROR_TEXT);
10938 if (isObject(options)) {
10939 leading = 'leading' in options ? !!options.leading : leading;
10940 trailing = 'trailing' in options ? !!options.trailing : trailing;
10942 return debounce(func, wait, {
10943 'leading': leading,
10945 'trailing': trailing
10950 * Creates a function that accepts up to one argument, ignoring any
10951 * additional arguments.
10956 * @category Function
10957 * @param {Function} func The function to cap arguments for.
10958 * @returns {Function} Returns the new capped function.
10961 * _.map(['6', '8', '10'], _.unary(parseInt));
10964 function unary(func) {
10965 return ary(func, 1);
10969 * Creates a function that provides `value` to `wrapper` as its first
10970 * argument. Any additional arguments provided to the function are appended
10971 * to those provided to the `wrapper`. The wrapper is invoked with the `this`
10972 * binding of the created function.
10977 * @category Function
10978 * @param {*} value The value to wrap.
10979 * @param {Function} [wrapper=identity] The wrapper function.
10980 * @returns {Function} Returns the new function.
10983 * var p = _.wrap(_.escape, function(func, text) {
10984 * return '<p>' + func(text) + '</p>';
10987 * p('fred, barney, & pebbles');
10988 * // => '<p>fred, barney, & pebbles</p>'
10990 function wrap(value, wrapper) {
10991 return partial(castFunction(wrapper), value);
10994 /*------------------------------------------------------------------------*/
10997 * Casts `value` as an array if it's not one.
11003 * @param {*} value The value to inspect.
11004 * @returns {Array} Returns the cast array.
11010 * _.castArray({ 'a': 1 });
11011 * // => [{ 'a': 1 }]
11013 * _.castArray('abc');
11016 * _.castArray(null);
11019 * _.castArray(undefined);
11020 * // => [undefined]
11025 * var array = [1, 2, 3];
11026 * console.log(_.castArray(array) === array);
11029 function castArray() {
11030 if (!arguments.length) {
11033 var value = arguments[0];
11034 return isArray(value) ? value : [value];
11038 * Creates a shallow clone of `value`.
11040 * **Note:** This method is loosely based on the
11041 * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
11042 * and supports cloning arrays, array buffers, booleans, date objects, maps,
11043 * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
11044 * arrays. The own enumerable properties of `arguments` objects are cloned
11045 * as plain objects. An empty object is returned for uncloneable values such
11046 * as error objects, functions, DOM nodes, and WeakMaps.
11052 * @param {*} value The value to clone.
11053 * @returns {*} Returns the cloned value.
11057 * var objects = [{ 'a': 1 }, { 'b': 2 }];
11059 * var shallow = _.clone(objects);
11060 * console.log(shallow[0] === objects[0]);
11063 function clone(value) {
11064 return baseClone(value, CLONE_SYMBOLS_FLAG);
11068 * This method is like `_.clone` except that it accepts `customizer` which
11069 * is invoked to produce the cloned value. If `customizer` returns `undefined`,
11070 * cloning is handled by the method instead. The `customizer` is invoked with
11071 * up to four arguments; (value [, index|key, object, stack]).
11077 * @param {*} value The value to clone.
11078 * @param {Function} [customizer] The function to customize cloning.
11079 * @returns {*} Returns the cloned value.
11080 * @see _.cloneDeepWith
11083 * function customizer(value) {
11084 * if (_.isElement(value)) {
11085 * return value.cloneNode(false);
11089 * var el = _.cloneWith(document.body, customizer);
11091 * console.log(el === document.body);
11093 * console.log(el.nodeName);
11095 * console.log(el.childNodes.length);
11098 function cloneWith(value, customizer) {
11099 customizer = typeof customizer == 'function' ? customizer : undefined;
11100 return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
11104 * This method is like `_.clone` except that it recursively clones `value`.
11110 * @param {*} value The value to recursively clone.
11111 * @returns {*} Returns the deep cloned value.
11115 * var objects = [{ 'a': 1 }, { 'b': 2 }];
11117 * var deep = _.cloneDeep(objects);
11118 * console.log(deep[0] === objects[0]);
11121 function cloneDeep(value) {
11122 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
11126 * This method is like `_.cloneWith` except that it recursively clones `value`.
11132 * @param {*} value The value to recursively clone.
11133 * @param {Function} [customizer] The function to customize cloning.
11134 * @returns {*} Returns the deep cloned value.
11138 * function customizer(value) {
11139 * if (_.isElement(value)) {
11140 * return value.cloneNode(true);
11144 * var el = _.cloneDeepWith(document.body, customizer);
11146 * console.log(el === document.body);
11148 * console.log(el.nodeName);
11150 * console.log(el.childNodes.length);
11153 function cloneDeepWith(value, customizer) {
11154 customizer = typeof customizer == 'function' ? customizer : undefined;
11155 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
11159 * Checks if `object` conforms to `source` by invoking the predicate
11160 * properties of `source` with the corresponding property values of `object`.
11162 * **Note:** This method is equivalent to `_.conforms` when `source` is
11163 * partially applied.
11169 * @param {Object} object The object to inspect.
11170 * @param {Object} source The object of property predicates to conform to.
11171 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
11174 * var object = { 'a': 1, 'b': 2 };
11176 * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
11179 * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
11182 function conformsTo(object, source) {
11183 return source == null || baseConformsTo(object, source, keys(source));
11188 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
11189 * comparison between two values to determine if they are equivalent.
11195 * @param {*} value The value to compare.
11196 * @param {*} other The other value to compare.
11197 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11200 * var object = { 'a': 1 };
11201 * var other = { 'a': 1 };
11203 * _.eq(object, object);
11206 * _.eq(object, other);
11212 * _.eq('a', Object('a'));
11218 function eq(value, other) {
11219 return value === other || (value !== value && other !== other);
11223 * Checks if `value` is greater than `other`.
11229 * @param {*} value The value to compare.
11230 * @param {*} other The other value to compare.
11231 * @returns {boolean} Returns `true` if `value` is greater than `other`,
11245 var gt = createRelationalOperation(baseGt);
11248 * Checks if `value` is greater than or equal to `other`.
11254 * @param {*} value The value to compare.
11255 * @param {*} other The other value to compare.
11256 * @returns {boolean} Returns `true` if `value` is greater than or equal to
11257 * `other`, else `false`.
11270 var gte = createRelationalOperation(function(value, other) {
11271 return value >= other;
11275 * Checks if `value` is likely an `arguments` object.
11281 * @param {*} value The value to check.
11282 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
11286 * _.isArguments(function() { return arguments; }());
11289 * _.isArguments([1, 2, 3]);
11292 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
11293 return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
11294 !propertyIsEnumerable.call(value, 'callee');
11298 * Checks if `value` is classified as an `Array` object.
11304 * @param {*} value The value to check.
11305 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
11308 * _.isArray([1, 2, 3]);
11311 * _.isArray(document.body.children);
11314 * _.isArray('abc');
11317 * _.isArray(_.noop);
11320 var isArray = Array.isArray;
11323 * Checks if `value` is classified as an `ArrayBuffer` object.
11329 * @param {*} value The value to check.
11330 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
11333 * _.isArrayBuffer(new ArrayBuffer(2));
11336 * _.isArrayBuffer(new Array(2));
11339 var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
11342 * Checks if `value` is array-like. A value is considered array-like if it's
11343 * not a function and has a `value.length` that's an integer greater than or
11344 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
11350 * @param {*} value The value to check.
11351 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
11354 * _.isArrayLike([1, 2, 3]);
11357 * _.isArrayLike(document.body.children);
11360 * _.isArrayLike('abc');
11363 * _.isArrayLike(_.noop);
11366 function isArrayLike(value) {
11367 return value != null && isLength(value.length) && !isFunction(value);
11371 * This method is like `_.isArrayLike` except that it also checks if `value`
11378 * @param {*} value The value to check.
11379 * @returns {boolean} Returns `true` if `value` is an array-like object,
11383 * _.isArrayLikeObject([1, 2, 3]);
11386 * _.isArrayLikeObject(document.body.children);
11389 * _.isArrayLikeObject('abc');
11392 * _.isArrayLikeObject(_.noop);
11395 function isArrayLikeObject(value) {
11396 return isObjectLike(value) && isArrayLike(value);
11400 * Checks if `value` is classified as a boolean primitive or object.
11406 * @param {*} value The value to check.
11407 * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
11410 * _.isBoolean(false);
11413 * _.isBoolean(null);
11416 function isBoolean(value) {
11417 return value === true || value === false ||
11418 (isObjectLike(value) && baseGetTag(value) == boolTag);
11422 * Checks if `value` is a buffer.
11428 * @param {*} value The value to check.
11429 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
11432 * _.isBuffer(new Buffer(2));
11435 * _.isBuffer(new Uint8Array(2));
11438 var isBuffer = nativeIsBuffer || stubFalse;
11441 * Checks if `value` is classified as a `Date` object.
11447 * @param {*} value The value to check.
11448 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
11451 * _.isDate(new Date);
11454 * _.isDate('Mon April 23 2012');
11457 var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
11460 * Checks if `value` is likely a DOM element.
11466 * @param {*} value The value to check.
11467 * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
11470 * _.isElement(document.body);
11473 * _.isElement('<body>');
11476 function isElement(value) {
11477 return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
11481 * Checks if `value` is an empty object, collection, map, or set.
11483 * Objects are considered empty if they have no own enumerable string keyed
11486 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
11487 * jQuery-like collections are considered empty if they have a `length` of `0`.
11488 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
11494 * @param {*} value The value to check.
11495 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
11507 * _.isEmpty([1, 2, 3]);
11510 * _.isEmpty({ 'a': 1 });
11513 function isEmpty(value) {
11514 if (value == null) {
11517 if (isArrayLike(value) &&
11518 (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
11519 isBuffer(value) || isTypedArray(value) || isArguments(value))) {
11520 return !value.length;
11522 var tag = getTag(value);
11523 if (tag == mapTag || tag == setTag) {
11524 return !value.size;
11526 if (isPrototype(value)) {
11527 return !baseKeys(value).length;
11529 for (var key in value) {
11530 if (hasOwnProperty.call(value, key)) {
11538 * Performs a deep comparison between two values to determine if they are
11541 * **Note:** This method supports comparing arrays, array buffers, booleans,
11542 * date objects, error objects, maps, numbers, `Object` objects, regexes,
11543 * sets, strings, symbols, and typed arrays. `Object` objects are compared
11544 * by their own, not inherited, enumerable properties. Functions and DOM
11545 * nodes are compared by strict equality, i.e. `===`.
11551 * @param {*} value The value to compare.
11552 * @param {*} other The other value to compare.
11553 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11556 * var object = { 'a': 1 };
11557 * var other = { 'a': 1 };
11559 * _.isEqual(object, other);
11562 * object === other;
11565 function isEqual(value, other) {
11566 return baseIsEqual(value, other);
11570 * This method is like `_.isEqual` except that it accepts `customizer` which
11571 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11572 * are handled by the method instead. The `customizer` is invoked with up to
11573 * six arguments: (objValue, othValue [, index|key, object, other, stack]).
11579 * @param {*} value The value to compare.
11580 * @param {*} other The other value to compare.
11581 * @param {Function} [customizer] The function to customize comparisons.
11582 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11585 * function isGreeting(value) {
11586 * return /^h(?:i|ello)$/.test(value);
11589 * function customizer(objValue, othValue) {
11590 * if (isGreeting(objValue) && isGreeting(othValue)) {
11595 * var array = ['hello', 'goodbye'];
11596 * var other = ['hi', 'goodbye'];
11598 * _.isEqualWith(array, other, customizer);
11601 function isEqualWith(value, other, customizer) {
11602 customizer = typeof customizer == 'function' ? customizer : undefined;
11603 var result = customizer ? customizer(value, other) : undefined;
11604 return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
11608 * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
11609 * `SyntaxError`, `TypeError`, or `URIError` object.
11615 * @param {*} value The value to check.
11616 * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
11619 * _.isError(new Error);
11622 * _.isError(Error);
11625 function isError(value) {
11626 if (!isObjectLike(value)) {
11629 var tag = baseGetTag(value);
11630 return tag == errorTag || tag == domExcTag ||
11631 (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
11635 * Checks if `value` is a finite primitive number.
11637 * **Note:** This method is based on
11638 * [`Number.isFinite`](https://mdn.io/Number/isFinite).
11644 * @param {*} value The value to check.
11645 * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
11651 * _.isFinite(Number.MIN_VALUE);
11654 * _.isFinite(Infinity);
11660 function isFinite(value) {
11661 return typeof value == 'number' && nativeIsFinite(value);
11665 * Checks if `value` is classified as a `Function` object.
11671 * @param {*} value The value to check.
11672 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
11678 * _.isFunction(/abc/);
11681 function isFunction(value) {
11682 if (!isObject(value)) {
11685 // The use of `Object#toString` avoids issues with the `typeof` operator
11686 // in Safari 9 which returns 'object' for typed arrays and other constructors.
11687 var tag = baseGetTag(value);
11688 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
11692 * Checks if `value` is an integer.
11694 * **Note:** This method is based on
11695 * [`Number.isInteger`](https://mdn.io/Number/isInteger).
11701 * @param {*} value The value to check.
11702 * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
11708 * _.isInteger(Number.MIN_VALUE);
11711 * _.isInteger(Infinity);
11714 * _.isInteger('3');
11717 function isInteger(value) {
11718 return typeof value == 'number' && value == toInteger(value);
11722 * Checks if `value` is a valid array-like length.
11724 * **Note:** This method is loosely based on
11725 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
11731 * @param {*} value The value to check.
11732 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
11738 * _.isLength(Number.MIN_VALUE);
11741 * _.isLength(Infinity);
11747 function isLength(value) {
11748 return typeof value == 'number' &&
11749 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
11753 * Checks if `value` is the
11754 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
11755 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
11761 * @param {*} value The value to check.
11762 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
11768 * _.isObject([1, 2, 3]);
11771 * _.isObject(_.noop);
11774 * _.isObject(null);
11777 function isObject(value) {
11778 var type = typeof value;
11779 return value != null && (type == 'object' || type == 'function');
11783 * Checks if `value` is object-like. A value is object-like if it's not `null`
11784 * and has a `typeof` result of "object".
11790 * @param {*} value The value to check.
11791 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
11794 * _.isObjectLike({});
11797 * _.isObjectLike([1, 2, 3]);
11800 * _.isObjectLike(_.noop);
11803 * _.isObjectLike(null);
11806 function isObjectLike(value) {
11807 return value != null && typeof value == 'object';
11811 * Checks if `value` is classified as a `Map` object.
11817 * @param {*} value The value to check.
11818 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
11821 * _.isMap(new Map);
11824 * _.isMap(new WeakMap);
11827 var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
11830 * Performs a partial deep comparison between `object` and `source` to
11831 * determine if `object` contains equivalent property values.
11833 * **Note:** This method is equivalent to `_.matches` when `source` is
11834 * partially applied.
11836 * Partial comparisons will match empty array and empty object `source`
11837 * values against any array or object value, respectively. See `_.isEqual`
11838 * for a list of supported value comparisons.
11844 * @param {Object} object The object to inspect.
11845 * @param {Object} source The object of property values to match.
11846 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11849 * var object = { 'a': 1, 'b': 2 };
11851 * _.isMatch(object, { 'b': 2 });
11854 * _.isMatch(object, { 'b': 1 });
11857 function isMatch(object, source) {
11858 return object === source || baseIsMatch(object, source, getMatchData(source));
11862 * This method is like `_.isMatch` except that it accepts `customizer` which
11863 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11864 * are handled by the method instead. The `customizer` is invoked with five
11865 * arguments: (objValue, srcValue, index|key, object, source).
11871 * @param {Object} object The object to inspect.
11872 * @param {Object} source The object of property values to match.
11873 * @param {Function} [customizer] The function to customize comparisons.
11874 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11877 * function isGreeting(value) {
11878 * return /^h(?:i|ello)$/.test(value);
11881 * function customizer(objValue, srcValue) {
11882 * if (isGreeting(objValue) && isGreeting(srcValue)) {
11887 * var object = { 'greeting': 'hello' };
11888 * var source = { 'greeting': 'hi' };
11890 * _.isMatchWith(object, source, customizer);
11893 function isMatchWith(object, source, customizer) {
11894 customizer = typeof customizer == 'function' ? customizer : undefined;
11895 return baseIsMatch(object, source, getMatchData(source), customizer);
11899 * Checks if `value` is `NaN`.
11901 * **Note:** This method is based on
11902 * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11903 * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11904 * `undefined` and other non-number values.
11910 * @param {*} value The value to check.
11911 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11917 * _.isNaN(new Number(NaN));
11920 * isNaN(undefined);
11923 * _.isNaN(undefined);
11926 function isNaN(value) {
11927 // An `NaN` primitive is the only value that is not equal to itself.
11928 // Perform the `toStringTag` check first to avoid errors with some
11929 // ActiveX objects in IE.
11930 return isNumber(value) && value != +value;
11934 * Checks if `value` is a pristine native function.
11936 * **Note:** This method can't reliably detect native functions in the presence
11937 * of the core-js package because core-js circumvents this kind of detection.
11938 * Despite multiple requests, the core-js maintainer has made it clear: any
11939 * attempt to fix the detection will be obstructed. As a result, we're left
11940 * with little choice but to throw an error. Unfortunately, this also affects
11941 * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
11942 * which rely on core-js.
11948 * @param {*} value The value to check.
11949 * @returns {boolean} Returns `true` if `value` is a native function,
11953 * _.isNative(Array.prototype.push);
11959 function isNative(value) {
11960 if (isMaskable(value)) {
11961 throw new Error(CORE_ERROR_TEXT);
11963 return baseIsNative(value);
11967 * Checks if `value` is `null`.
11973 * @param {*} value The value to check.
11974 * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
11980 * _.isNull(void 0);
11983 function isNull(value) {
11984 return value === null;
11988 * Checks if `value` is `null` or `undefined`.
11994 * @param {*} value The value to check.
11995 * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
12007 function isNil(value) {
12008 return value == null;
12012 * Checks if `value` is classified as a `Number` primitive or object.
12014 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
12015 * classified as numbers, use the `_.isFinite` method.
12021 * @param {*} value The value to check.
12022 * @returns {boolean} Returns `true` if `value` is a number, else `false`.
12028 * _.isNumber(Number.MIN_VALUE);
12031 * _.isNumber(Infinity);
12037 function isNumber(value) {
12038 return typeof value == 'number' ||
12039 (isObjectLike(value) && baseGetTag(value) == numberTag);
12043 * Checks if `value` is a plain object, that is, an object created by the
12044 * `Object` constructor or one with a `[[Prototype]]` of `null`.
12050 * @param {*} value The value to check.
12051 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
12058 * _.isPlainObject(new Foo);
12061 * _.isPlainObject([1, 2, 3]);
12064 * _.isPlainObject({ 'x': 0, 'y': 0 });
12067 * _.isPlainObject(Object.create(null));
12070 function isPlainObject(value) {
12071 if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
12074 var proto = getPrototype(value);
12075 if (proto === null) {
12078 var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
12079 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
12080 funcToString.call(Ctor) == objectCtorString;
12084 * Checks if `value` is classified as a `RegExp` object.
12090 * @param {*} value The value to check.
12091 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
12094 * _.isRegExp(/abc/);
12097 * _.isRegExp('/abc/');
12100 var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
12103 * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
12104 * double precision number which isn't the result of a rounded unsafe integer.
12106 * **Note:** This method is based on
12107 * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
12113 * @param {*} value The value to check.
12114 * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
12117 * _.isSafeInteger(3);
12120 * _.isSafeInteger(Number.MIN_VALUE);
12123 * _.isSafeInteger(Infinity);
12126 * _.isSafeInteger('3');
12129 function isSafeInteger(value) {
12130 return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
12134 * Checks if `value` is classified as a `Set` object.
12140 * @param {*} value The value to check.
12141 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
12144 * _.isSet(new Set);
12147 * _.isSet(new WeakSet);
12150 var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
12153 * Checks if `value` is classified as a `String` primitive or object.
12159 * @param {*} value The value to check.
12160 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
12163 * _.isString('abc');
12169 function isString(value) {
12170 return typeof value == 'string' ||
12171 (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
12175 * Checks if `value` is classified as a `Symbol` primitive or object.
12181 * @param {*} value The value to check.
12182 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
12185 * _.isSymbol(Symbol.iterator);
12188 * _.isSymbol('abc');
12191 function isSymbol(value) {
12192 return typeof value == 'symbol' ||
12193 (isObjectLike(value) && baseGetTag(value) == symbolTag);
12197 * Checks if `value` is classified as a typed array.
12203 * @param {*} value The value to check.
12204 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
12207 * _.isTypedArray(new Uint8Array);
12210 * _.isTypedArray([]);
12213 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
12216 * Checks if `value` is `undefined`.
12222 * @param {*} value The value to check.
12223 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
12226 * _.isUndefined(void 0);
12229 * _.isUndefined(null);
12232 function isUndefined(value) {
12233 return value === undefined;
12237 * Checks if `value` is classified as a `WeakMap` object.
12243 * @param {*} value The value to check.
12244 * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
12247 * _.isWeakMap(new WeakMap);
12250 * _.isWeakMap(new Map);
12253 function isWeakMap(value) {
12254 return isObjectLike(value) && getTag(value) == weakMapTag;
12258 * Checks if `value` is classified as a `WeakSet` object.
12264 * @param {*} value The value to check.
12265 * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
12268 * _.isWeakSet(new WeakSet);
12271 * _.isWeakSet(new Set);
12274 function isWeakSet(value) {
12275 return isObjectLike(value) && baseGetTag(value) == weakSetTag;
12279 * Checks if `value` is less than `other`.
12285 * @param {*} value The value to compare.
12286 * @param {*} other The other value to compare.
12287 * @returns {boolean} Returns `true` if `value` is less than `other`,
12301 var lt = createRelationalOperation(baseLt);
12304 * Checks if `value` is less than or equal to `other`.
12310 * @param {*} value The value to compare.
12311 * @param {*} other The other value to compare.
12312 * @returns {boolean} Returns `true` if `value` is less than or equal to
12313 * `other`, else `false`.
12326 var lte = createRelationalOperation(function(value, other) {
12327 return value <= other;
12331 * Converts `value` to an array.
12337 * @param {*} value The value to convert.
12338 * @returns {Array} Returns the converted array.
12341 * _.toArray({ 'a': 1, 'b': 2 });
12344 * _.toArray('abc');
12345 * // => ['a', 'b', 'c']
12353 function toArray(value) {
12357 if (isArrayLike(value)) {
12358 return isString(value) ? stringToArray(value) : copyArray(value);
12360 if (symIterator && value[symIterator]) {
12361 return iteratorToArray(value[symIterator]());
12363 var tag = getTag(value),
12364 func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
12366 return func(value);
12370 * Converts `value` to a finite number.
12376 * @param {*} value The value to convert.
12377 * @returns {number} Returns the converted number.
12383 * _.toFinite(Number.MIN_VALUE);
12386 * _.toFinite(Infinity);
12387 * // => 1.7976931348623157e+308
12389 * _.toFinite('3.2');
12392 function toFinite(value) {
12394 return value === 0 ? value : 0;
12396 value = toNumber(value);
12397 if (value === INFINITY || value === -INFINITY) {
12398 var sign = (value < 0 ? -1 : 1);
12399 return sign * MAX_INTEGER;
12401 return value === value ? value : 0;
12405 * Converts `value` to an integer.
12407 * **Note:** This method is loosely based on
12408 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
12414 * @param {*} value The value to convert.
12415 * @returns {number} Returns the converted integer.
12418 * _.toInteger(3.2);
12421 * _.toInteger(Number.MIN_VALUE);
12424 * _.toInteger(Infinity);
12425 * // => 1.7976931348623157e+308
12427 * _.toInteger('3.2');
12430 function toInteger(value) {
12431 var result = toFinite(value),
12432 remainder = result % 1;
12434 return result === result ? (remainder ? result - remainder : result) : 0;
12438 * Converts `value` to an integer suitable for use as the length of an
12439 * array-like object.
12441 * **Note:** This method is based on
12442 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12448 * @param {*} value The value to convert.
12449 * @returns {number} Returns the converted integer.
12455 * _.toLength(Number.MIN_VALUE);
12458 * _.toLength(Infinity);
12461 * _.toLength('3.2');
12464 function toLength(value) {
12465 return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
12469 * Converts `value` to a number.
12475 * @param {*} value The value to process.
12476 * @returns {number} Returns the number.
12482 * _.toNumber(Number.MIN_VALUE);
12485 * _.toNumber(Infinity);
12488 * _.toNumber('3.2');
12491 function toNumber(value) {
12492 if (typeof value == 'number') {
12495 if (isSymbol(value)) {
12498 if (isObject(value)) {
12499 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
12500 value = isObject(other) ? (other + '') : other;
12502 if (typeof value != 'string') {
12503 return value === 0 ? value : +value;
12505 value = value.replace(reTrim, '');
12506 var isBinary = reIsBinary.test(value);
12507 return (isBinary || reIsOctal.test(value))
12508 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
12509 : (reIsBadHex.test(value) ? NAN : +value);
12513 * Converts `value` to a plain object flattening inherited enumerable string
12514 * keyed properties of `value` to own properties of the plain object.
12520 * @param {*} value The value to convert.
12521 * @returns {Object} Returns the converted plain object.
12528 * Foo.prototype.c = 3;
12530 * _.assign({ 'a': 1 }, new Foo);
12531 * // => { 'a': 1, 'b': 2 }
12533 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
12534 * // => { 'a': 1, 'b': 2, 'c': 3 }
12536 function toPlainObject(value) {
12537 return copyObject(value, keysIn(value));
12541 * Converts `value` to a safe integer. A safe integer can be compared and
12542 * represented correctly.
12548 * @param {*} value The value to convert.
12549 * @returns {number} Returns the converted integer.
12552 * _.toSafeInteger(3.2);
12555 * _.toSafeInteger(Number.MIN_VALUE);
12558 * _.toSafeInteger(Infinity);
12559 * // => 9007199254740991
12561 * _.toSafeInteger('3.2');
12564 function toSafeInteger(value) {
12566 ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
12567 : (value === 0 ? value : 0);
12571 * Converts `value` to a string. An empty string is returned for `null`
12572 * and `undefined` values. The sign of `-0` is preserved.
12578 * @param {*} value The value to convert.
12579 * @returns {string} Returns the converted string.
12582 * _.toString(null);
12588 * _.toString([1, 2, 3]);
12591 function toString(value) {
12592 return value == null ? '' : baseToString(value);
12595 /*------------------------------------------------------------------------*/
12598 * Assigns own enumerable string keyed properties of source objects to the
12599 * destination object. Source objects are applied from left to right.
12600 * Subsequent sources overwrite property assignments of previous sources.
12602 * **Note:** This method mutates `object` and is loosely based on
12603 * [`Object.assign`](https://mdn.io/Object/assign).
12609 * @param {Object} object The destination object.
12610 * @param {...Object} [sources] The source objects.
12611 * @returns {Object} Returns `object`.
12623 * Foo.prototype.b = 2;
12624 * Bar.prototype.d = 4;
12626 * _.assign({ 'a': 0 }, new Foo, new Bar);
12627 * // => { 'a': 1, 'c': 3 }
12629 var assign = createAssigner(function(object, source) {
12630 if (isPrototype(source) || isArrayLike(source)) {
12631 copyObject(source, keys(source), object);
12634 for (var key in source) {
12635 if (hasOwnProperty.call(source, key)) {
12636 assignValue(object, key, source[key]);
12642 * This method is like `_.assign` except that it iterates over own and
12643 * inherited source properties.
12645 * **Note:** This method mutates `object`.
12652 * @param {Object} object The destination object.
12653 * @param {...Object} [sources] The source objects.
12654 * @returns {Object} Returns `object`.
12666 * Foo.prototype.b = 2;
12667 * Bar.prototype.d = 4;
12669 * _.assignIn({ 'a': 0 }, new Foo, new Bar);
12670 * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
12672 var assignIn = createAssigner(function(object, source) {
12673 copyObject(source, keysIn(source), object);
12677 * This method is like `_.assignIn` except that it accepts `customizer`
12678 * which is invoked to produce the assigned values. If `customizer` returns
12679 * `undefined`, assignment is handled by the method instead. The `customizer`
12680 * is invoked with five arguments: (objValue, srcValue, key, object, source).
12682 * **Note:** This method mutates `object`.
12687 * @alias extendWith
12689 * @param {Object} object The destination object.
12690 * @param {...Object} sources The source objects.
12691 * @param {Function} [customizer] The function to customize assigned values.
12692 * @returns {Object} Returns `object`.
12693 * @see _.assignWith
12696 * function customizer(objValue, srcValue) {
12697 * return _.isUndefined(objValue) ? srcValue : objValue;
12700 * var defaults = _.partialRight(_.assignInWith, customizer);
12702 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12703 * // => { 'a': 1, 'b': 2 }
12705 var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
12706 copyObject(source, keysIn(source), object, customizer);
12710 * This method is like `_.assign` except that it accepts `customizer`
12711 * which is invoked to produce the assigned values. If `customizer` returns
12712 * `undefined`, assignment is handled by the method instead. The `customizer`
12713 * is invoked with five arguments: (objValue, srcValue, key, object, source).
12715 * **Note:** This method mutates `object`.
12721 * @param {Object} object The destination object.
12722 * @param {...Object} sources The source objects.
12723 * @param {Function} [customizer] The function to customize assigned values.
12724 * @returns {Object} Returns `object`.
12725 * @see _.assignInWith
12728 * function customizer(objValue, srcValue) {
12729 * return _.isUndefined(objValue) ? srcValue : objValue;
12732 * var defaults = _.partialRight(_.assignWith, customizer);
12734 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12735 * // => { 'a': 1, 'b': 2 }
12737 var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
12738 copyObject(source, keys(source), object, customizer);
12742 * Creates an array of values corresponding to `paths` of `object`.
12748 * @param {Object} object The object to iterate over.
12749 * @param {...(string|string[])} [paths] The property paths to pick.
12750 * @returns {Array} Returns the picked values.
12753 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
12755 * _.at(object, ['a[0].b.c', 'a[1]']);
12758 var at = flatRest(baseAt);
12761 * Creates an object that inherits from the `prototype` object. If a
12762 * `properties` object is given, its own enumerable string keyed properties
12763 * are assigned to the created object.
12769 * @param {Object} prototype The object to inherit from.
12770 * @param {Object} [properties] The properties to assign to the object.
12771 * @returns {Object} Returns the new object.
12774 * function Shape() {
12779 * function Circle() {
12780 * Shape.call(this);
12783 * Circle.prototype = _.create(Shape.prototype, {
12784 * 'constructor': Circle
12787 * var circle = new Circle;
12788 * circle instanceof Circle;
12791 * circle instanceof Shape;
12794 function create(prototype, properties) {
12795 var result = baseCreate(prototype);
12796 return properties == null ? result : baseAssign(result, properties);
12800 * Assigns own and inherited enumerable string keyed properties of source
12801 * objects to the destination object for all destination properties that
12802 * resolve to `undefined`. Source objects are applied from left to right.
12803 * Once a property is set, additional values of the same property are ignored.
12805 * **Note:** This method mutates `object`.
12811 * @param {Object} object The destination object.
12812 * @param {...Object} [sources] The source objects.
12813 * @returns {Object} Returns `object`.
12814 * @see _.defaultsDeep
12817 * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12818 * // => { 'a': 1, 'b': 2 }
12820 var defaults = baseRest(function(args) {
12821 args.push(undefined, customDefaultsAssignIn);
12822 return apply(assignInWith, undefined, args);
12826 * This method is like `_.defaults` except that it recursively assigns
12827 * default properties.
12829 * **Note:** This method mutates `object`.
12835 * @param {Object} object The destination object.
12836 * @param {...Object} [sources] The source objects.
12837 * @returns {Object} Returns `object`.
12841 * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
12842 * // => { 'a': { 'b': 2, 'c': 3 } }
12844 var defaultsDeep = baseRest(function(args) {
12845 args.push(undefined, customDefaultsMerge);
12846 return apply(mergeWith, undefined, args);
12850 * This method is like `_.find` except that it returns the key of the first
12851 * element `predicate` returns truthy for instead of the element itself.
12857 * @param {Object} object The object to inspect.
12858 * @param {Function} [predicate=_.identity] The function invoked per iteration.
12859 * @returns {string|undefined} Returns the key of the matched element,
12860 * else `undefined`.
12864 * 'barney': { 'age': 36, 'active': true },
12865 * 'fred': { 'age': 40, 'active': false },
12866 * 'pebbles': { 'age': 1, 'active': true }
12869 * _.findKey(users, function(o) { return o.age < 40; });
12870 * // => 'barney' (iteration order is not guaranteed)
12872 * // The `_.matches` iteratee shorthand.
12873 * _.findKey(users, { 'age': 1, 'active': true });
12876 * // The `_.matchesProperty` iteratee shorthand.
12877 * _.findKey(users, ['active', false]);
12880 * // The `_.property` iteratee shorthand.
12881 * _.findKey(users, 'active');
12884 function findKey(object, predicate) {
12885 return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
12889 * This method is like `_.findKey` except that it iterates over elements of
12890 * a collection in the opposite order.
12896 * @param {Object} object The object to inspect.
12897 * @param {Function} [predicate=_.identity] The function invoked per iteration.
12898 * @returns {string|undefined} Returns the key of the matched element,
12899 * else `undefined`.
12903 * 'barney': { 'age': 36, 'active': true },
12904 * 'fred': { 'age': 40, 'active': false },
12905 * 'pebbles': { 'age': 1, 'active': true }
12908 * _.findLastKey(users, function(o) { return o.age < 40; });
12909 * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12911 * // The `_.matches` iteratee shorthand.
12912 * _.findLastKey(users, { 'age': 36, 'active': true });
12915 * // The `_.matchesProperty` iteratee shorthand.
12916 * _.findLastKey(users, ['active', false]);
12919 * // The `_.property` iteratee shorthand.
12920 * _.findLastKey(users, 'active');
12923 function findLastKey(object, predicate) {
12924 return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
12928 * Iterates over own and inherited enumerable string keyed properties of an
12929 * object and invokes `iteratee` for each property. The iteratee is invoked
12930 * with three arguments: (value, key, object). Iteratee functions may exit
12931 * iteration early by explicitly returning `false`.
12937 * @param {Object} object The object to iterate over.
12938 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12939 * @returns {Object} Returns `object`.
12940 * @see _.forInRight
12948 * Foo.prototype.c = 3;
12950 * _.forIn(new Foo, function(value, key) {
12951 * console.log(key);
12953 * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
12955 function forIn(object, iteratee) {
12956 return object == null
12958 : baseFor(object, getIteratee(iteratee, 3), keysIn);
12962 * This method is like `_.forIn` except that it iterates over properties of
12963 * `object` in the opposite order.
12969 * @param {Object} object The object to iterate over.
12970 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12971 * @returns {Object} Returns `object`.
12980 * Foo.prototype.c = 3;
12982 * _.forInRight(new Foo, function(value, key) {
12983 * console.log(key);
12985 * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
12987 function forInRight(object, iteratee) {
12988 return object == null
12990 : baseForRight(object, getIteratee(iteratee, 3), keysIn);
12994 * Iterates over own enumerable string keyed properties of an object and
12995 * invokes `iteratee` for each property. The iteratee is invoked with three
12996 * arguments: (value, key, object). Iteratee functions may exit iteration
12997 * early by explicitly returning `false`.
13003 * @param {Object} object The object to iterate over.
13004 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13005 * @returns {Object} Returns `object`.
13006 * @see _.forOwnRight
13014 * Foo.prototype.c = 3;
13016 * _.forOwn(new Foo, function(value, key) {
13017 * console.log(key);
13019 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
13021 function forOwn(object, iteratee) {
13022 return object && baseForOwn(object, getIteratee(iteratee, 3));
13026 * This method is like `_.forOwn` except that it iterates over properties of
13027 * `object` in the opposite order.
13033 * @param {Object} object The object to iterate over.
13034 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13035 * @returns {Object} Returns `object`.
13044 * Foo.prototype.c = 3;
13046 * _.forOwnRight(new Foo, function(value, key) {
13047 * console.log(key);
13049 * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
13051 function forOwnRight(object, iteratee) {
13052 return object && baseForOwnRight(object, getIteratee(iteratee, 3));
13056 * Creates an array of function property names from own enumerable properties
13063 * @param {Object} object The object to inspect.
13064 * @returns {Array} Returns the function names.
13065 * @see _.functionsIn
13069 * this.a = _.constant('a');
13070 * this.b = _.constant('b');
13073 * Foo.prototype.c = _.constant('c');
13075 * _.functions(new Foo);
13078 function functions(object) {
13079 return object == null ? [] : baseFunctions(object, keys(object));
13083 * Creates an array of function property names from own and inherited
13084 * enumerable properties of `object`.
13090 * @param {Object} object The object to inspect.
13091 * @returns {Array} Returns the function names.
13096 * this.a = _.constant('a');
13097 * this.b = _.constant('b');
13100 * Foo.prototype.c = _.constant('c');
13102 * _.functionsIn(new Foo);
13103 * // => ['a', 'b', 'c']
13105 function functionsIn(object) {
13106 return object == null ? [] : baseFunctions(object, keysIn(object));
13110 * Gets the value at `path` of `object`. If the resolved value is
13111 * `undefined`, the `defaultValue` is returned in its place.
13117 * @param {Object} object The object to query.
13118 * @param {Array|string} path The path of the property to get.
13119 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13120 * @returns {*} Returns the resolved value.
13123 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13125 * _.get(object, 'a[0].b.c');
13128 * _.get(object, ['a', '0', 'b', 'c']);
13131 * _.get(object, 'a.b.c', 'default');
13134 function get(object, path, defaultValue) {
13135 var result = object == null ? undefined : baseGet(object, path);
13136 return result === undefined ? defaultValue : result;
13140 * Checks if `path` is a direct property of `object`.
13146 * @param {Object} object The object to query.
13147 * @param {Array|string} path The path to check.
13148 * @returns {boolean} Returns `true` if `path` exists, else `false`.
13151 * var object = { 'a': { 'b': 2 } };
13152 * var other = _.create({ 'a': _.create({ 'b': 2 }) });
13154 * _.has(object, 'a');
13157 * _.has(object, 'a.b');
13160 * _.has(object, ['a', 'b']);
13163 * _.has(other, 'a');
13166 function has(object, path) {
13167 return object != null && hasPath(object, path, baseHas);
13171 * Checks if `path` is a direct or inherited property of `object`.
13177 * @param {Object} object The object to query.
13178 * @param {Array|string} path The path to check.
13179 * @returns {boolean} Returns `true` if `path` exists, else `false`.
13182 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
13184 * _.hasIn(object, 'a');
13187 * _.hasIn(object, 'a.b');
13190 * _.hasIn(object, ['a', 'b']);
13193 * _.hasIn(object, 'b');
13196 function hasIn(object, path) {
13197 return object != null && hasPath(object, path, baseHasIn);
13201 * Creates an object composed of the inverted keys and values of `object`.
13202 * If `object` contains duplicate values, subsequent values overwrite
13203 * property assignments of previous values.
13209 * @param {Object} object The object to invert.
13210 * @returns {Object} Returns the new inverted object.
13213 * var object = { 'a': 1, 'b': 2, 'c': 1 };
13215 * _.invert(object);
13216 * // => { '1': 'c', '2': 'b' }
13218 var invert = createInverter(function(result, value, key) {
13219 result[value] = key;
13220 }, constant(identity));
13223 * This method is like `_.invert` except that the inverted object is generated
13224 * from the results of running each element of `object` thru `iteratee`. The
13225 * corresponding inverted value of each inverted key is an array of keys
13226 * responsible for generating the inverted value. The iteratee is invoked
13227 * with one argument: (value).
13233 * @param {Object} object The object to invert.
13234 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
13235 * @returns {Object} Returns the new inverted object.
13238 * var object = { 'a': 1, 'b': 2, 'c': 1 };
13240 * _.invertBy(object);
13241 * // => { '1': ['a', 'c'], '2': ['b'] }
13243 * _.invertBy(object, function(value) {
13244 * return 'group' + value;
13246 * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
13248 var invertBy = createInverter(function(result, value, key) {
13249 if (hasOwnProperty.call(result, value)) {
13250 result[value].push(key);
13252 result[value] = [key];
13257 * Invokes the method at `path` of `object`.
13263 * @param {Object} object The object to query.
13264 * @param {Array|string} path The path of the method to invoke.
13265 * @param {...*} [args] The arguments to invoke the method with.
13266 * @returns {*} Returns the result of the invoked method.
13269 * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
13271 * _.invoke(object, 'a[0].b.c.slice', 1, 3);
13274 var invoke = baseRest(baseInvoke);
13277 * Creates an array of the own enumerable property names of `object`.
13279 * **Note:** Non-object values are coerced to objects. See the
13280 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
13281 * for more details.
13287 * @param {Object} object The object to query.
13288 * @returns {Array} Returns the array of property names.
13296 * Foo.prototype.c = 3;
13299 * // => ['a', 'b'] (iteration order is not guaranteed)
13304 function keys(object) {
13305 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
13309 * Creates an array of the own and inherited enumerable property names of `object`.
13311 * **Note:** Non-object values are coerced to objects.
13317 * @param {Object} object The object to query.
13318 * @returns {Array} Returns the array of property names.
13326 * Foo.prototype.c = 3;
13328 * _.keysIn(new Foo);
13329 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
13331 function keysIn(object) {
13332 return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
13336 * The opposite of `_.mapValues`; this method creates an object with the
13337 * same values as `object` and keys generated by running each own enumerable
13338 * string keyed property of `object` thru `iteratee`. The iteratee is invoked
13339 * with three arguments: (value, key, object).
13345 * @param {Object} object The object to iterate over.
13346 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13347 * @returns {Object} Returns the new mapped object.
13351 * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
13352 * return key + value;
13354 * // => { 'a1': 1, 'b2': 2 }
13356 function mapKeys(object, iteratee) {
13358 iteratee = getIteratee(iteratee, 3);
13360 baseForOwn(object, function(value, key, object) {
13361 baseAssignValue(result, iteratee(value, key, object), value);
13367 * Creates an object with the same keys as `object` and values generated
13368 * by running each own enumerable string keyed property of `object` thru
13369 * `iteratee`. The iteratee is invoked with three arguments:
13370 * (value, key, object).
13376 * @param {Object} object The object to iterate over.
13377 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13378 * @returns {Object} Returns the new mapped object.
13383 * 'fred': { 'user': 'fred', 'age': 40 },
13384 * 'pebbles': { 'user': 'pebbles', 'age': 1 }
13387 * _.mapValues(users, function(o) { return o.age; });
13388 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13390 * // The `_.property` iteratee shorthand.
13391 * _.mapValues(users, 'age');
13392 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13394 function mapValues(object, iteratee) {
13396 iteratee = getIteratee(iteratee, 3);
13398 baseForOwn(object, function(value, key, object) {
13399 baseAssignValue(result, key, iteratee(value, key, object));
13405 * This method is like `_.assign` except that it recursively merges own and
13406 * inherited enumerable string keyed properties of source objects into the
13407 * destination object. Source properties that resolve to `undefined` are
13408 * skipped if a destination value exists. Array and plain object properties
13409 * are merged recursively. Other objects and value types are overridden by
13410 * assignment. Source objects are applied from left to right. Subsequent
13411 * sources overwrite property assignments of previous sources.
13413 * **Note:** This method mutates `object`.
13419 * @param {Object} object The destination object.
13420 * @param {...Object} [sources] The source objects.
13421 * @returns {Object} Returns `object`.
13425 * 'a': [{ 'b': 2 }, { 'd': 4 }]
13429 * 'a': [{ 'c': 3 }, { 'e': 5 }]
13432 * _.merge(object, other);
13433 * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
13435 var merge = createAssigner(function(object, source, srcIndex) {
13436 baseMerge(object, source, srcIndex);
13440 * This method is like `_.merge` except that it accepts `customizer` which
13441 * is invoked to produce the merged values of the destination and source
13442 * properties. If `customizer` returns `undefined`, merging is handled by the
13443 * method instead. The `customizer` is invoked with six arguments:
13444 * (objValue, srcValue, key, object, source, stack).
13446 * **Note:** This method mutates `object`.
13452 * @param {Object} object The destination object.
13453 * @param {...Object} sources The source objects.
13454 * @param {Function} customizer The function to customize assigned values.
13455 * @returns {Object} Returns `object`.
13458 * function customizer(objValue, srcValue) {
13459 * if (_.isArray(objValue)) {
13460 * return objValue.concat(srcValue);
13464 * var object = { 'a': [1], 'b': [2] };
13465 * var other = { 'a': [3], 'b': [4] };
13467 * _.mergeWith(object, other, customizer);
13468 * // => { 'a': [1, 3], 'b': [2, 4] }
13470 var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
13471 baseMerge(object, source, srcIndex, customizer);
13475 * The opposite of `_.pick`; this method creates an object composed of the
13476 * own and inherited enumerable property paths of `object` that are not omitted.
13478 * **Note:** This method is considerably slower than `_.pick`.
13484 * @param {Object} object The source object.
13485 * @param {...(string|string[])} [paths] The property paths to omit.
13486 * @returns {Object} Returns the new object.
13489 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13491 * _.omit(object, ['a', 'c']);
13492 * // => { 'b': '2' }
13494 var omit = flatRest(function(object, paths) {
13496 if (object == null) {
13499 var isDeep = false;
13500 paths = arrayMap(paths, function(path) {
13501 path = castPath(path, object);
13502 isDeep || (isDeep = path.length > 1);
13505 copyObject(object, getAllKeysIn(object), result);
13507 result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
13509 var length = paths.length;
13511 baseUnset(result, paths[length]);
13517 * The opposite of `_.pickBy`; this method creates an object composed of
13518 * the own and inherited enumerable string keyed properties of `object` that
13519 * `predicate` doesn't return truthy for. The predicate is invoked with two
13520 * arguments: (value, key).
13526 * @param {Object} object The source object.
13527 * @param {Function} [predicate=_.identity] The function invoked per property.
13528 * @returns {Object} Returns the new object.
13531 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13533 * _.omitBy(object, _.isNumber);
13534 * // => { 'b': '2' }
13536 function omitBy(object, predicate) {
13537 return pickBy(object, negate(getIteratee(predicate)));
13541 * Creates an object composed of the picked `object` properties.
13547 * @param {Object} object The source object.
13548 * @param {...(string|string[])} [paths] The property paths to pick.
13549 * @returns {Object} Returns the new object.
13552 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13554 * _.pick(object, ['a', 'c']);
13555 * // => { 'a': 1, 'c': 3 }
13557 var pick = flatRest(function(object, paths) {
13558 return object == null ? {} : basePick(object, paths);
13562 * Creates an object composed of the `object` properties `predicate` returns
13563 * truthy for. The predicate is invoked with two arguments: (value, key).
13569 * @param {Object} object The source object.
13570 * @param {Function} [predicate=_.identity] The function invoked per property.
13571 * @returns {Object} Returns the new object.
13574 * var object = { 'a': 1, 'b': '2', 'c': 3 };
13576 * _.pickBy(object, _.isNumber);
13577 * // => { 'a': 1, 'c': 3 }
13579 function pickBy(object, predicate) {
13580 if (object == null) {
13583 var props = arrayMap(getAllKeysIn(object), function(prop) {
13586 predicate = getIteratee(predicate);
13587 return basePickBy(object, props, function(value, path) {
13588 return predicate(value, path[0]);
13593 * This method is like `_.get` except that if the resolved value is a
13594 * function it's invoked with the `this` binding of its parent object and
13595 * its result is returned.
13601 * @param {Object} object The object to query.
13602 * @param {Array|string} path The path of the property to resolve.
13603 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13604 * @returns {*} Returns the resolved value.
13607 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
13609 * _.result(object, 'a[0].b.c1');
13612 * _.result(object, 'a[0].b.c2');
13615 * _.result(object, 'a[0].b.c3', 'default');
13618 * _.result(object, 'a[0].b.c3', _.constant('default'));
13621 function result(object, path, defaultValue) {
13622 path = castPath(path, object);
13625 length = path.length;
13627 // Ensure the loop is entered when path is empty.
13630 object = undefined;
13632 while (++index < length) {
13633 var value = object == null ? undefined : object[toKey(path[index])];
13634 if (value === undefined) {
13636 value = defaultValue;
13638 object = isFunction(value) ? value.call(object) : value;
13644 * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
13645 * it's created. Arrays are created for missing index properties while objects
13646 * are created for all other missing properties. Use `_.setWith` to customize
13649 * **Note:** This method mutates `object`.
13655 * @param {Object} object The object to modify.
13656 * @param {Array|string} path The path of the property to set.
13657 * @param {*} value The value to set.
13658 * @returns {Object} Returns `object`.
13661 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13663 * _.set(object, 'a[0].b.c', 4);
13664 * console.log(object.a[0].b.c);
13667 * _.set(object, ['x', '0', 'y', 'z'], 5);
13668 * console.log(object.x[0].y.z);
13671 function set(object, path, value) {
13672 return object == null ? object : baseSet(object, path, value);
13676 * This method is like `_.set` except that it accepts `customizer` which is
13677 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
13678 * path creation is handled by the method instead. The `customizer` is invoked
13679 * with three arguments: (nsValue, key, nsObject).
13681 * **Note:** This method mutates `object`.
13687 * @param {Object} object The object to modify.
13688 * @param {Array|string} path The path of the property to set.
13689 * @param {*} value The value to set.
13690 * @param {Function} [customizer] The function to customize assigned values.
13691 * @returns {Object} Returns `object`.
13696 * _.setWith(object, '[0][1]', 'a', Object);
13697 * // => { '0': { '1': 'a' } }
13699 function setWith(object, path, value, customizer) {
13700 customizer = typeof customizer == 'function' ? customizer : undefined;
13701 return object == null ? object : baseSet(object, path, value, customizer);
13705 * Creates an array of own enumerable string keyed-value pairs for `object`
13706 * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
13707 * entries are returned.
13714 * @param {Object} object The object to query.
13715 * @returns {Array} Returns the key-value pairs.
13723 * Foo.prototype.c = 3;
13725 * _.toPairs(new Foo);
13726 * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
13728 var toPairs = createToPairs(keys);
13731 * Creates an array of own and inherited enumerable string keyed-value pairs
13732 * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
13733 * or set, its entries are returned.
13740 * @param {Object} object The object to query.
13741 * @returns {Array} Returns the key-value pairs.
13749 * Foo.prototype.c = 3;
13751 * _.toPairsIn(new Foo);
13752 * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
13754 var toPairsIn = createToPairs(keysIn);
13757 * An alternative to `_.reduce`; this method transforms `object` to a new
13758 * `accumulator` object which is the result of running each of its own
13759 * enumerable string keyed properties thru `iteratee`, with each invocation
13760 * potentially mutating the `accumulator` object. If `accumulator` is not
13761 * provided, a new object with the same `[[Prototype]]` will be used. The
13762 * iteratee is invoked with four arguments: (accumulator, value, key, object).
13763 * Iteratee functions may exit iteration early by explicitly returning `false`.
13769 * @param {Object} object The object to iterate over.
13770 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13771 * @param {*} [accumulator] The custom accumulator value.
13772 * @returns {*} Returns the accumulated value.
13775 * _.transform([2, 3, 4], function(result, n) {
13776 * result.push(n *= n);
13777 * return n % 2 == 0;
13781 * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
13782 * (result[value] || (result[value] = [])).push(key);
13784 * // => { '1': ['a', 'c'], '2': ['b'] }
13786 function transform(object, iteratee, accumulator) {
13787 var isArr = isArray(object),
13788 isArrLike = isArr || isBuffer(object) || isTypedArray(object);
13790 iteratee = getIteratee(iteratee, 4);
13791 if (accumulator == null) {
13792 var Ctor = object && object.constructor;
13794 accumulator = isArr ? new Ctor : [];
13796 else if (isObject(object)) {
13797 accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
13803 (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
13804 return iteratee(accumulator, value, index, object);
13806 return accumulator;
13810 * Removes the property at `path` of `object`.
13812 * **Note:** This method mutates `object`.
13818 * @param {Object} object The object to modify.
13819 * @param {Array|string} path The path of the property to unset.
13820 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
13823 * var object = { 'a': [{ 'b': { 'c': 7 } }] };
13824 * _.unset(object, 'a[0].b.c');
13827 * console.log(object);
13828 * // => { 'a': [{ 'b': {} }] };
13830 * _.unset(object, ['a', '0', 'b', 'c']);
13833 * console.log(object);
13834 * // => { 'a': [{ 'b': {} }] };
13836 function unset(object, path) {
13837 return object == null ? true : baseUnset(object, path);
13841 * This method is like `_.set` except that accepts `updater` to produce the
13842 * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13843 * is invoked with one argument: (value).
13845 * **Note:** This method mutates `object`.
13851 * @param {Object} object The object to modify.
13852 * @param {Array|string} path The path of the property to set.
13853 * @param {Function} updater The function to produce the updated value.
13854 * @returns {Object} Returns `object`.
13857 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13859 * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13860 * console.log(object.a[0].b.c);
13863 * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13864 * console.log(object.x[0].y.z);
13867 function update(object, path, updater) {
13868 return object == null ? object : baseUpdate(object, path, castFunction(updater));
13872 * This method is like `_.update` except that it accepts `customizer` which is
13873 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
13874 * path creation is handled by the method instead. The `customizer` is invoked
13875 * with three arguments: (nsValue, key, nsObject).
13877 * **Note:** This method mutates `object`.
13883 * @param {Object} object The object to modify.
13884 * @param {Array|string} path The path of the property to set.
13885 * @param {Function} updater The function to produce the updated value.
13886 * @param {Function} [customizer] The function to customize assigned values.
13887 * @returns {Object} Returns `object`.
13892 * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13893 * // => { '0': { '1': 'a' } }
13895 function updateWith(object, path, updater, customizer) {
13896 customizer = typeof customizer == 'function' ? customizer : undefined;
13897 return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13901 * Creates an array of the own enumerable string keyed property values of `object`.
13903 * **Note:** Non-object values are coerced to objects.
13909 * @param {Object} object The object to query.
13910 * @returns {Array} Returns the array of property values.
13918 * Foo.prototype.c = 3;
13920 * _.values(new Foo);
13921 * // => [1, 2] (iteration order is not guaranteed)
13926 function values(object) {
13927 return object == null ? [] : baseValues(object, keys(object));
13931 * Creates an array of the own and inherited enumerable string keyed property
13932 * values of `object`.
13934 * **Note:** Non-object values are coerced to objects.
13940 * @param {Object} object The object to query.
13941 * @returns {Array} Returns the array of property values.
13949 * Foo.prototype.c = 3;
13951 * _.valuesIn(new Foo);
13952 * // => [1, 2, 3] (iteration order is not guaranteed)
13954 function valuesIn(object) {
13955 return object == null ? [] : baseValues(object, keysIn(object));
13958 /*------------------------------------------------------------------------*/
13961 * Clamps `number` within the inclusive `lower` and `upper` bounds.
13967 * @param {number} number The number to clamp.
13968 * @param {number} [lower] The lower bound.
13969 * @param {number} upper The upper bound.
13970 * @returns {number} Returns the clamped number.
13973 * _.clamp(-10, -5, 5);
13976 * _.clamp(10, -5, 5);
13979 function clamp(number, lower, upper) {
13980 if (upper === undefined) {
13984 if (upper !== undefined) {
13985 upper = toNumber(upper);
13986 upper = upper === upper ? upper : 0;
13988 if (lower !== undefined) {
13989 lower = toNumber(lower);
13990 lower = lower === lower ? lower : 0;
13992 return baseClamp(toNumber(number), lower, upper);
13996 * Checks if `n` is between `start` and up to, but not including, `end`. If
13997 * `end` is not specified, it's set to `start` with `start` then set to `0`.
13998 * If `start` is greater than `end` the params are swapped to support
14005 * @param {number} number The number to check.
14006 * @param {number} [start=0] The start of the range.
14007 * @param {number} end The end of the range.
14008 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
14009 * @see _.range, _.rangeRight
14012 * _.inRange(3, 2, 4);
14024 * _.inRange(1.2, 2);
14027 * _.inRange(5.2, 4);
14030 * _.inRange(-3, -2, -6);
14033 function inRange(number, start, end) {
14034 start = toFinite(start);
14035 if (end === undefined) {
14039 end = toFinite(end);
14041 number = toNumber(number);
14042 return baseInRange(number, start, end);
14046 * Produces a random number between the inclusive `lower` and `upper` bounds.
14047 * If only one argument is provided a number between `0` and the given number
14048 * is returned. If `floating` is `true`, or either `lower` or `upper` are
14049 * floats, a floating-point number is returned instead of an integer.
14051 * **Note:** JavaScript follows the IEEE-754 standard for resolving
14052 * floating-point values which can produce unexpected results.
14058 * @param {number} [lower=0] The lower bound.
14059 * @param {number} [upper=1] The upper bound.
14060 * @param {boolean} [floating] Specify returning a floating-point number.
14061 * @returns {number} Returns the random number.
14065 * // => an integer between 0 and 5
14068 * // => also an integer between 0 and 5
14070 * _.random(5, true);
14071 * // => a floating-point number between 0 and 5
14073 * _.random(1.2, 5.2);
14074 * // => a floating-point number between 1.2 and 5.2
14076 function random(lower, upper, floating) {
14077 if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
14078 upper = floating = undefined;
14080 if (floating === undefined) {
14081 if (typeof upper == 'boolean') {
14085 else if (typeof lower == 'boolean') {
14090 if (lower === undefined && upper === undefined) {
14095 lower = toFinite(lower);
14096 if (upper === undefined) {
14100 upper = toFinite(upper);
14103 if (lower > upper) {
14108 if (floating || lower % 1 || upper % 1) {
14109 var rand = nativeRandom();
14110 return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
14112 return baseRandom(lower, upper);
14115 /*------------------------------------------------------------------------*/
14118 * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
14124 * @param {string} [string=''] The string to convert.
14125 * @returns {string} Returns the camel cased string.
14128 * _.camelCase('Foo Bar');
14131 * _.camelCase('--foo-bar--');
14134 * _.camelCase('__FOO_BAR__');
14137 var camelCase = createCompounder(function(result, word, index) {
14138 word = word.toLowerCase();
14139 return result + (index ? capitalize(word) : word);
14143 * Converts the first character of `string` to upper case and the remaining
14150 * @param {string} [string=''] The string to capitalize.
14151 * @returns {string} Returns the capitalized string.
14154 * _.capitalize('FRED');
14157 function capitalize(string) {
14158 return upperFirst(toString(string).toLowerCase());
14162 * Deburrs `string` by converting
14163 * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
14164 * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
14165 * letters to basic Latin letters and removing
14166 * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
14172 * @param {string} [string=''] The string to deburr.
14173 * @returns {string} Returns the deburred string.
14176 * _.deburr('déjà vu');
14179 function deburr(string) {
14180 string = toString(string);
14181 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
14185 * Checks if `string` ends with the given target string.
14191 * @param {string} [string=''] The string to inspect.
14192 * @param {string} [target] The string to search for.
14193 * @param {number} [position=string.length] The position to search up to.
14194 * @returns {boolean} Returns `true` if `string` ends with `target`,
14198 * _.endsWith('abc', 'c');
14201 * _.endsWith('abc', 'b');
14204 * _.endsWith('abc', 'b', 2);
14207 function endsWith(string, target, position) {
14208 string = toString(string);
14209 target = baseToString(target);
14211 var length = string.length;
14212 position = position === undefined
14214 : baseClamp(toInteger(position), 0, length);
14216 var end = position;
14217 position -= target.length;
14218 return position >= 0 && string.slice(position, end) == target;
14222 * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
14223 * corresponding HTML entities.
14225 * **Note:** No other characters are escaped. To escape additional
14226 * characters use a third-party library like [_he_](https://mths.be/he).
14228 * Though the ">" character is escaped for symmetry, characters like
14229 * ">" and "/" don't need escaping in HTML and have no special meaning
14230 * unless they're part of a tag or unquoted attribute value. See
14231 * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
14232 * (under "semi-related fun fact") for more details.
14234 * When working with HTML you should always
14235 * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
14242 * @param {string} [string=''] The string to escape.
14243 * @returns {string} Returns the escaped string.
14246 * _.escape('fred, barney, & pebbles');
14247 * // => 'fred, barney, & pebbles'
14249 function escape(string) {
14250 string = toString(string);
14251 return (string && reHasUnescapedHtml.test(string))
14252 ? string.replace(reUnescapedHtml, escapeHtmlChar)
14257 * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
14258 * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
14264 * @param {string} [string=''] The string to escape.
14265 * @returns {string} Returns the escaped string.
14268 * _.escapeRegExp('[lodash](https://lodash.com/)');
14269 * // => '\[lodash\]\(https://lodash\.com/\)'
14271 function escapeRegExp(string) {
14272 string = toString(string);
14273 return (string && reHasRegExpChar.test(string))
14274 ? string.replace(reRegExpChar, '\\$&')
14279 * Converts `string` to
14280 * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
14286 * @param {string} [string=''] The string to convert.
14287 * @returns {string} Returns the kebab cased string.
14290 * _.kebabCase('Foo Bar');
14293 * _.kebabCase('fooBar');
14296 * _.kebabCase('__FOO_BAR__');
14299 var kebabCase = createCompounder(function(result, word, index) {
14300 return result + (index ? '-' : '') + word.toLowerCase();
14304 * Converts `string`, as space separated words, to lower case.
14310 * @param {string} [string=''] The string to convert.
14311 * @returns {string} Returns the lower cased string.
14314 * _.lowerCase('--Foo-Bar--');
14317 * _.lowerCase('fooBar');
14320 * _.lowerCase('__FOO_BAR__');
14323 var lowerCase = createCompounder(function(result, word, index) {
14324 return result + (index ? ' ' : '') + word.toLowerCase();
14328 * Converts the first character of `string` to lower case.
14334 * @param {string} [string=''] The string to convert.
14335 * @returns {string} Returns the converted string.
14338 * _.lowerFirst('Fred');
14341 * _.lowerFirst('FRED');
14344 var lowerFirst = createCaseFirst('toLowerCase');
14347 * Pads `string` on the left and right sides if it's shorter than `length`.
14348 * Padding characters are truncated if they can't be evenly divided by `length`.
14354 * @param {string} [string=''] The string to pad.
14355 * @param {number} [length=0] The padding length.
14356 * @param {string} [chars=' '] The string used as padding.
14357 * @returns {string} Returns the padded string.
14363 * _.pad('abc', 8, '_-');
14369 function pad(string, length, chars) {
14370 string = toString(string);
14371 length = toInteger(length);
14373 var strLength = length ? stringSize(string) : 0;
14374 if (!length || strLength >= length) {
14377 var mid = (length - strLength) / 2;
14379 createPadding(nativeFloor(mid), chars) +
14381 createPadding(nativeCeil(mid), chars)
14386 * Pads `string` on the right side if it's shorter than `length`. Padding
14387 * characters are truncated if they exceed `length`.
14393 * @param {string} [string=''] The string to pad.
14394 * @param {number} [length=0] The padding length.
14395 * @param {string} [chars=' '] The string used as padding.
14396 * @returns {string} Returns the padded string.
14399 * _.padEnd('abc', 6);
14402 * _.padEnd('abc', 6, '_-');
14405 * _.padEnd('abc', 3);
14408 function padEnd(string, length, chars) {
14409 string = toString(string);
14410 length = toInteger(length);
14412 var strLength = length ? stringSize(string) : 0;
14413 return (length && strLength < length)
14414 ? (string + createPadding(length - strLength, chars))
14419 * Pads `string` on the left side if it's shorter than `length`. Padding
14420 * characters are truncated if they exceed `length`.
14426 * @param {string} [string=''] The string to pad.
14427 * @param {number} [length=0] The padding length.
14428 * @param {string} [chars=' '] The string used as padding.
14429 * @returns {string} Returns the padded string.
14432 * _.padStart('abc', 6);
14435 * _.padStart('abc', 6, '_-');
14438 * _.padStart('abc', 3);
14441 function padStart(string, length, chars) {
14442 string = toString(string);
14443 length = toInteger(length);
14445 var strLength = length ? stringSize(string) : 0;
14446 return (length && strLength < length)
14447 ? (createPadding(length - strLength, chars) + string)
14452 * Converts `string` to an integer of the specified radix. If `radix` is
14453 * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
14454 * hexadecimal, in which case a `radix` of `16` is used.
14456 * **Note:** This method aligns with the
14457 * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
14463 * @param {string} string The string to convert.
14464 * @param {number} [radix=10] The radix to interpret `value` by.
14465 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14466 * @returns {number} Returns the converted integer.
14469 * _.parseInt('08');
14472 * _.map(['6', '08', '10'], _.parseInt);
14475 function parseInt(string, radix, guard) {
14476 if (guard || radix == null) {
14478 } else if (radix) {
14481 return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
14485 * Repeats the given string `n` times.
14491 * @param {string} [string=''] The string to repeat.
14492 * @param {number} [n=1] The number of times to repeat the string.
14493 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14494 * @returns {string} Returns the repeated string.
14497 * _.repeat('*', 3);
14500 * _.repeat('abc', 2);
14503 * _.repeat('abc', 0);
14506 function repeat(string, n, guard) {
14507 if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
14512 return baseRepeat(toString(string), n);
14516 * Replaces matches for `pattern` in `string` with `replacement`.
14518 * **Note:** This method is based on
14519 * [`String#replace`](https://mdn.io/String/replace).
14525 * @param {string} [string=''] The string to modify.
14526 * @param {RegExp|string} pattern The pattern to replace.
14527 * @param {Function|string} replacement The match replacement.
14528 * @returns {string} Returns the modified string.
14531 * _.replace('Hi Fred', 'Fred', 'Barney');
14532 * // => 'Hi Barney'
14534 function replace() {
14535 var args = arguments,
14536 string = toString(args[0]);
14538 return args.length < 3 ? string : string.replace(args[1], args[2]);
14542 * Converts `string` to
14543 * [snake case](https://en.wikipedia.org/wiki/Snake_case).
14549 * @param {string} [string=''] The string to convert.
14550 * @returns {string} Returns the snake cased string.
14553 * _.snakeCase('Foo Bar');
14556 * _.snakeCase('fooBar');
14559 * _.snakeCase('--FOO-BAR--');
14562 var snakeCase = createCompounder(function(result, word, index) {
14563 return result + (index ? '_' : '') + word.toLowerCase();
14567 * Splits `string` by `separator`.
14569 * **Note:** This method is based on
14570 * [`String#split`](https://mdn.io/String/split).
14576 * @param {string} [string=''] The string to split.
14577 * @param {RegExp|string} separator The separator pattern to split by.
14578 * @param {number} [limit] The length to truncate results to.
14579 * @returns {Array} Returns the string segments.
14582 * _.split('a-b-c', '-', 2);
14585 function split(string, separator, limit) {
14586 if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
14587 separator = limit = undefined;
14589 limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
14593 string = toString(string);
14595 typeof separator == 'string' ||
14596 (separator != null && !isRegExp(separator))
14598 separator = baseToString(separator);
14599 if (!separator && hasUnicode(string)) {
14600 return castSlice(stringToArray(string), 0, limit);
14603 return string.split(separator, limit);
14607 * Converts `string` to
14608 * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
14614 * @param {string} [string=''] The string to convert.
14615 * @returns {string} Returns the start cased string.
14618 * _.startCase('--foo-bar--');
14621 * _.startCase('fooBar');
14624 * _.startCase('__FOO_BAR__');
14627 var startCase = createCompounder(function(result, word, index) {
14628 return result + (index ? ' ' : '') + upperFirst(word);
14632 * Checks if `string` starts with the given target string.
14638 * @param {string} [string=''] The string to inspect.
14639 * @param {string} [target] The string to search for.
14640 * @param {number} [position=0] The position to search from.
14641 * @returns {boolean} Returns `true` if `string` starts with `target`,
14645 * _.startsWith('abc', 'a');
14648 * _.startsWith('abc', 'b');
14651 * _.startsWith('abc', 'b', 1);
14654 function startsWith(string, target, position) {
14655 string = toString(string);
14656 position = position == null
14658 : baseClamp(toInteger(position), 0, string.length);
14660 target = baseToString(target);
14661 return string.slice(position, position + target.length) == target;
14665 * Creates a compiled template function that can interpolate data properties
14666 * in "interpolate" delimiters, HTML-escape interpolated data properties in
14667 * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
14668 * properties may be accessed as free variables in the template. If a setting
14669 * object is given, it takes precedence over `_.templateSettings` values.
14671 * **Note:** In the development build `_.template` utilizes
14672 * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
14673 * for easier debugging.
14675 * For more information on precompiling templates see
14676 * [lodash's custom builds documentation](https://lodash.com/custom-builds).
14678 * For more information on Chrome extension sandboxes see
14679 * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
14685 * @param {string} [string=''] The template string.
14686 * @param {Object} [options={}] The options object.
14687 * @param {RegExp} [options.escape=_.templateSettings.escape]
14688 * The HTML "escape" delimiter.
14689 * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
14690 * The "evaluate" delimiter.
14691 * @param {Object} [options.imports=_.templateSettings.imports]
14692 * An object to import into the template as free variables.
14693 * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
14694 * The "interpolate" delimiter.
14695 * @param {string} [options.sourceURL='lodash.templateSources[n]']
14696 * The sourceURL of the compiled template.
14697 * @param {string} [options.variable='obj']
14698 * The data object variable name.
14699 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14700 * @returns {Function} Returns the compiled template function.
14703 * // Use the "interpolate" delimiter to create a compiled template.
14704 * var compiled = _.template('hello <%= user %>!');
14705 * compiled({ 'user': 'fred' });
14706 * // => 'hello fred!'
14708 * // Use the HTML "escape" delimiter to escape data property values.
14709 * var compiled = _.template('<b><%- value %></b>');
14710 * compiled({ 'value': '<script>' });
14711 * // => '<b><script></b>'
14713 * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
14714 * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
14715 * compiled({ 'users': ['fred', 'barney'] });
14716 * // => '<li>fred</li><li>barney</li>'
14718 * // Use the internal `print` function in "evaluate" delimiters.
14719 * var compiled = _.template('<% print("hello " + user); %>!');
14720 * compiled({ 'user': 'barney' });
14721 * // => 'hello barney!'
14723 * // Use the ES template literal delimiter as an "interpolate" delimiter.
14724 * // Disable support by replacing the "interpolate" delimiter.
14725 * var compiled = _.template('hello ${ user }!');
14726 * compiled({ 'user': 'pebbles' });
14727 * // => 'hello pebbles!'
14729 * // Use backslashes to treat delimiters as plain text.
14730 * var compiled = _.template('<%= "\\<%- value %\\>" %>');
14731 * compiled({ 'value': 'ignored' });
14732 * // => '<%- value %>'
14734 * // Use the `imports` option to import `jQuery` as `jq`.
14735 * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
14736 * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
14737 * compiled({ 'users': ['fred', 'barney'] });
14738 * // => '<li>fred</li><li>barney</li>'
14740 * // Use the `sourceURL` option to specify a custom sourceURL for the template.
14741 * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
14743 * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
14745 * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
14746 * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
14748 * // => function(data) {
14749 * // var __t, __p = '';
14750 * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
14754 * // Use custom template delimiters.
14755 * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
14756 * var compiled = _.template('hello {{ user }}!');
14757 * compiled({ 'user': 'mustache' });
14758 * // => 'hello mustache!'
14760 * // Use the `source` property to inline compiled templates for meaningful
14761 * // line numbers in error messages and stack traces.
14762 * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
14764 * "main": ' + _.template(mainText).source + '\
14768 function template(string, options, guard) {
14769 // Based on John Resig's `tmpl` implementation
14770 // (http://ejohn.org/blog/javascript-micro-templating/)
14771 // and Laura Doktorova's doT.js (https://github.com/olado/doT).
14772 var settings = lodash.templateSettings;
14774 if (guard && isIterateeCall(string, options, guard)) {
14775 options = undefined;
14777 string = toString(string);
14778 options = assignInWith({}, options, settings, customDefaultsAssignIn);
14780 var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
14781 importsKeys = keys(imports),
14782 importsValues = baseValues(imports, importsKeys);
14787 interpolate = options.interpolate || reNoMatch,
14788 source = "__p += '";
14790 // Compile the regexp to match each delimiter.
14791 var reDelimiters = RegExp(
14792 (options.escape || reNoMatch).source + '|' +
14793 interpolate.source + '|' +
14794 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
14795 (options.evaluate || reNoMatch).source + '|$'
14798 // Use a sourceURL for easier debugging.
14799 var sourceURL = '//# sourceURL=' +
14800 ('sourceURL' in options
14801 ? options.sourceURL
14802 : ('lodash.templateSources[' + (++templateCounter) + ']')
14805 string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
14806 interpolateValue || (interpolateValue = esTemplateValue);
14808 // Escape characters that can't be included in string literals.
14809 source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
14811 // Replace delimiters with snippets.
14814 source += "' +\n__e(" + escapeValue + ") +\n'";
14816 if (evaluateValue) {
14817 isEvaluating = true;
14818 source += "';\n" + evaluateValue + ";\n__p += '";
14820 if (interpolateValue) {
14821 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
14823 index = offset + match.length;
14825 // The JS engine embedded in Adobe products needs `match` returned in
14826 // order to produce the correct `offset` value.
14832 // If `variable` is not specified wrap a with-statement around the generated
14833 // code to add the data object to the top of the scope chain.
14834 var variable = options.variable;
14836 source = 'with (obj) {\n' + source + '\n}\n';
14838 // Cleanup code by stripping empty strings.
14839 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14840 .replace(reEmptyStringMiddle, '$1')
14841 .replace(reEmptyStringTrailing, '$1;');
14843 // Frame code as the function body.
14844 source = 'function(' + (variable || 'obj') + ') {\n' +
14847 : 'obj || (obj = {});\n'
14849 "var __t, __p = ''" +
14851 ? ', __e = _.escape'
14855 ? ', __j = Array.prototype.join;\n' +
14856 "function print() { __p += __j.call(arguments, '') }\n"
14862 var result = attempt(function() {
14863 return Function(importsKeys, sourceURL + 'return ' + source)
14864 .apply(undefined, importsValues);
14867 // Provide the compiled function's source by its `toString` method or
14868 // the `source` property as a convenience for inlining compiled templates.
14869 result.source = source;
14870 if (isError(result)) {
14877 * Converts `string`, as a whole, to lower case just like
14878 * [String#toLowerCase](https://mdn.io/toLowerCase).
14884 * @param {string} [string=''] The string to convert.
14885 * @returns {string} Returns the lower cased string.
14888 * _.toLower('--Foo-Bar--');
14889 * // => '--foo-bar--'
14891 * _.toLower('fooBar');
14894 * _.toLower('__FOO_BAR__');
14895 * // => '__foo_bar__'
14897 function toLower(value) {
14898 return toString(value).toLowerCase();
14902 * Converts `string`, as a whole, to upper case just like
14903 * [String#toUpperCase](https://mdn.io/toUpperCase).
14909 * @param {string} [string=''] The string to convert.
14910 * @returns {string} Returns the upper cased string.
14913 * _.toUpper('--foo-bar--');
14914 * // => '--FOO-BAR--'
14916 * _.toUpper('fooBar');
14919 * _.toUpper('__foo_bar__');
14920 * // => '__FOO_BAR__'
14922 function toUpper(value) {
14923 return toString(value).toUpperCase();
14927 * Removes leading and trailing whitespace or specified characters from `string`.
14933 * @param {string} [string=''] The string to trim.
14934 * @param {string} [chars=whitespace] The characters to trim.
14935 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14936 * @returns {string} Returns the trimmed string.
14942 * _.trim('-_-abc-_-', '_-');
14945 * _.map([' foo ', ' bar '], _.trim);
14946 * // => ['foo', 'bar']
14948 function trim(string, chars, guard) {
14949 string = toString(string);
14950 if (string && (guard || chars === undefined)) {
14951 return string.replace(reTrim, '');
14953 if (!string || !(chars = baseToString(chars))) {
14956 var strSymbols = stringToArray(string),
14957 chrSymbols = stringToArray(chars),
14958 start = charsStartIndex(strSymbols, chrSymbols),
14959 end = charsEndIndex(strSymbols, chrSymbols) + 1;
14961 return castSlice(strSymbols, start, end).join('');
14965 * Removes trailing whitespace or specified characters from `string`.
14971 * @param {string} [string=''] The string to trim.
14972 * @param {string} [chars=whitespace] The characters to trim.
14973 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14974 * @returns {string} Returns the trimmed string.
14977 * _.trimEnd(' abc ');
14980 * _.trimEnd('-_-abc-_-', '_-');
14983 function trimEnd(string, chars, guard) {
14984 string = toString(string);
14985 if (string && (guard || chars === undefined)) {
14986 return string.replace(reTrimEnd, '');
14988 if (!string || !(chars = baseToString(chars))) {
14991 var strSymbols = stringToArray(string),
14992 end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
14994 return castSlice(strSymbols, 0, end).join('');
14998 * Removes leading whitespace or specified characters from `string`.
15004 * @param {string} [string=''] The string to trim.
15005 * @param {string} [chars=whitespace] The characters to trim.
15006 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15007 * @returns {string} Returns the trimmed string.
15010 * _.trimStart(' abc ');
15013 * _.trimStart('-_-abc-_-', '_-');
15016 function trimStart(string, chars, guard) {
15017 string = toString(string);
15018 if (string && (guard || chars === undefined)) {
15019 return string.replace(reTrimStart, '');
15021 if (!string || !(chars = baseToString(chars))) {
15024 var strSymbols = stringToArray(string),
15025 start = charsStartIndex(strSymbols, stringToArray(chars));
15027 return castSlice(strSymbols, start).join('');
15031 * Truncates `string` if it's longer than the given maximum string length.
15032 * The last characters of the truncated string are replaced with the omission
15033 * string which defaults to "...".
15039 * @param {string} [string=''] The string to truncate.
15040 * @param {Object} [options={}] The options object.
15041 * @param {number} [options.length=30] The maximum string length.
15042 * @param {string} [options.omission='...'] The string to indicate text is omitted.
15043 * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
15044 * @returns {string} Returns the truncated string.
15047 * _.truncate('hi-diddly-ho there, neighborino');
15048 * // => 'hi-diddly-ho there, neighbo...'
15050 * _.truncate('hi-diddly-ho there, neighborino', {
15054 * // => 'hi-diddly-ho there,...'
15056 * _.truncate('hi-diddly-ho there, neighborino', {
15058 * 'separator': /,? +/
15060 * // => 'hi-diddly-ho there...'
15062 * _.truncate('hi-diddly-ho there, neighborino', {
15063 * 'omission': ' [...]'
15065 * // => 'hi-diddly-ho there, neig [...]'
15067 function truncate(string, options) {
15068 var length = DEFAULT_TRUNC_LENGTH,
15069 omission = DEFAULT_TRUNC_OMISSION;
15071 if (isObject(options)) {
15072 var separator = 'separator' in options ? options.separator : separator;
15073 length = 'length' in options ? toInteger(options.length) : length;
15074 omission = 'omission' in options ? baseToString(options.omission) : omission;
15076 string = toString(string);
15078 var strLength = string.length;
15079 if (hasUnicode(string)) {
15080 var strSymbols = stringToArray(string);
15081 strLength = strSymbols.length;
15083 if (length >= strLength) {
15086 var end = length - stringSize(omission);
15090 var result = strSymbols
15091 ? castSlice(strSymbols, 0, end).join('')
15092 : string.slice(0, end);
15094 if (separator === undefined) {
15095 return result + omission;
15098 end += (result.length - end);
15100 if (isRegExp(separator)) {
15101 if (string.slice(end).search(separator)) {
15103 substring = result;
15105 if (!separator.global) {
15106 separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
15108 separator.lastIndex = 0;
15109 while ((match = separator.exec(substring))) {
15110 var newEnd = match.index;
15112 result = result.slice(0, newEnd === undefined ? end : newEnd);
15114 } else if (string.indexOf(baseToString(separator), end) != end) {
15115 var index = result.lastIndexOf(separator);
15117 result = result.slice(0, index);
15120 return result + omission;
15124 * The inverse of `_.escape`; this method converts the HTML entities
15125 * `&`, `<`, `>`, `"`, and `'` in `string` to
15126 * their corresponding characters.
15128 * **Note:** No other HTML entities are unescaped. To unescape additional
15129 * HTML entities use a third-party library like [_he_](https://mths.be/he).
15135 * @param {string} [string=''] The string to unescape.
15136 * @returns {string} Returns the unescaped string.
15139 * _.unescape('fred, barney, & pebbles');
15140 * // => 'fred, barney, & pebbles'
15142 function unescape(string) {
15143 string = toString(string);
15144 return (string && reHasEscapedHtml.test(string))
15145 ? string.replace(reEscapedHtml, unescapeHtmlChar)
15150 * Converts `string`, as space separated words, to upper case.
15156 * @param {string} [string=''] The string to convert.
15157 * @returns {string} Returns the upper cased string.
15160 * _.upperCase('--foo-bar');
15163 * _.upperCase('fooBar');
15166 * _.upperCase('__foo_bar__');
15169 var upperCase = createCompounder(function(result, word, index) {
15170 return result + (index ? ' ' : '') + word.toUpperCase();
15174 * Converts the first character of `string` to upper case.
15180 * @param {string} [string=''] The string to convert.
15181 * @returns {string} Returns the converted string.
15184 * _.upperFirst('fred');
15187 * _.upperFirst('FRED');
15190 var upperFirst = createCaseFirst('toUpperCase');
15193 * Splits `string` into an array of its words.
15199 * @param {string} [string=''] The string to inspect.
15200 * @param {RegExp|string} [pattern] The pattern to match words.
15201 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15202 * @returns {Array} Returns the words of `string`.
15205 * _.words('fred, barney, & pebbles');
15206 * // => ['fred', 'barney', 'pebbles']
15208 * _.words('fred, barney, & pebbles', /[^, ]+/g);
15209 * // => ['fred', 'barney', '&', 'pebbles']
15211 function words(string, pattern, guard) {
15212 string = toString(string);
15213 pattern = guard ? undefined : pattern;
15215 if (pattern === undefined) {
15216 return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
15218 return string.match(pattern) || [];
15221 /*------------------------------------------------------------------------*/
15224 * Attempts to invoke `func`, returning either the result or the caught error
15225 * object. Any additional arguments are provided to `func` when it's invoked.
15231 * @param {Function} func The function to attempt.
15232 * @param {...*} [args] The arguments to invoke `func` with.
15233 * @returns {*} Returns the `func` result or error object.
15236 * // Avoid throwing errors for invalid selectors.
15237 * var elements = _.attempt(function(selector) {
15238 * return document.querySelectorAll(selector);
15241 * if (_.isError(elements)) {
15245 var attempt = baseRest(function(func, args) {
15247 return apply(func, undefined, args);
15249 return isError(e) ? e : new Error(e);
15254 * Binds methods of an object to the object itself, overwriting the existing
15257 * **Note:** This method doesn't set the "length" property of bound functions.
15263 * @param {Object} object The object to bind and assign the bound methods to.
15264 * @param {...(string|string[])} methodNames The object method names to bind.
15265 * @returns {Object} Returns `object`.
15270 * 'click': function() {
15271 * console.log('clicked ' + this.label);
15275 * _.bindAll(view, ['click']);
15276 * jQuery(element).on('click', view.click);
15277 * // => Logs 'clicked docs' when clicked.
15279 var bindAll = flatRest(function(object, methodNames) {
15280 arrayEach(methodNames, function(key) {
15282 baseAssignValue(object, key, bind(object[key], object));
15288 * Creates a function that iterates over `pairs` and invokes the corresponding
15289 * function of the first predicate to return truthy. The predicate-function
15290 * pairs are invoked with the `this` binding and arguments of the created
15297 * @param {Array} pairs The predicate-function pairs.
15298 * @returns {Function} Returns the new composite function.
15301 * var func = _.cond([
15302 * [_.matches({ 'a': 1 }), _.constant('matches A')],
15303 * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
15304 * [_.stubTrue, _.constant('no match')]
15307 * func({ 'a': 1, 'b': 2 });
15308 * // => 'matches A'
15310 * func({ 'a': 0, 'b': 1 });
15311 * // => 'matches B'
15313 * func({ 'a': '1', 'b': '2' });
15316 function cond(pairs) {
15317 var length = pairs == null ? 0 : pairs.length,
15318 toIteratee = getIteratee();
15320 pairs = !length ? [] : arrayMap(pairs, function(pair) {
15321 if (typeof pair[1] != 'function') {
15322 throw new TypeError(FUNC_ERROR_TEXT);
15324 return [toIteratee(pair[0]), pair[1]];
15327 return baseRest(function(args) {
15329 while (++index < length) {
15330 var pair = pairs[index];
15331 if (apply(pair[0], this, args)) {
15332 return apply(pair[1], this, args);
15339 * Creates a function that invokes the predicate properties of `source` with
15340 * the corresponding property values of a given object, returning `true` if
15341 * all predicates return truthy, else `false`.
15343 * **Note:** The created function is equivalent to `_.conformsTo` with
15344 * `source` partially applied.
15350 * @param {Object} source The object of property predicates to conform to.
15351 * @returns {Function} Returns the new spec function.
15355 * { 'a': 2, 'b': 1 },
15356 * { 'a': 1, 'b': 2 }
15359 * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
15360 * // => [{ 'a': 1, 'b': 2 }]
15362 function conforms(source) {
15363 return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
15367 * Creates a function that returns `value`.
15373 * @param {*} value The value to return from the new function.
15374 * @returns {Function} Returns the new constant function.
15377 * var objects = _.times(2, _.constant({ 'a': 1 }));
15379 * console.log(objects);
15380 * // => [{ 'a': 1 }, { 'a': 1 }]
15382 * console.log(objects[0] === objects[1]);
15385 function constant(value) {
15386 return function() {
15392 * Checks `value` to determine whether a default value should be returned in
15393 * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
15400 * @param {*} value The value to check.
15401 * @param {*} defaultValue The default value.
15402 * @returns {*} Returns the resolved value.
15405 * _.defaultTo(1, 10);
15408 * _.defaultTo(undefined, 10);
15411 function defaultTo(value, defaultValue) {
15412 return (value == null || value !== value) ? defaultValue : value;
15416 * Creates a function that returns the result of invoking the given functions
15417 * with the `this` binding of the created function, where each successive
15418 * invocation is supplied the return value of the previous.
15424 * @param {...(Function|Function[])} [funcs] The functions to invoke.
15425 * @returns {Function} Returns the new composite function.
15429 * function square(n) {
15433 * var addSquare = _.flow([_.add, square]);
15437 var flow = createFlow();
15440 * This method is like `_.flow` except that it creates a function that
15441 * invokes the given functions from right to left.
15447 * @param {...(Function|Function[])} [funcs] The functions to invoke.
15448 * @returns {Function} Returns the new composite function.
15452 * function square(n) {
15456 * var addSquare = _.flowRight([square, _.add]);
15460 var flowRight = createFlow(true);
15463 * This method returns the first argument it receives.
15469 * @param {*} value Any value.
15470 * @returns {*} Returns `value`.
15473 * var object = { 'a': 1 };
15475 * console.log(_.identity(object) === object);
15478 function identity(value) {
15483 * Creates a function that invokes `func` with the arguments of the created
15484 * function. If `func` is a property name, the created function returns the
15485 * property value for a given element. If `func` is an array or object, the
15486 * created function returns `true` for elements that contain the equivalent
15487 * source properties, otherwise it returns `false`.
15493 * @param {*} [func=_.identity] The value to convert to a callback.
15494 * @returns {Function} Returns the callback.
15498 * { 'user': 'barney', 'age': 36, 'active': true },
15499 * { 'user': 'fred', 'age': 40, 'active': false }
15502 * // The `_.matches` iteratee shorthand.
15503 * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
15504 * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
15506 * // The `_.matchesProperty` iteratee shorthand.
15507 * _.filter(users, _.iteratee(['user', 'fred']));
15508 * // => [{ 'user': 'fred', 'age': 40 }]
15510 * // The `_.property` iteratee shorthand.
15511 * _.map(users, _.iteratee('user'));
15512 * // => ['barney', 'fred']
15514 * // Create custom iteratee shorthands.
15515 * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
15516 * return !_.isRegExp(func) ? iteratee(func) : function(string) {
15517 * return func.test(string);
15521 * _.filter(['abc', 'def'], /ef/);
15524 function iteratee(func) {
15525 return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
15529 * Creates a function that performs a partial deep comparison between a given
15530 * object and `source`, returning `true` if the given object has equivalent
15531 * property values, else `false`.
15533 * **Note:** The created function is equivalent to `_.isMatch` with `source`
15534 * partially applied.
15536 * Partial comparisons will match empty array and empty object `source`
15537 * values against any array or object value, respectively. See `_.isEqual`
15538 * for a list of supported value comparisons.
15544 * @param {Object} source The object of property values to match.
15545 * @returns {Function} Returns the new spec function.
15549 * { 'a': 1, 'b': 2, 'c': 3 },
15550 * { 'a': 4, 'b': 5, 'c': 6 }
15553 * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
15554 * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
15556 function matches(source) {
15557 return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
15561 * Creates a function that performs a partial deep comparison between the
15562 * value at `path` of a given object to `srcValue`, returning `true` if the
15563 * object value is equivalent, else `false`.
15565 * **Note:** Partial comparisons will match empty array and empty object
15566 * `srcValue` values against any array or object value, respectively. See
15567 * `_.isEqual` for a list of supported value comparisons.
15573 * @param {Array|string} path The path of the property to get.
15574 * @param {*} srcValue The value to match.
15575 * @returns {Function} Returns the new spec function.
15579 * { 'a': 1, 'b': 2, 'c': 3 },
15580 * { 'a': 4, 'b': 5, 'c': 6 }
15583 * _.find(objects, _.matchesProperty('a', 4));
15584 * // => { 'a': 4, 'b': 5, 'c': 6 }
15586 function matchesProperty(path, srcValue) {
15587 return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
15591 * Creates a function that invokes the method at `path` of a given object.
15592 * Any additional arguments are provided to the invoked method.
15598 * @param {Array|string} path The path of the method to invoke.
15599 * @param {...*} [args] The arguments to invoke the method with.
15600 * @returns {Function} Returns the new invoker function.
15604 * { 'a': { 'b': _.constant(2) } },
15605 * { 'a': { 'b': _.constant(1) } }
15608 * _.map(objects, _.method('a.b'));
15611 * _.map(objects, _.method(['a', 'b']));
15614 var method = baseRest(function(path, args) {
15615 return function(object) {
15616 return baseInvoke(object, path, args);
15621 * The opposite of `_.method`; this method creates a function that invokes
15622 * the method at a given path of `object`. Any additional arguments are
15623 * provided to the invoked method.
15629 * @param {Object} object The object to query.
15630 * @param {...*} [args] The arguments to invoke the method with.
15631 * @returns {Function} Returns the new invoker function.
15634 * var array = _.times(3, _.constant),
15635 * object = { 'a': array, 'b': array, 'c': array };
15637 * _.map(['a[2]', 'c[0]'], _.methodOf(object));
15640 * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
15643 var methodOf = baseRest(function(object, args) {
15644 return function(path) {
15645 return baseInvoke(object, path, args);
15650 * Adds all own enumerable string keyed function properties of a source
15651 * object to the destination object. If `object` is a function, then methods
15652 * are added to its prototype as well.
15654 * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
15655 * avoid conflicts caused by modifying the original.
15661 * @param {Function|Object} [object=lodash] The destination object.
15662 * @param {Object} source The object of functions to add.
15663 * @param {Object} [options={}] The options object.
15664 * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
15665 * @returns {Function|Object} Returns `object`.
15668 * function vowels(string) {
15669 * return _.filter(string, function(v) {
15670 * return /[aeiou]/i.test(v);
15674 * _.mixin({ 'vowels': vowels });
15675 * _.vowels('fred');
15678 * _('fred').vowels().value();
15681 * _.mixin({ 'vowels': vowels }, { 'chain': false });
15682 * _('fred').vowels();
15685 function mixin(object, source, options) {
15686 var props = keys(source),
15687 methodNames = baseFunctions(source, props);
15689 if (options == null &&
15690 !(isObject(source) && (methodNames.length || !props.length))) {
15694 methodNames = baseFunctions(source, keys(source));
15696 var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
15697 isFunc = isFunction(object);
15699 arrayEach(methodNames, function(methodName) {
15700 var func = source[methodName];
15701 object[methodName] = func;
15703 object.prototype[methodName] = function() {
15704 var chainAll = this.__chain__;
15705 if (chain || chainAll) {
15706 var result = object(this.__wrapped__),
15707 actions = result.__actions__ = copyArray(this.__actions__);
15709 actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
15710 result.__chain__ = chainAll;
15713 return func.apply(object, arrayPush([this.value()], arguments));
15722 * Reverts the `_` variable to its previous value and returns a reference to
15723 * the `lodash` function.
15729 * @returns {Function} Returns the `lodash` function.
15732 * var lodash = _.noConflict();
15734 function noConflict() {
15735 if (root._ === this) {
15742 * This method returns `undefined`.
15750 * _.times(2, _.noop);
15751 * // => [undefined, undefined]
15754 // No operation performed.
15758 * Creates a function that gets the argument at index `n`. If `n` is negative,
15759 * the nth argument from the end is returned.
15765 * @param {number} [n=0] The index of the argument to return.
15766 * @returns {Function} Returns the new pass-thru function.
15769 * var func = _.nthArg(1);
15770 * func('a', 'b', 'c', 'd');
15773 * var func = _.nthArg(-2);
15774 * func('a', 'b', 'c', 'd');
15777 function nthArg(n) {
15779 return baseRest(function(args) {
15780 return baseNth(args, n);
15785 * Creates a function that invokes `iteratees` with the arguments it receives
15786 * and returns their results.
15792 * @param {...(Function|Function[])} [iteratees=[_.identity]]
15793 * The iteratees to invoke.
15794 * @returns {Function} Returns the new function.
15797 * var func = _.over([Math.max, Math.min]);
15799 * func(1, 2, 3, 4);
15802 var over = createOver(arrayMap);
15805 * Creates a function that checks if **all** of the `predicates` return
15806 * truthy when invoked with the arguments it receives.
15812 * @param {...(Function|Function[])} [predicates=[_.identity]]
15813 * The predicates to check.
15814 * @returns {Function} Returns the new function.
15817 * var func = _.overEvery([Boolean, isFinite]);
15828 var overEvery = createOver(arrayEvery);
15831 * Creates a function that checks if **any** of the `predicates` return
15832 * truthy when invoked with the arguments it receives.
15838 * @param {...(Function|Function[])} [predicates=[_.identity]]
15839 * The predicates to check.
15840 * @returns {Function} Returns the new function.
15843 * var func = _.overSome([Boolean, isFinite]);
15854 var overSome = createOver(arraySome);
15857 * Creates a function that returns the value at `path` of a given object.
15863 * @param {Array|string} path The path of the property to get.
15864 * @returns {Function} Returns the new accessor function.
15868 * { 'a': { 'b': 2 } },
15869 * { 'a': { 'b': 1 } }
15872 * _.map(objects, _.property('a.b'));
15875 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15878 function property(path) {
15879 return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15883 * The opposite of `_.property`; this method creates a function that returns
15884 * the value at a given path of `object`.
15890 * @param {Object} object The object to query.
15891 * @returns {Function} Returns the new accessor function.
15894 * var array = [0, 1, 2],
15895 * object = { 'a': array, 'b': array, 'c': array };
15897 * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
15900 * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
15903 function propertyOf(object) {
15904 return function(path) {
15905 return object == null ? undefined : baseGet(object, path);
15910 * Creates an array of numbers (positive and/or negative) progressing from
15911 * `start` up to, but not including, `end`. A step of `-1` is used if a negative
15912 * `start` is specified without an `end` or `step`. If `end` is not specified,
15913 * it's set to `start` with `start` then set to `0`.
15915 * **Note:** JavaScript follows the IEEE-754 standard for resolving
15916 * floating-point values which can produce unexpected results.
15922 * @param {number} [start=0] The start of the range.
15923 * @param {number} end The end of the range.
15924 * @param {number} [step=1] The value to increment or decrement by.
15925 * @returns {Array} Returns the range of numbers.
15926 * @see _.inRange, _.rangeRight
15930 * // => [0, 1, 2, 3]
15933 * // => [0, -1, -2, -3]
15936 * // => [1, 2, 3, 4]
15938 * _.range(0, 20, 5);
15939 * // => [0, 5, 10, 15]
15941 * _.range(0, -4, -1);
15942 * // => [0, -1, -2, -3]
15944 * _.range(1, 4, 0);
15950 var range = createRange();
15953 * This method is like `_.range` except that it populates values in
15954 * descending order.
15960 * @param {number} [start=0] The start of the range.
15961 * @param {number} end The end of the range.
15962 * @param {number} [step=1] The value to increment or decrement by.
15963 * @returns {Array} Returns the range of numbers.
15964 * @see _.inRange, _.range
15968 * // => [3, 2, 1, 0]
15970 * _.rangeRight(-4);
15971 * // => [-3, -2, -1, 0]
15973 * _.rangeRight(1, 5);
15974 * // => [4, 3, 2, 1]
15976 * _.rangeRight(0, 20, 5);
15977 * // => [15, 10, 5, 0]
15979 * _.rangeRight(0, -4, -1);
15980 * // => [-3, -2, -1, 0]
15982 * _.rangeRight(1, 4, 0);
15988 var rangeRight = createRange(true);
15991 * This method returns a new empty array.
15997 * @returns {Array} Returns the new empty array.
16000 * var arrays = _.times(2, _.stubArray);
16002 * console.log(arrays);
16005 * console.log(arrays[0] === arrays[1]);
16008 function stubArray() {
16013 * This method returns `false`.
16019 * @returns {boolean} Returns `false`.
16022 * _.times(2, _.stubFalse);
16023 * // => [false, false]
16025 function stubFalse() {
16030 * This method returns a new empty object.
16036 * @returns {Object} Returns the new empty object.
16039 * var objects = _.times(2, _.stubObject);
16041 * console.log(objects);
16044 * console.log(objects[0] === objects[1]);
16047 function stubObject() {
16052 * This method returns an empty string.
16058 * @returns {string} Returns the empty string.
16061 * _.times(2, _.stubString);
16064 function stubString() {
16069 * This method returns `true`.
16075 * @returns {boolean} Returns `true`.
16078 * _.times(2, _.stubTrue);
16079 * // => [true, true]
16081 function stubTrue() {
16086 * Invokes the iteratee `n` times, returning an array of the results of
16087 * each invocation. The iteratee is invoked with one argument; (index).
16093 * @param {number} n The number of times to invoke `iteratee`.
16094 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
16095 * @returns {Array} Returns the array of results.
16098 * _.times(3, String);
16099 * // => ['0', '1', '2']
16101 * _.times(4, _.constant(0));
16102 * // => [0, 0, 0, 0]
16104 function times(n, iteratee) {
16106 if (n < 1 || n > MAX_SAFE_INTEGER) {
16109 var index = MAX_ARRAY_LENGTH,
16110 length = nativeMin(n, MAX_ARRAY_LENGTH);
16112 iteratee = getIteratee(iteratee);
16113 n -= MAX_ARRAY_LENGTH;
16115 var result = baseTimes(length, iteratee);
16116 while (++index < n) {
16123 * Converts `value` to a property path array.
16129 * @param {*} value The value to convert.
16130 * @returns {Array} Returns the new property path array.
16133 * _.toPath('a.b.c');
16134 * // => ['a', 'b', 'c']
16136 * _.toPath('a[0].b.c');
16137 * // => ['a', '0', 'b', 'c']
16139 function toPath(value) {
16140 if (isArray(value)) {
16141 return arrayMap(value, toKey);
16143 return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
16147 * Generates a unique ID. If `prefix` is given, the ID is appended to it.
16153 * @param {string} [prefix=''] The value to prefix the ID with.
16154 * @returns {string} Returns the unique ID.
16157 * _.uniqueId('contact_');
16158 * // => 'contact_104'
16163 function uniqueId(prefix) {
16164 var id = ++idCounter;
16165 return toString(prefix) + id;
16168 /*------------------------------------------------------------------------*/
16171 * Adds two numbers.
16177 * @param {number} augend The first number in an addition.
16178 * @param {number} addend The second number in an addition.
16179 * @returns {number} Returns the total.
16185 var add = createMathOperation(function(augend, addend) {
16186 return augend + addend;
16190 * Computes `number` rounded up to `precision`.
16196 * @param {number} number The number to round up.
16197 * @param {number} [precision=0] The precision to round up to.
16198 * @returns {number} Returns the rounded up number.
16204 * _.ceil(6.004, 2);
16207 * _.ceil(6040, -2);
16210 var ceil = createRound('ceil');
16213 * Divide two numbers.
16219 * @param {number} dividend The first number in a division.
16220 * @param {number} divisor The second number in a division.
16221 * @returns {number} Returns the quotient.
16227 var divide = createMathOperation(function(dividend, divisor) {
16228 return dividend / divisor;
16232 * Computes `number` rounded down to `precision`.
16238 * @param {number} number The number to round down.
16239 * @param {number} [precision=0] The precision to round down to.
16240 * @returns {number} Returns the rounded down number.
16246 * _.floor(0.046, 2);
16249 * _.floor(4060, -2);
16252 var floor = createRound('floor');
16255 * Computes the maximum value of `array`. If `array` is empty or falsey,
16256 * `undefined` is returned.
16262 * @param {Array} array The array to iterate over.
16263 * @returns {*} Returns the maximum value.
16266 * _.max([4, 2, 8, 6]);
16272 function max(array) {
16273 return (array && array.length)
16274 ? baseExtremum(array, identity, baseGt)
16279 * This method is like `_.max` except that it accepts `iteratee` which is
16280 * invoked for each element in `array` to generate the criterion by which
16281 * the value is ranked. The iteratee is invoked with one argument: (value).
16287 * @param {Array} array The array to iterate over.
16288 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16289 * @returns {*} Returns the maximum value.
16292 * var objects = [{ 'n': 1 }, { 'n': 2 }];
16294 * _.maxBy(objects, function(o) { return o.n; });
16297 * // The `_.property` iteratee shorthand.
16298 * _.maxBy(objects, 'n');
16301 function maxBy(array, iteratee) {
16302 return (array && array.length)
16303 ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
16308 * Computes the mean of the values in `array`.
16314 * @param {Array} array The array to iterate over.
16315 * @returns {number} Returns the mean.
16318 * _.mean([4, 2, 8, 6]);
16321 function mean(array) {
16322 return baseMean(array, identity);
16326 * This method is like `_.mean` except that it accepts `iteratee` which is
16327 * invoked for each element in `array` to generate the value to be averaged.
16328 * The iteratee is invoked with one argument: (value).
16334 * @param {Array} array The array to iterate over.
16335 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16336 * @returns {number} Returns the mean.
16339 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16341 * _.meanBy(objects, function(o) { return o.n; });
16344 * // The `_.property` iteratee shorthand.
16345 * _.meanBy(objects, 'n');
16348 function meanBy(array, iteratee) {
16349 return baseMean(array, getIteratee(iteratee, 2));
16353 * Computes the minimum value of `array`. If `array` is empty or falsey,
16354 * `undefined` is returned.
16360 * @param {Array} array The array to iterate over.
16361 * @returns {*} Returns the minimum value.
16364 * _.min([4, 2, 8, 6]);
16370 function min(array) {
16371 return (array && array.length)
16372 ? baseExtremum(array, identity, baseLt)
16377 * This method is like `_.min` except that it accepts `iteratee` which is
16378 * invoked for each element in `array` to generate the criterion by which
16379 * the value is ranked. The iteratee is invoked with one argument: (value).
16385 * @param {Array} array The array to iterate over.
16386 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16387 * @returns {*} Returns the minimum value.
16390 * var objects = [{ 'n': 1 }, { 'n': 2 }];
16392 * _.minBy(objects, function(o) { return o.n; });
16395 * // The `_.property` iteratee shorthand.
16396 * _.minBy(objects, 'n');
16399 function minBy(array, iteratee) {
16400 return (array && array.length)
16401 ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
16406 * Multiply two numbers.
16412 * @param {number} multiplier The first number in a multiplication.
16413 * @param {number} multiplicand The second number in a multiplication.
16414 * @returns {number} Returns the product.
16417 * _.multiply(6, 4);
16420 var multiply = createMathOperation(function(multiplier, multiplicand) {
16421 return multiplier * multiplicand;
16425 * Computes `number` rounded to `precision`.
16431 * @param {number} number The number to round.
16432 * @param {number} [precision=0] The precision to round to.
16433 * @returns {number} Returns the rounded number.
16439 * _.round(4.006, 2);
16442 * _.round(4060, -2);
16445 var round = createRound('round');
16448 * Subtract two numbers.
16454 * @param {number} minuend The first number in a subtraction.
16455 * @param {number} subtrahend The second number in a subtraction.
16456 * @returns {number} Returns the difference.
16459 * _.subtract(6, 4);
16462 var subtract = createMathOperation(function(minuend, subtrahend) {
16463 return minuend - subtrahend;
16467 * Computes the sum of the values in `array`.
16473 * @param {Array} array The array to iterate over.
16474 * @returns {number} Returns the sum.
16477 * _.sum([4, 2, 8, 6]);
16480 function sum(array) {
16481 return (array && array.length)
16482 ? baseSum(array, identity)
16487 * This method is like `_.sum` except that it accepts `iteratee` which is
16488 * invoked for each element in `array` to generate the value to be summed.
16489 * The iteratee is invoked with one argument: (value).
16495 * @param {Array} array The array to iterate over.
16496 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16497 * @returns {number} Returns the sum.
16500 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16502 * _.sumBy(objects, function(o) { return o.n; });
16505 * // The `_.property` iteratee shorthand.
16506 * _.sumBy(objects, 'n');
16509 function sumBy(array, iteratee) {
16510 return (array && array.length)
16511 ? baseSum(array, getIteratee(iteratee, 2))
16515 /*------------------------------------------------------------------------*/
16517 // Add methods that return wrapped values in chain sequences.
16518 lodash.after = after;
16520 lodash.assign = assign;
16521 lodash.assignIn = assignIn;
16522 lodash.assignInWith = assignInWith;
16523 lodash.assignWith = assignWith;
16525 lodash.before = before;
16526 lodash.bind = bind;
16527 lodash.bindAll = bindAll;
16528 lodash.bindKey = bindKey;
16529 lodash.castArray = castArray;
16530 lodash.chain = chain;
16531 lodash.chunk = chunk;
16532 lodash.compact = compact;
16533 lodash.concat = concat;
16534 lodash.cond = cond;
16535 lodash.conforms = conforms;
16536 lodash.constant = constant;
16537 lodash.countBy = countBy;
16538 lodash.create = create;
16539 lodash.curry = curry;
16540 lodash.curryRight = curryRight;
16541 lodash.debounce = debounce;
16542 lodash.defaults = defaults;
16543 lodash.defaultsDeep = defaultsDeep;
16544 lodash.defer = defer;
16545 lodash.delay = delay;
16546 lodash.difference = difference;
16547 lodash.differenceBy = differenceBy;
16548 lodash.differenceWith = differenceWith;
16549 lodash.drop = drop;
16550 lodash.dropRight = dropRight;
16551 lodash.dropRightWhile = dropRightWhile;
16552 lodash.dropWhile = dropWhile;
16553 lodash.fill = fill;
16554 lodash.filter = filter;
16555 lodash.flatMap = flatMap;
16556 lodash.flatMapDeep = flatMapDeep;
16557 lodash.flatMapDepth = flatMapDepth;
16558 lodash.flatten = flatten;
16559 lodash.flattenDeep = flattenDeep;
16560 lodash.flattenDepth = flattenDepth;
16561 lodash.flip = flip;
16562 lodash.flow = flow;
16563 lodash.flowRight = flowRight;
16564 lodash.fromPairs = fromPairs;
16565 lodash.functions = functions;
16566 lodash.functionsIn = functionsIn;
16567 lodash.groupBy = groupBy;
16568 lodash.initial = initial;
16569 lodash.intersection = intersection;
16570 lodash.intersectionBy = intersectionBy;
16571 lodash.intersectionWith = intersectionWith;
16572 lodash.invert = invert;
16573 lodash.invertBy = invertBy;
16574 lodash.invokeMap = invokeMap;
16575 lodash.iteratee = iteratee;
16576 lodash.keyBy = keyBy;
16577 lodash.keys = keys;
16578 lodash.keysIn = keysIn;
16580 lodash.mapKeys = mapKeys;
16581 lodash.mapValues = mapValues;
16582 lodash.matches = matches;
16583 lodash.matchesProperty = matchesProperty;
16584 lodash.memoize = memoize;
16585 lodash.merge = merge;
16586 lodash.mergeWith = mergeWith;
16587 lodash.method = method;
16588 lodash.methodOf = methodOf;
16589 lodash.mixin = mixin;
16590 lodash.negate = negate;
16591 lodash.nthArg = nthArg;
16592 lodash.omit = omit;
16593 lodash.omitBy = omitBy;
16594 lodash.once = once;
16595 lodash.orderBy = orderBy;
16596 lodash.over = over;
16597 lodash.overArgs = overArgs;
16598 lodash.overEvery = overEvery;
16599 lodash.overSome = overSome;
16600 lodash.partial = partial;
16601 lodash.partialRight = partialRight;
16602 lodash.partition = partition;
16603 lodash.pick = pick;
16604 lodash.pickBy = pickBy;
16605 lodash.property = property;
16606 lodash.propertyOf = propertyOf;
16607 lodash.pull = pull;
16608 lodash.pullAll = pullAll;
16609 lodash.pullAllBy = pullAllBy;
16610 lodash.pullAllWith = pullAllWith;
16611 lodash.pullAt = pullAt;
16612 lodash.range = range;
16613 lodash.rangeRight = rangeRight;
16614 lodash.rearg = rearg;
16615 lodash.reject = reject;
16616 lodash.remove = remove;
16617 lodash.rest = rest;
16618 lodash.reverse = reverse;
16619 lodash.sampleSize = sampleSize;
16621 lodash.setWith = setWith;
16622 lodash.shuffle = shuffle;
16623 lodash.slice = slice;
16624 lodash.sortBy = sortBy;
16625 lodash.sortedUniq = sortedUniq;
16626 lodash.sortedUniqBy = sortedUniqBy;
16627 lodash.split = split;
16628 lodash.spread = spread;
16629 lodash.tail = tail;
16630 lodash.take = take;
16631 lodash.takeRight = takeRight;
16632 lodash.takeRightWhile = takeRightWhile;
16633 lodash.takeWhile = takeWhile;
16635 lodash.throttle = throttle;
16636 lodash.thru = thru;
16637 lodash.toArray = toArray;
16638 lodash.toPairs = toPairs;
16639 lodash.toPairsIn = toPairsIn;
16640 lodash.toPath = toPath;
16641 lodash.toPlainObject = toPlainObject;
16642 lodash.transform = transform;
16643 lodash.unary = unary;
16644 lodash.union = union;
16645 lodash.unionBy = unionBy;
16646 lodash.unionWith = unionWith;
16647 lodash.uniq = uniq;
16648 lodash.uniqBy = uniqBy;
16649 lodash.uniqWith = uniqWith;
16650 lodash.unset = unset;
16651 lodash.unzip = unzip;
16652 lodash.unzipWith = unzipWith;
16653 lodash.update = update;
16654 lodash.updateWith = updateWith;
16655 lodash.values = values;
16656 lodash.valuesIn = valuesIn;
16657 lodash.without = without;
16658 lodash.words = words;
16659 lodash.wrap = wrap;
16661 lodash.xorBy = xorBy;
16662 lodash.xorWith = xorWith;
16664 lodash.zipObject = zipObject;
16665 lodash.zipObjectDeep = zipObjectDeep;
16666 lodash.zipWith = zipWith;
16669 lodash.entries = toPairs;
16670 lodash.entriesIn = toPairsIn;
16671 lodash.extend = assignIn;
16672 lodash.extendWith = assignInWith;
16674 // Add methods to `lodash.prototype`.
16675 mixin(lodash, lodash);
16677 /*------------------------------------------------------------------------*/
16679 // Add methods that return unwrapped values in chain sequences.
16681 lodash.attempt = attempt;
16682 lodash.camelCase = camelCase;
16683 lodash.capitalize = capitalize;
16684 lodash.ceil = ceil;
16685 lodash.clamp = clamp;
16686 lodash.clone = clone;
16687 lodash.cloneDeep = cloneDeep;
16688 lodash.cloneDeepWith = cloneDeepWith;
16689 lodash.cloneWith = cloneWith;
16690 lodash.conformsTo = conformsTo;
16691 lodash.deburr = deburr;
16692 lodash.defaultTo = defaultTo;
16693 lodash.divide = divide;
16694 lodash.endsWith = endsWith;
16696 lodash.escape = escape;
16697 lodash.escapeRegExp = escapeRegExp;
16698 lodash.every = every;
16699 lodash.find = find;
16700 lodash.findIndex = findIndex;
16701 lodash.findKey = findKey;
16702 lodash.findLast = findLast;
16703 lodash.findLastIndex = findLastIndex;
16704 lodash.findLastKey = findLastKey;
16705 lodash.floor = floor;
16706 lodash.forEach = forEach;
16707 lodash.forEachRight = forEachRight;
16708 lodash.forIn = forIn;
16709 lodash.forInRight = forInRight;
16710 lodash.forOwn = forOwn;
16711 lodash.forOwnRight = forOwnRight;
16716 lodash.hasIn = hasIn;
16717 lodash.head = head;
16718 lodash.identity = identity;
16719 lodash.includes = includes;
16720 lodash.indexOf = indexOf;
16721 lodash.inRange = inRange;
16722 lodash.invoke = invoke;
16723 lodash.isArguments = isArguments;
16724 lodash.isArray = isArray;
16725 lodash.isArrayBuffer = isArrayBuffer;
16726 lodash.isArrayLike = isArrayLike;
16727 lodash.isArrayLikeObject = isArrayLikeObject;
16728 lodash.isBoolean = isBoolean;
16729 lodash.isBuffer = isBuffer;
16730 lodash.isDate = isDate;
16731 lodash.isElement = isElement;
16732 lodash.isEmpty = isEmpty;
16733 lodash.isEqual = isEqual;
16734 lodash.isEqualWith = isEqualWith;
16735 lodash.isError = isError;
16736 lodash.isFinite = isFinite;
16737 lodash.isFunction = isFunction;
16738 lodash.isInteger = isInteger;
16739 lodash.isLength = isLength;
16740 lodash.isMap = isMap;
16741 lodash.isMatch = isMatch;
16742 lodash.isMatchWith = isMatchWith;
16743 lodash.isNaN = isNaN;
16744 lodash.isNative = isNative;
16745 lodash.isNil = isNil;
16746 lodash.isNull = isNull;
16747 lodash.isNumber = isNumber;
16748 lodash.isObject = isObject;
16749 lodash.isObjectLike = isObjectLike;
16750 lodash.isPlainObject = isPlainObject;
16751 lodash.isRegExp = isRegExp;
16752 lodash.isSafeInteger = isSafeInteger;
16753 lodash.isSet = isSet;
16754 lodash.isString = isString;
16755 lodash.isSymbol = isSymbol;
16756 lodash.isTypedArray = isTypedArray;
16757 lodash.isUndefined = isUndefined;
16758 lodash.isWeakMap = isWeakMap;
16759 lodash.isWeakSet = isWeakSet;
16760 lodash.join = join;
16761 lodash.kebabCase = kebabCase;
16762 lodash.last = last;
16763 lodash.lastIndexOf = lastIndexOf;
16764 lodash.lowerCase = lowerCase;
16765 lodash.lowerFirst = lowerFirst;
16769 lodash.maxBy = maxBy;
16770 lodash.mean = mean;
16771 lodash.meanBy = meanBy;
16773 lodash.minBy = minBy;
16774 lodash.stubArray = stubArray;
16775 lodash.stubFalse = stubFalse;
16776 lodash.stubObject = stubObject;
16777 lodash.stubString = stubString;
16778 lodash.stubTrue = stubTrue;
16779 lodash.multiply = multiply;
16781 lodash.noConflict = noConflict;
16782 lodash.noop = noop;
16785 lodash.padEnd = padEnd;
16786 lodash.padStart = padStart;
16787 lodash.parseInt = parseInt;
16788 lodash.random = random;
16789 lodash.reduce = reduce;
16790 lodash.reduceRight = reduceRight;
16791 lodash.repeat = repeat;
16792 lodash.replace = replace;
16793 lodash.result = result;
16794 lodash.round = round;
16795 lodash.runInContext = runInContext;
16796 lodash.sample = sample;
16797 lodash.size = size;
16798 lodash.snakeCase = snakeCase;
16799 lodash.some = some;
16800 lodash.sortedIndex = sortedIndex;
16801 lodash.sortedIndexBy = sortedIndexBy;
16802 lodash.sortedIndexOf = sortedIndexOf;
16803 lodash.sortedLastIndex = sortedLastIndex;
16804 lodash.sortedLastIndexBy = sortedLastIndexBy;
16805 lodash.sortedLastIndexOf = sortedLastIndexOf;
16806 lodash.startCase = startCase;
16807 lodash.startsWith = startsWith;
16808 lodash.subtract = subtract;
16810 lodash.sumBy = sumBy;
16811 lodash.template = template;
16812 lodash.times = times;
16813 lodash.toFinite = toFinite;
16814 lodash.toInteger = toInteger;
16815 lodash.toLength = toLength;
16816 lodash.toLower = toLower;
16817 lodash.toNumber = toNumber;
16818 lodash.toSafeInteger = toSafeInteger;
16819 lodash.toString = toString;
16820 lodash.toUpper = toUpper;
16821 lodash.trim = trim;
16822 lodash.trimEnd = trimEnd;
16823 lodash.trimStart = trimStart;
16824 lodash.truncate = truncate;
16825 lodash.unescape = unescape;
16826 lodash.uniqueId = uniqueId;
16827 lodash.upperCase = upperCase;
16828 lodash.upperFirst = upperFirst;
16831 lodash.each = forEach;
16832 lodash.eachRight = forEachRight;
16833 lodash.first = head;
16835 mixin(lodash, (function() {
16837 baseForOwn(lodash, function(func, methodName) {
16838 if (!hasOwnProperty.call(lodash.prototype, methodName)) {
16839 source[methodName] = func;
16843 }()), { 'chain': false });
16845 /*------------------------------------------------------------------------*/
16848 * The semantic version number.
16854 lodash.VERSION = VERSION;
16856 // Assign default placeholders.
16857 arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
16858 lodash[methodName].placeholder = lodash;
16861 // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
16862 arrayEach(['drop', 'take'], function(methodName, index) {
16863 LazyWrapper.prototype[methodName] = function(n) {
16864 n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
16866 var result = (this.__filtered__ && !index)
16867 ? new LazyWrapper(this)
16870 if (result.__filtered__) {
16871 result.__takeCount__ = nativeMin(n, result.__takeCount__);
16873 result.__views__.push({
16874 'size': nativeMin(n, MAX_ARRAY_LENGTH),
16875 'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
16881 LazyWrapper.prototype[methodName + 'Right'] = function(n) {
16882 return this.reverse()[methodName](n).reverse();
16886 // Add `LazyWrapper` methods that accept an `iteratee` value.
16887 arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
16888 var type = index + 1,
16889 isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
16891 LazyWrapper.prototype[methodName] = function(iteratee) {
16892 var result = this.clone();
16893 result.__iteratees__.push({
16894 'iteratee': getIteratee(iteratee, 3),
16897 result.__filtered__ = result.__filtered__ || isFilter;
16902 // Add `LazyWrapper` methods for `_.head` and `_.last`.
16903 arrayEach(['head', 'last'], function(methodName, index) {
16904 var takeName = 'take' + (index ? 'Right' : '');
16906 LazyWrapper.prototype[methodName] = function() {
16907 return this[takeName](1).value()[0];
16911 // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
16912 arrayEach(['initial', 'tail'], function(methodName, index) {
16913 var dropName = 'drop' + (index ? '' : 'Right');
16915 LazyWrapper.prototype[methodName] = function() {
16916 return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
16920 LazyWrapper.prototype.compact = function() {
16921 return this.filter(identity);
16924 LazyWrapper.prototype.find = function(predicate) {
16925 return this.filter(predicate).head();
16928 LazyWrapper.prototype.findLast = function(predicate) {
16929 return this.reverse().find(predicate);
16932 LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
16933 if (typeof path == 'function') {
16934 return new LazyWrapper(this);
16936 return this.map(function(value) {
16937 return baseInvoke(value, path, args);
16941 LazyWrapper.prototype.reject = function(predicate) {
16942 return this.filter(negate(getIteratee(predicate)));
16945 LazyWrapper.prototype.slice = function(start, end) {
16946 start = toInteger(start);
16949 if (result.__filtered__ && (start > 0 || end < 0)) {
16950 return new LazyWrapper(result);
16953 result = result.takeRight(-start);
16954 } else if (start) {
16955 result = result.drop(start);
16957 if (end !== undefined) {
16958 end = toInteger(end);
16959 result = end < 0 ? result.dropRight(-end) : result.take(end - start);
16964 LazyWrapper.prototype.takeRightWhile = function(predicate) {
16965 return this.reverse().takeWhile(predicate).reverse();
16968 LazyWrapper.prototype.toArray = function() {
16969 return this.take(MAX_ARRAY_LENGTH);
16972 // Add `LazyWrapper` methods to `lodash.prototype`.
16973 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16974 var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
16975 isTaker = /^(?:head|last)$/.test(methodName),
16976 lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
16977 retUnwrapped = isTaker || /^find/.test(methodName);
16982 lodash.prototype[methodName] = function() {
16983 var value = this.__wrapped__,
16984 args = isTaker ? [1] : arguments,
16985 isLazy = value instanceof LazyWrapper,
16986 iteratee = args[0],
16987 useLazy = isLazy || isArray(value);
16989 var interceptor = function(value) {
16990 var result = lodashFunc.apply(lodash, arrayPush([value], args));
16991 return (isTaker && chainAll) ? result[0] : result;
16994 if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
16995 // Avoid lazy use if the iteratee has a "length" value other than `1`.
16996 isLazy = useLazy = false;
16998 var chainAll = this.__chain__,
16999 isHybrid = !!this.__actions__.length,
17000 isUnwrapped = retUnwrapped && !chainAll,
17001 onlyLazy = isLazy && !isHybrid;
17003 if (!retUnwrapped && useLazy) {
17004 value = onlyLazy ? value : new LazyWrapper(this);
17005 var result = func.apply(value, args);
17006 result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
17007 return new LodashWrapper(result, chainAll);
17009 if (isUnwrapped && onlyLazy) {
17010 return func.apply(this, args);
17012 result = this.thru(interceptor);
17013 return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
17017 // Add `Array` methods to `lodash.prototype`.
17018 arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
17019 var func = arrayProto[methodName],
17020 chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
17021 retUnwrapped = /^(?:pop|shift)$/.test(methodName);
17023 lodash.prototype[methodName] = function() {
17024 var args = arguments;
17025 if (retUnwrapped && !this.__chain__) {
17026 var value = this.value();
17027 return func.apply(isArray(value) ? value : [], args);
17029 return this[chainName](function(value) {
17030 return func.apply(isArray(value) ? value : [], args);
17035 // Map minified method names to their real names.
17036 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
17037 var lodashFunc = lodash[methodName];
17039 var key = (lodashFunc.name + ''),
17040 names = realNames[key] || (realNames[key] = []);
17042 names.push({ 'name': methodName, 'func': lodashFunc });
17046 realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
17051 // Add methods to `LazyWrapper`.
17052 LazyWrapper.prototype.clone = lazyClone;
17053 LazyWrapper.prototype.reverse = lazyReverse;
17054 LazyWrapper.prototype.value = lazyValue;
17056 // Add chain sequence methods to the `lodash` wrapper.
17057 lodash.prototype.at = wrapperAt;
17058 lodash.prototype.chain = wrapperChain;
17059 lodash.prototype.commit = wrapperCommit;
17060 lodash.prototype.next = wrapperNext;
17061 lodash.prototype.plant = wrapperPlant;
17062 lodash.prototype.reverse = wrapperReverse;
17063 lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
17065 // Add lazy aliases.
17066 lodash.prototype.first = lodash.prototype.head;
17069 lodash.prototype[symIterator] = wrapperToIterator;
17074 /*--------------------------------------------------------------------------*/
17077 var _ = runInContext();
17079 // Some AMD build optimizers, like r.js, check for condition patterns like:
17080 if (typeof undefined == 'function' && typeof undefined.amd == 'object' && undefined.amd) {
17081 // Expose Lodash on the global object to prevent errors when Lodash is
17082 // loaded by a script tag in the presence of an AMD loader.
17083 // See http://requirejs.org/docs/errors.html#mismatch for more details.
17084 // Use `_.noConflict` to remove Lodash from the global object.
17087 // Define as an anonymous module so, through path mapping, it can be
17088 // referenced as the "underscore" module.
17089 undefined(function() {
17093 // Check for `exports` after `define` in case a build optimizer adds it.
17094 else if (freeModule) {
17095 // Export for Node.js.
17096 (freeModule.exports = _)._ = _;
17097 // Export for CommonJS support.
17101 // Export to the global object.
17104 }.call(commonjsGlobal));
17107 function osmIsInterestingTag(key) {
17108 return key !== 'attribution' &&
17109 key !== 'created_by' &&
17110 key !== 'source' &&
17112 key.indexOf('tiger:') !== 0;
17117 var osmOneWayTags = {
17119 'chair_lift': true,
17120 'mixed_lift': true,
17125 'magic_carpet': true,
17130 'motorway_link': true
17136 'piste:halfpipe': true
17150 var osmPavedTags = {
17161 var dataWikipedia = [
17278 "беларуская (тарашкевіца)",
17279 "беларуская (тарашкевіца)",
17319 "বিষ্ণুপ্রিয়া মণিপুরী",
17348 "Chavacano de Zamboanga",
17349 "Chavacano de Zamboanga",
17353 "Min Dong Chinese",
17394 "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ",
17414 "словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ",
17468 "Emiliano-Romagnolo",
17469 "emiliàn e rumagnòl",
17524 "Na Vosa Vakaviti",
17543 "Northern Frisian",
17594 "गोंयची कोंकणी / Gõychi Konknni",
17674 "Bahasa Indonesia",
17714 "ᐃᓄᒃᑎᑐᑦ/inuktitut",
17723 "Jamaican Creole English",
17799 "къарачай-малкъар",
17939 "Baso Minangkabau",
18038 "Norwegian Nynorsk",
18059 "Sesotho sa Leboa",
18123 "Pennsylvania German",
18138 "Norfuk / Pitkern",
18139 "Norfuk / Pitkern",
18264 "srpskohrvatski / српскохрватски",
18328 "Saterland Frisian",
18454 "ئۇيغۇرچە / Uyghurche",
18469 "oʻzbekcha/ўзбекча",
18563 "Classical Chinese",
18568 "Chinese (Min Nan)",
18584 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}}};
18585 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}}};
18586 var dataSuggestions = {
18591 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"]]},{"countryCodes":["jp"],"format":[["postcode","province","county"],["city","suburb"],["quarter","neighbourhood"],["block_number","housenumber"]],"dropdowns":["postcode","province","county","city","suburb","quarter","neighbourhood","block_number"],"widths":{"postcode":0.3,"province":0.35,"county":0.35,"city":0.65,"suburb":0.35,"quarter":0.5,"neighbourhood":0.5,"block_number":0.5,"housenumber":0.5}},{"countryCodes":["tr"],"format":[["neighbourhood"],["street","housenumber"],["postcode","district","city"]]}];
18593 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"}}];
18595 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"];
18597 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},"mk":{"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}};
18599 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 1234 5678","tw":"+886 1 2345 6789","tr":"+90 312 123 4567"};
18601 var type = "FeatureCollection";
18602 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]]]}}];
18603 var dataImperial = {
18608 var type$1 = "FeatureCollection";
18609 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]]]}}];
18610 var dataDriveLeft = {
18612 features: features$1
18615 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":{"single":"Delete this feature permanently.","multiple":"Delete these features 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} features."},"incomplete_relation":{"single":"This feature can't be deleted because it hasn't been fully downloaded.","multiple":"These features can't be deleted because they haven't been fully downloaded."},"part_of_relation":{"single":"This feature can't be deleted because it is part of a larger relation. You must remove it from the relation first.","multiple":"These features can't be deleted because they are part of larger relations. You must remove them from the relations first."},"connected_to_hidden":{"single":"This feature can't be deleted because it is connected to a hidden feature.","multiple":"These features can't be deleted because some are connected to hidden features."}},"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":{"single":"Move this feature to a different location.","multiple":"Move these features 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 features."},"incomplete_relation":{"single":"This feature can't be moved because it hasn't been fully downloaded.","multiple":"These features can't be moved because they haven't been fully downloaded."},"too_large":{"single":"This feature can't be moved because not enough of it is currently visible.","multiple":"These features can't be moved because not enough of them are currently visible."},"connected_to_hidden":{"single":"This feature can't be moved because it is connected to a hidden feature.","multiple":"These features can't be moved because some are connected to hidden features."}},"reflect":{"title":"reflect","description":{"long":{"single":"Reflect this feature across its long axis.","multiple":"Reflect these features across their long axis."},"short":{"single":"Reflect this feature across its short axis.","multiple":"Reflect these features across their short axis."}},"key":{"long":"T","short":"Y"},"annotation":{"long":{"single":"Reflected an feature across its long axis.","multiple":"Reflected multiple features across their long axis."},"short":{"single":"Reflected an feature across its short axis.","multiple":"Reflected multiple features across their short axis."}},"incomplete_relation":{"single":"This feature can't be reflected because it hasn't been fully downloaded.","multiple":"These features can't be reflected because they haven't been fully downloaded."},"too_large":{"single":"This feature can't be reflected because not enough of it is currently visible.","multiple":"These features can't be reflected because not enough of them are currently visible."},"connected_to_hidden":{"single":"This feature can't be reflected because it is connected to a hidden feature.","multiple":"These features can't be reflected because some are connected to hidden features."}},"rotate":{"title":"Rotate","description":{"single":"Rotate this feature around its center point.","multiple":"Rotate these features around their center point."},"key":"R","annotation":{"line":"Rotated a line.","area":"Rotated an area.","multiple":"Rotated multiple features."},"incomplete_relation":{"single":"This feature can't be rotated because it hasn't been fully downloaded.","multiple":"These features can't be rotated because they haven't been fully downloaded."},"too_large":{"single":"This feature can't be rotated because not enough of it is currently visible.","multiple":"These features can't be rotated because not enough of them are currently visible."},"connected_to_hidden":{"single":"This feature can't be rotated because it is connected to a hidden feature.","multiple":"These features can't be rotated because some are connected to hidden features."}},"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":"Upload to OpenStreetMap","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":"Upload","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 features","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 feature 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 feature has been deleted by {user}.","location":"This feature 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":{"disconnected_highway":"Disconnected highway","disconnected_highway_tooltip":"Roads should be connected to other roads.","untagged_point":"Untagged point","untagged_line":"Untagged line","untagged_area":"Untagged area","untagged_relation":"Untagged relation","many_deletions":"You're deleting {n} features. 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.","untagged_relation_tooltip":"Select a feature type that describes what this relation 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 file","drag_drop":"Drag and drop a .gpx, .geojson or .kml file on the page, or click the button to the right to browse","zoom":"Zoom to layer","browse":"Browse for a 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-natural-area":{"name":"Natural Features"},"category-natural-line":{"name":"Natural Features"},"category-natural-point":{"name":"Natural 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":{"block_number":"Block Number","block_number!jp":"Block No.","city":"City","city!jp":"City/Town/Village/Tokyo Special Ward","city!vn":"City/Town","conscriptionnumber":"123","country":"Country","county":"County","county!jp":"District","district":"District","district!vn":"Arrondissement/Town/District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","housenumber!jp":"Building No./Lot No.","neighbourhood":"Neighbourhood","neighbourhood!jp":"Chōme/Aza/Koaza","place":"Place","postcode":"Postcode","province":"Province","province!jp":"Prefecture","quarter":"Quarter","quarter!jp":"Ōaza/Machi","state":"State","street":"Street","subdistrict":"Subdistrict","subdistrict!vn":"Ward/Commune/Townlet","suburb":"Suburb","suburb!jp":"Ward"}},"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"},"bunker_type":{"label":"Type"},"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"}},"castle_type":{"label":"Type"},"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"},"email":{"label":"Email","placeholder":"example@example.com"},"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/position":{"label":"Position","options":{"lane":"Lane","parking_lot":"Parking Lot","sidewalk":"Sidewalk","green":"Green"}},"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"},"plant":{"label":"Plant"},"population":{"label":"Population"},"power_supply":{"label":"Power Supply"},"power":{"label":"Type"},"product":{"label":"Product"},"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"},"social_facility":{"label":"Type"},"source":{"label":"Source"},"sport_ice":{"label":"Sport"},"sport_racing":{"label":"Sport"},"sport":{"label":"Sport"},"stars":{"label":"Stars"},"step_count":{"label":"Number of Steps"},"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"}},"toll":{"label":"Toll"},"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/drag_lift":{"name":"Drag Lift","terms":""},"aerialway/gondola":{"name":"Gondola","terms":""},"aerialway/goods":{"name":"Goods Aerialway","terms":""},"aerialway/magic_carpet":{"name":"Magic Carpet Lift","terms":""},"aerialway/mixed_lift":{"name":"Mixed 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/coworking_space":{"name":"Coworking Space","terms":""},"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/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,gun,lookout,rifle,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/border_control":{"name":"Border Control","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":"fire plug"},"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":"autobahn,expressway,freeway,highway,interstate,parkway,thruway,turnpike"},"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":"crop,grow,plant"},"landuse/farmyard":{"name":"Farmyard","terms":"crop,grow,plant"},"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/military/airfield":{"name":"Military Airfield","terms":"air force,army,base,bomb,fight,force,guard,heli*,jet,marine,navy,plane,troop,war"},"landuse/military/barracks":{"name":"Barracks","terms":"air force,army,base,fight,force,guard,marine,navy,troop,war"},"landuse/military/bunker":{"name":"Military Bunker","terms":"air force,army,base,fight,force,guard,marine,navy,troop,war"},"landuse/military/checkpoint":{"name":"Checkpoint","terms":"air force,army,base,force,guard,marine,navy,troop,war"},"landuse/military/danger_area":{"name":"Danger Area","terms":"air force,army,base,blast,bomb,explo*,force,guard,mine,marine,navy,troop,war"},"landuse/military/naval_base":{"name":"Naval Base","terms":"base,fight,force,guard,marine,navy,ship,sub,troop,war"},"landuse/military/nuclear_explosion_site":{"name":"Nuclear Explosion Site","terms":"atom,blast,bomb,detonat*,nuke,site,test"},"landuse/military/obstacle_course":{"name":"Obstacle Course","terms":"army,base,force,guard,marine,navy,troop,war"},"landuse/military/office":{"name":"Military Office","terms":"air force,army,base,enlist,fight,force,guard,marine,navy,recruit,troop,war"},"landuse/military/range":{"name":"Military Range","terms":"air force,army,base,fight,fire,force,guard,gun,marine,navy,rifle,shoot*,snip*,train,troop,war"},"landuse/military/training_area":{"name":"Training Area","terms":"air force,army,base,fight,fire,force,guard,gun,marine,navy,rifle,shoot*,snip*,train,troop,war"},"landuse/orchard":{"name":"Orchard","terms":"fruit"},"landuse/plant_nursery":{"name":"Plant Nursery","terms":"flower,garden,grow,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":"grape,wine"},"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/horse_riding":{"name":"Horseback Riding Facility","terms":"equestrian,stable"},"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":"Factory","terms":"assembly,build,brewery,car,plant,plastic,processing,manufacture,refinery"},"natural":{"name":"Natural","terms":""},"natural/bare_rock":{"name":"Bare Rock","terms":"rock"},"natural/bay":{"name":"Bay","terms":""},"natural/beach":{"name":"Beach","terms":"shore"},"natural/cave_entrance":{"name":"Cave Entrance","terms":"cavern,hollow,grotto,shelter,cavity"},"natural/cliff":{"name":"Cliff","terms":"escarpment"},"natural/coastline":{"name":"Coastline","terms":"shore"},"natural/fell":{"name":"Fell","terms":""},"natural/glacier":{"name":"Glacier","terms":""},"natural/grassland":{"name":"Grassland","terms":"prairie,savanna"},"natural/heath":{"name":"Heath","terms":""},"natural/peak":{"name":"Peak","terms":"acme,aiguille,alp,climax,crest,crown,hill,mount,mountain,pinnacle,summit,tip,top"},"natural/ridge":{"name":"Ridge","terms":"crest"},"natural/saddle":{"name":"Saddle","terms":"pass,mountain pass,top"},"natural/sand":{"name":"Sand","terms":"desert"},"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"},"noexit/yes":{"name":"No Exit","terms":"no exit,road end,dead end"},"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/coworking":{"name":"Coworking Space","terms":"coworking,office"},"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/lawyer/notary":{"name":"Notary Office","terms":"clerk,signature,wills,deeds,estate"},"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/square":{"name":"Square","terms":""},"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/plant":{"name":"Power Station Grounds","terms":"coal,gas,generat*,hydro,nuclear,power,station"},"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/watches":{"name":"Watches Shop","terms":""},"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":""}}}};
18617 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":[[[-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]],[[-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]]],"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":"lu.geoportail.opendata.basemap","name":"Basemap geoportail.lu","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":"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],[2.31953818544,6.55745092536]],[[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],[1.69563043958,6.25076170066]]],"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":"lu.geoportail.opendata.cadastre","name":"Cadastre geoportail.lu","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":"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],[15.0063684,49.0177392]]],"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],[15.0063684,49.0177392]]],"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-S2A_R119_N09_20160327T050917","name":"imagico.de OSM images for mapping: Adams Bridge","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R119_N09_20160327T050917&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160330T091608_R119_V20160327T050917_20160327T050917, 2016-03-27, channels 234 (true color), Supplementing incomplete coverage in other sources","scaleExtent":[0,14],"polygon":[[[79.01779174804685,8.827572266651268],[79.01401519775389,9.64678471986339],[80.17642021179198,9.650423231331946],[80.17727851867674,8.831304063493132],[79.01779174804685,8.827572266651268]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"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.70872943147867,62.30357443926811],[-152.70838610872474,62.58153176976553],[-152.00835101350992,63.54645538851267],[-148.99432055696695,63.53329945446586],[-148.99432055696695,62.30357443926811],[-152.70872943147867,62.30357443926811]]],"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":[[[114.35999506049737,2.028456548619032],[113.5344754987298,2.030000532161949],[113.53619211249934,3.070767124420059],[114.76511591010677,3.067510236472651],[114.76254098945248,2.088156161702156],[114.35999506049737,2.028456548619032]]],"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 to 2016, channels 234 (true color), Missing Islands in OSM","scaleExtent":[0,13],"polygon":[[[104.00154570197358,-0.000078769115171],[104.00137404059662,1.45099139170518],[104.91014937018647,1.451162998032411],[104.91014937018647,-0.000078769115171],[104.00154570197358,-0.000078769115171]]],"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.246529403113632,-54.47046993167111],[3.246529403113632,-54.375391687979096],[3.463852706336288,-54.375391687979096],[3.463852706336288,-54.47046993167111],[3.246529403113632,-54.47046993167111]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping","best":true},{"id":"osmim-imagicode-S2A_R065_N47_20160929T102022","name":"imagico.de OSM images for mapping: Cental Alps in late September 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R065_N47_20160929T102022&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160929Txxxxxx_R065_V20160929T102022_20160929T102344, 2016-09-29, channels 234 (true color), Up-to-date image for glacier mapping - beware of some fresh snow at higher altitudes","scaleExtent":[0,13],"polygon":[[[10.559062957763668,45.95484945195885],[7.473964691162107,45.95532682303484],[7.555847167968747,46.27080015119853],[8.05469512939453,47.66469371011084],[11.752452850341793,47.664809318453564],[11.752452850341793,46.813336457338615],[11.38423919677734,45.955088138010865],[10.559062957763668,45.95484945195885]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"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":[[[-34.17701089820909,-55.29692751183208],[-35.19599283180284,-55.282851769908206],[-35.16663873634385,-54.7209735214882],[-34.12516916236925,-54.73465315976587],[-34.14010370216417,-55.29692751183208],[-34.17701089820909,-55.29692751183208]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-EO1A0040712016264110KF","name":"imagico.de OSM images for mapping: Coropuna","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A0040712016264110KF&z={zoom}&x={x}&y={-y}","description":"EO1A0040712016264110KF, 2016-09-21, channels 123 (true color), Up-to-date image for glacier mapping","scaleExtent":[0,14],"polygon":[[[-72.7594470977783,-15.68684010813036],[-72.7594470977783,-15.49570157136026],[-72.74434089660643,-15.426295586903299],[-72.41286277770995,-15.426295586903299],[-72.41286277770995,-15.652957427428944],[-72.42410659790038,-15.686674840407827],[-72.7594470977783,-15.68684010813036]]],"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.839749701876779,6.257803795151386],[1.839749701876779,7.114271792431897],[2.549397834200998,7.114271792431897],[2.549397834200998,6.489052510574106],[2.497813590426584,6.258059752887941],[1.839749701876779,6.257803795151386]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R040_N01_20160311T164128","name":"imagico.de OSM images for mapping: Darwin and Wolf islands, Galapagos","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R040_N01_20160311T164128&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160312T000419_R040_V20160311T164128_20160311T164128, 2016-03-11, channels 234 (true color), Recent image, only old and poor images in other sources currently","scaleExtent":[0,14],"polygon":[[[-92.05216379429558,1.321295617717369],[-92.05216379429558,1.72181118585353],[-91.74849481846549,1.72181118585353],[-91.74849481846549,1.321295617717369],[-92.05216379429558,1.321295617717369]]],"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.34798733886554,74.38945823827667],[-84.34798733886554,75.89030323920836],[-79.14870755370929,75.89030323920836],[-79.14870755370929,74.38945823827667],[-84.34798733886554,74.38945823827667]]],"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":[[[-13.047005598725303,64.2110895294821],[-15.164963667572959,64.22408122727819],[-15.168053572358117,64.81572800422087],[-13.043572371186242,64.80359943673454],[-13.047005598725303,64.2110895294821]]],"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.805085317123331],[-78.531997745432,-1.608105565001241],[-78.33561713019762,-1.608105565001241],[-78.33561713019762,-1.805085317123331],[-78.531997745432,-1.805085317123331]]],"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.13476090727487,-61.63471600102006],[-56.13476090727487,-61.199363166283845],[-55.83263688383738,-60.84015069906498],[-53.72343354521433,-60.83981613078141],[-53.72343354521433,-61.63471600102006],[-56.13476090727487,-61.63471600102006]]],"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.758781955967567,14.748140156641956],[-24.758781955967567,15.092493544965103],[-24.267057941685337,15.092493544965103],[-24.267057941685337,14.748140156641956],[-24.758781955967567,14.748140156641956]]],"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 to 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.5600891113281,76.43270387722659],[-74.5600891113281,82.6959093208192],[-12.86159673508746,82.6959093208192],[-11.878165975221727,82.54102593940235],[-10.7796478271484,82.51186682511671],[-10.7796478271484,78.34463154312763],[-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.06896521028185,-53.270590689700434],[73.06896521028185,-52.875489636268725],[73.67338491853381,-52.87673289134188],[74.08863378938341,-52.94950473139763],[74.08863378938341,-53.270590689700434],[73.06896521028185,-53.270590689700434]]],"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":[[[-69.85679747431641,-55.55949231551995],[-72.26520659296875,-55.149427383391455],[-72.26520659296875,-54.51089432315929],[-72.08530546992188,-54.17909103768387],[-69.49115874140625,-54.17889010631196],[-69.49150206416016,-55.28378528847367],[-69.62230803339844,-55.55910398108892],[-69.85679747431641,-55.55949231551995]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R021_N44_20160807T083013","name":"imagico.de OSM images for mapping: Kerch Strait","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R021_N44_20160807T083013&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160807T224006_R021_V20160807T083013_20160807T083013, 2016-08-07, channels 234 (true color), State of bridge construction in August 2016","scaleExtent":[0,14],"polygon":[[[35.932588577270494,44.96236872935039],[35.932588577270494,45.559256426515695],[37.369909286499016,45.559256426515695],[37.369909286499016,44.96236872935039],[35.932588577270494,44.96236872935039]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-ls_polar2","name":"imagico.de OSM images for mapping: Landsat off-nadir July 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ls_polar2&z={zoom}&x={x}&y={-y}","description":"LC80402432016199LGN00-LC80402482016199LGN00, 2016-07-17, channels 234 (true color), Latest images north of the regular Landsat limit","scaleExtent":[0,10],"polygon":[[[-79.05174500251786,81.91484289044183],[-79.05174500251786,83.43338556749623],[-73.60389956385866,83.80224987787145],[-26.424486898081835,83.80224987787145],[-21.492998879371186,83.50352415480617],[-16.888354121159868,83.15094632775453],[-16.888354121159868,81.91484289044183],[-79.05174500251786,81.91484289044183]]],"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.210747081406492,-56.72108048139938],[-28.210747081406492,-56.624975043089115],[-27.96956284678735,-56.624975043089115],[-27.96956284678735,-56.72108048139938],[-28.210747081406492,-56.72108048139938]]],"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":[[[-27.992928409215843,-56.73479060902333],[-28.227761172887714,-56.732624892496354],[-28.2241562839717,-56.600752537318456],[-27.969754123327167,-56.60283135691063],[-27.97318735086623,-56.73479060902333],[-27.992928409215843,-56.73479060902333]]],"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), First available image north of the regular Landsat limit, mostly with seasonal snow cover so difficult to interpret","scaleExtent":[0,10],"polygon":[[[-85.76109385682587,81.39333391115835],[-89.83015512094161,82.14951616258433],[-89.83152841195212,82.24404688557661],[-84.99342418195555,82.73098798225534],[-79.95207288240479,83.13107965605444],[-74.55641250214465,83.46266728201661],[-69.35850602739671,83.70450775086888],[-28.207840897721187,83.70450775086888],[-23.06623935440381,83.46532469372944],[-17.96583654140148,83.15518123848051],[-17.96720983241198,82.72386035102944],[-22.781968115230015,81.44190408358111],[-85.76109385682587,81.39333391115835]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R092_S02_20160613T075613","name":"imagico.de OSM images for mapping: Mount Kenya 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S02_20160613T075613&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160613T140051_R092_V20160613T075613_20160613T075613, 2016-06-13, channels 234 (true color), Up-to-date image for glacier mapping","scaleExtent":[0,14],"polygon":[[[37.20665931701659,-0.266846645776291],[37.20665931701659,-0.011930465612033],[37.5655174255371,-0.011930465612033],[37.5655174255371,-0.266846645776291],[37.20665931701659,-0.266846645776291]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R092_S05_20160802T075556","name":"imagico.de OSM images for mapping: Mount Kilimanjaro 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R092_S05_20160802T075556&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160802T130554_R092_V20160802T075556_20160802T075556, 2016-08-02, channels 234 (true color), Up-to-date image for glacier mapping","scaleExtent":[0,14],"polygon":[[[37.24768638610839,-3.229213650135676],[37.24768638610839,-2.968155849006605],[37.61581420898436,-2.968155849006605],[37.61581420898436,-3.229213650135676],[37.24768638610839,-3.229213650135676]]],"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.38853376619625,-2.800534349432724],[150.38853376619625,-2.383396178206425],[150.83348005525875,-2.383396178206425],[150.83348005525875,-2.800534349432724],[150.38853376619625,-2.800534349432724]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-ural_s2_2016","name":"imagico.de OSM images for mapping: Northern and Polar Ural mountains August 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=ural_s2_2016&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160812T212938_R092_V20160812T073612_20160812T073615/S2A_OPER_PRD_MSIL1C_PDMC_20160812T222950_R092_V20160812T073612_20160812T073615, 2016-08-12, channels 234 (true color), Up-to-date late summer imagery with few clouds - caution: not all visible snow is glaciers","scaleExtent":[0,13],"polygon":[[[59.198977223476454,64.8920468958533],[59.198977223476454,66.91656046303187],[60.733286610683486,68.44289182710118],[67.7329509173241,68.44327026354412],[67.7329509173241,67.748828729217],[64.21646761043934,64.9195663902952],[59.198977223476454,64.8920468958533]]],"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":[[[-81.62923243782096,82.45969864814401],[-83.03136255954291,82.47985512217643],[-83.03136255954291,83.05876272004272],[-72.80309111332822,83.09567468670448],[-65.65785798568925,83.03232446260982],[-65.8116665788654,82.45969864814401],[-81.62923243782096,82.45969864814401]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-nellesmere_ast_2016","name":"imagico.de OSM images for mapping: Northern Ellesmere Island July 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=nellesmere_ast_2016&z={zoom}&x={x}&y={-y}","description":"ASTER L1T, 2012-07-08 to 2012-07-15, channels 12x (true color with estimated blue), Assembled from July 2016 ASTER imagery","scaleExtent":[0,10],"polygon":[[[-78.89729497133754,82.17577067162792],[-82.64500613899595,82.19425721404356],[-82.64500613899595,83.08067098163464],[-66.58986093522367,83.08497116318647],[-63.78010752773773,82.98907949583335],[-63.78010752773773,82.72198178031782],[-65.0092029821365,82.17577067162792],[-78.89729497133754,82.17577067162792]]],"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.28027339774928],[7.63567991501593,53.66770140276793],[8.49433012253546,55.502457780526],[9.207754805152648,55.48106268908912],[9.207754805152648,53.28027339774928],[7.63567991501593,53.28027339774928]]],"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.28027339774928],[7.63567991501593,53.66810821588294],[8.49433012253546,55.502457780526],[9.207754805152648,55.48106268908912],[9.207754805152648,53.28027339774928],[7.63567991501593,53.28027339774928]]],"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.49221819430999,82.48971755550389],[-52.49221819430999,82.94294978186194],[-49.28695697579964,83.47311821807558],[-44.52850362441216,83.7321400994933],[-29.525299334683975,83.7321400994933],[-25.263977329098022,83.58271128961059],[-21.183929736898254,83.39775984253468],[-21.183929736898254,82.74312310369845],[-23.404541300879075,82.48971755550389],[-52.49221819430999,82.48971755550389]]],"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.22790413350113,-53.20333324999222],[73.22790413350113,-53.01072925838941],[73.2594898268605,-52.94943913810479],[73.78992348164566,-52.94943913810479],[73.78992348164566,-53.06048282358537],[73.71782570332533,-53.20333324999222],[73.22790413350113,-53.20333324999222]]],"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.01653561766223,8.848981570244637],[-80.01653561766223,9.41480707574399],[-79.46859250242785,9.41480707574399],[-79.46859250242785,8.848981570244637],[-80.01653561766223,8.848981570244637]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-EO1A0120532016364110KF","name":"imagico.de OSM images for mapping: Panama Canal - Pacific side","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=EO1A0120532016364110KF&z={zoom}&x={x}&y={-y}","description":"EO1A0120532016364110KF, 2016-12-30, channels 123 (true color), New locks with less clouds than in the Sentinel-2 image - make sure to check image alignment","scaleExtent":[0,14],"polygon":[[[-79.62538719177245,8.770827350748924],[-79.68684196472167,8.821974500616129],[-79.6866703033447,8.93705081902936],[-79.65362548828124,9.0929436313527],[-79.268159866333,9.0929436313527],[-79.32832717895505,8.770827350748924],[-79.62538719177245,8.770827350748924]]],"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":[[[-53.20921946177197,-84.12524693598144],[-60.615377881406225,-83.78609327915953],[-60.615377881406225,-82.29968785439104],[-48.72405102147429,-82.29987186164387],[-44.52178052933989,-82.43683433550413],[-44.51354078327688,-84.12524693598144],[-53.20921946177197,-84.12524693598144]]],"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.112325688609005,42.1531576323006],[19.08425905347717,43.08073531915633],[20.63298799634826,43.09602978090892],[20.637880345591427,42.167791043253985],[19.112325688609005,42.1531576323006]]],"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.238571767352376,68.79971882076842],[-51.243335370562825,68.85302612951142],[-51.151668195269856,68.85302612951142],[-51.14038145973519,68.80116208175376],[-51.238571767352376,68.79971882076842]]],"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.96839858817646,22.36264542957619],[67.86231185721942,22.38391650007107],[67.86231185721942,24.886930816927297],[71.48986007499286,24.886930816927297],[71.48986007499286,22.36264542957619],[67.96839858817646,22.36264542957619]]],"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":[[[23.808114560320394,41.584878805945024],[22.992379697039144,41.6019534981177],[23.011863263323328,42.29983747360261],[23.99402383156063,42.283393175568236],[23.965613873674886,41.584878805945024],[23.808114560320394,41.584878805945024]]],"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.766296776846374,0.206886934953159],[29.766296776846374,0.509176367154027],[30.034603509024116,0.509176367154027],[30.034603509024116,0.206886934953159],[29.766296776846374,0.206886934953159]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R078_N01_20160702T082522","name":"imagico.de OSM images for mapping: Rwenzori Mountains 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R078_N01_20160702T082522&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160702T132847_R078_V20160702T082522_20160702T082522, 2016-07-02, channels 234 (true color), Up-to-date image for glacier mapping","scaleExtent":[0,14],"polygon":[[[29.8051357269287,0.235862065771959],[29.8051357269287,0.467085433008179],[30.02503395080565,0.467085433008179],[30.02503395080565,0.235862065771959],[29.8051357269287,0.235862065771959]]],"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.4263452007858],[-180,-67.32544337276457],[-179.8247337341308,-67.3253771978419],[-179.8247337341308,-67.4263452007858],[-180,-67.4263452007858]]],"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.12874872458635,-53.72050213468143],[-42.14625818503558,-53.45782244664258],[-41.67573435080706,-53.445862233424414],[-41.6558216310805,-53.70871763480476],[-42.12874872458635,-53.72050213468143]]],"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.84382442048364,-3.595452324350203],[120.84382442048364,-3.159848173206955],[120.98184016755395,-2.514681686347053],[122.62618449738794,-2.514681686347053],[122.62618449738794,-3.002148034113534],[122.5007000308352,-3.595452324350203],[120.84382442048364,-3.595452324350203]]],"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":[[[156.96951345925345,-84.50097988272655],[154.50857596843485,-84.46255082580927],[154.50857596843485,-82.60681485793681],[175.46774337070775,-82.58504749645738],[177.00582930246938,-83.52806548607914],[177.00582930246938,-84.19262083779002],[171.93838547371908,-84.34632646581997],[166.83798266071676,-84.44370142483508],[161.67028858819987,-84.50045345467909],[156.96951345925345,-84.50097988272655]]],"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.93976917529807,76.51132557714853],[-68.93976917529807,76.54990046497333],[-68.76634826923117,76.55175699880375],[-68.50992908740743,76.55175699880375],[-68.50743999744161,76.51611959755911],[-68.67897262836203,76.51193618208278],[-68.93976917529807,76.51132557714853]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-dms_thule2_2015.09.25","name":"imagico.de OSM images for mapping: Thule Airbase DMS low altitude overflight September 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_thule2_2015.09.25&z={zoom}&x={x}&y={-y}","description":"DMS 2015-09-25, true color, Icebridge DMS aerial images from Thule Airbase - alignment might be poor","scaleExtent":[0,17],"polygon":[[[-68.74291885235837,76.52635852412212],[-68.74446380475094,76.52840070669755],[-68.74806869366695,76.54938731810256],[-68.7461482320123,76.56016657973251],[-68.72275936940244,76.56022393334496],[-68.72017371991207,76.5577475347327],[-68.71853220799495,76.5292079974043],[-68.71977675297786,76.52636602351234],[-68.74291885235837,76.52635852412212]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-dms_thule_2015.10.06","name":"imagico.de OSM images for mapping: Thule Airbase DMS overflight October 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_thule_2015.10.06&z={zoom}&x={x}&y={-y}","description":"DMS 2015-10-06, true color, Icebridge DMS aerial images from Thule Airbase - alignment might be poor","scaleExtent":[0,16],"polygon":[[[-68.81923965911197,76.52510098413808],[-68.82651380996036,76.54176603738404],[-68.77344898680974,76.5439032956252],[-68.7021022270136,76.54544610909097],[-68.59176687697696,76.54560088014632],[-68.59183124999333,76.52793072237704],[-68.65970186690618,76.52510098413808],[-68.81923965911197,76.52510098413808]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-dms_thule_2015.09.25","name":"imagico.de OSM images for mapping: Thule Airbase DMS overflight September 2015","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=dms_thule_2015.09.25&z={zoom}&x={x}&y={-y}","description":"DMS 2015-09-25, true color, Icebridge DMS aerial images from Thule Airbase - alignment might be poor","scaleExtent":[0,16],"polygon":[[[-68.7777130980429,76.50687742381471],[-68.77661875676482,76.57064446843503],[-68.68115357350676,76.57065443536027],[-68.67630413960784,76.55384487076157],[-68.67619685124725,76.5307435998188],[-68.6852305312094,76.50688243050337],[-68.7777130980429,76.50687742381471]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R094_N79_20160812T105622","name":"imagico.de OSM images for mapping: Ushakov Island August 2016","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R094_N79_20160812T105622&z={zoom}&x={x}&y={-y}","description":"S2A_OPER_PRD_MSIL1C_PDMC_20160813T183324_R094_V20160812T105622_20160812T105622, 2016-08-12, channels 234 (true color), Up-to-date late summer imagery with few clouds","scaleExtent":[0,12],"polygon":[[[78.45885691499899,80.72643412860921],[78.45885691499899,80.9098976404357],[80.48892435884663,80.9098976404357],[80.48892435884663,80.72643412860921],[78.45885691499899,80.72643412860921]]],"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.0613810625655,-11.789228234021259],[153.0613810625655,-11.288690822294749],[153.10927458673538,-11.072292520575749],[154.41201277643268,-11.072292520575749],[154.41201277643268,-11.789228234021259],[153.0613810625655,-11.789228234021259]]],"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.51741123877955],[-72.8669610523419,-41.045274923011036],[-72.23181395761533,-41.045274923011036],[-71.87510161630674,-41.10829439141359],[-72.00007109872861,-41.51741123877955],[-72.8669610523419,-41.51741123877955]]],"terms_url":"http://maps.imagico.de/#osmim","terms_text":"imagico.de OSM images for mapping"},{"id":"osmim-imagicode-S2A_R089_N52_20160623T024048","name":"imagico.de OSM images for mapping: Vostochny Cosmodrome","type":"tms","template":"http://imagico.de/map/osmim_tiles.php?layer=S2A_R089_N52_20160623T024048&z={zoom}&x={x}&y={-y}","description":"S2A_R089_N52_20160623T024048, 2016-06-23, channels 234 (true color), Recent image showing newest features","scaleExtent":[0,13],"polygon":[[[126.36143429881301,51.375528375017275],[126.34804471141064,52.33932231282816],[128.60762341624462,52.340895519845674],[128.6117432892915,51.375528375017275],[126.36143429881301,51.375528375017275]]],"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":[[[75.98364343730569,34.97850982318471],[73.96164407817483,35.36957188964085],[74.44281091777444,37.09391400468158],[76.50600900737405,36.7026732100855],[75.98364343730569,34.97850982318471]]],"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.18070648306262,-14.4978507264954],[-71.17976234548938,-13.710292880050797],[-70.5563740550841,-13.71262765059222],[-70.5563740550841,-14.4978507264954],[-71.18070648306262,-14.4978507264954]]],"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":"Basel-Landschaft-2015","name":"Kanton Basel-Landschaft 10cm (2015)","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTBASELLANDSCHAFT2015/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[18,21],"polygon":[[[7.370281219482422,47.413684985326796],[7.357578277587891,47.41507892620101],[7.357921600341797,47.41827323486739],[7.353544235229492,47.4196089792119],[7.344875335693359,47.42402250214274],[7.339725494384765,47.42971307765559],[7.332687377929687,47.430235650685475],[7.32685089111328,47.4319194618196],[7.325280543317693,47.43489176778178],[7.33050406703179,47.44175856152086],[7.338990092194756,47.44109169292469],[7.344964876980962,47.43607806019703],[7.352656881264292,47.43435807026775],[7.38119797480828,47.432081698142134],[7.375988960266113,47.414309359238985],[7.378145456314087,47.41399717320828],[7.382040023803711,47.41330745332341],[7.388391494750976,47.41397539271845],[7.413708184603623,47.410929293287566],[7.420743520414262,47.411098781635985],[7.427483310496426,47.41448047082256],[7.438105529405026,47.412739349590474],[7.448396898794484,47.41507114537187],[7.455576414208223,47.42792319548619],[7.45061852232364,47.43534476535272],[7.437842682352891,47.446323188615104],[7.425422575234655,47.443283894442736],[7.420904049355535,47.44594415975335],[7.422417620777747,47.45071647996838],[7.428795928789581,47.45387944195848],[7.430028776685507,47.459491697398036],[7.445765194338128,47.46197276972992],[7.44717015944249,47.456958090215814],[7.456512189239691,47.44925575541638],[7.492356675875099,47.458972279610066],[7.530679075390223,47.46118857622267],[7.527445320030451,47.473906165741866],[7.536326693749955,47.48383279861684],[7.536231113003725,47.49105266753894],[7.532603895549507,47.490968962664795],[7.531789123586811,47.49739885661967],[7.520038351186771,47.49678264400428],[7.512226152318425,47.49891674929323],[7.509348758631863,47.508884893812876],[7.499082452238831,47.51627805213703],[7.497870355425969,47.52124757864722],[7.502278119030558,47.514906577969604],[7.517459288006065,47.51728104695845],[7.522200236749534,47.514091442409054],[7.530955756497733,47.52904526885427],[7.519353655277215,47.53471778813415],[7.510751927105658,47.528989768842564],[7.50229842095598,47.52840455858729],[7.4980383403841,47.536152181750076],[7.505454651706732,47.54438188661593],[7.516758242758337,47.545408295649786],[7.527317399933993,47.552778846515565],[7.554658254426867,47.564368052237306],[7.5645783501094,47.55703599040843],[7.561243624111692,47.55172275211291],[7.558752685660356,47.55235329499035],[7.555882119169953,47.54433555917895],[7.564785321950861,47.54568625396918],[7.587263056821628,47.54190064304111],[7.582688476068778,47.53246814131337],[7.589482524394103,47.5279230654027],[7.590248428005343,47.51978966346127],[7.594781326929009,47.51929395578897],[7.613780785019665,47.53925099543145],[7.622303281783164,47.53977428916004],[7.622854488041502,47.550040256825795],[7.617740918118178,47.554366555487356],[7.617617220103555,47.558648485827725],[7.632727781497729,47.5614887674157],[7.639973682410965,47.55816478484801],[7.648995462809379,47.548295861439875],[7.661308760240334,47.544832242956765],[7.665860164458853,47.53745814872834],[7.674674254363578,47.5337535789565],[7.694938989531916,47.532496041115465],[7.71346844906592,47.53978344629896],[7.715956243413761,47.53582195507857],[7.723622825374551,47.536754165368905],[7.727157067196862,47.53293048764033],[7.733221863174538,47.53275465944404],[7.737974130690588,47.52732498381306],[7.749022330706917,47.5249849998809],[7.757861753102653,47.52605097450287],[7.787633628417415,47.52011695778467],[7.790143521321244,47.51864117486466],[7.788870069574476,47.50682929074843],[7.792799480290271,47.500684271209245],[7.786625359342518,47.49312139201968],[7.798890147748131,47.49565149600841],[7.798162871694108,47.49939947973339],[7.799400121334925,47.497477088945935],[7.807418124234862,47.4971384859743],[7.814709929059118,47.504801278976316],[7.831976267472122,47.51473657456054],[7.833207588232065,47.53382387257594],[7.846527268275818,47.53266095290337],[7.852330295179702,47.53523506225097],[7.862569292788096,47.52692027402488],[7.86395674074442,47.519309183202445],[7.876658649367283,47.52269034821798],[7.87567113137545,47.51319304945735],[7.893993798731052,47.50605656803392],[7.904769180395594,47.49217505264052],[7.904821911502771,47.48490926161113],[7.93328835504665,47.48140776210853],[7.947015241408695,47.48488995686335],[7.940027875634228,47.462021295570224],[7.948854362289874,47.46377967418039],[7.957614193951437,47.45880646812721],[7.957849013566705,47.451279351685564],[7.946784554043733,47.44319336966537],[7.950032053627354,47.431716361052416],[7.96183169437885,47.421834282667845],[7.956570351591289,47.41968057428149],[7.955037646053525,47.415605646331336],[7.948388855309641,47.4162657867356],[7.934927870271696,47.41176694218953],[7.936722434714782,47.408057452805856],[7.932661510641391,47.40527495151619],[7.909737672400531,47.398520997340924],[7.890221593189976,47.407141074214024],[7.883331964118422,47.40609724771633],[7.883443085719068,47.4012049891245],[7.877702761222016,47.401257097623],[7.869136696167237,47.3955142728722],[7.879434713089799,47.38799354849815],[7.878812180597903,47.38351047538804],[7.862650230995195,47.38198499163919],[7.840119046365023,47.374763282921705],[7.830547227518145,47.36512144155488],[7.80216648325237,47.36109584064414],[7.796366151294341,47.3534705803715],[7.793560892325092,47.33905227137494],[7.78528803737905,47.3378822997136],[7.768963133383802,47.33891408469915],[7.766419194330703,47.342734660857005],[7.751518928544542,47.3443274446774],[7.734153146629586,47.35776074638933],[7.727913718160677,47.36885889855421],[7.701953574259492,47.37244716296033],[7.644203220263186,47.36720838530677],[7.641761060331779,47.38046937860509],[7.635580022356337,47.38059279713257],[7.633316986492583,47.38291397270416],[7.633305398225418,47.38533959871929],[7.637251158279386,47.38606854199808],[7.63272275093214,47.41003108104519],[7.664054730400831,47.41001995588381],[7.679802017668389,47.41751395224505],[7.686578998003315,47.43366406703297],[7.682972441800632,47.43872228466388],[7.684853783500164,47.447843589969715],[7.692273418589347,47.45421309996921],[7.698831030331891,47.45585888435835],[7.699930658071183,47.46190517358485],[7.709877972706822,47.469384739707586],[7.699760966314013,47.48063247960835],[7.668326578902932,47.48634665620256],[7.666120855554305,47.49686816039971],[7.65217109717027,47.49581439933043],[7.648646287658441,47.49183004211102],[7.655389581170213,47.49020559719241],[7.650513795302598,47.48826095607083],[7.655925875394832,47.48739459757455],[7.644422678687097,47.485637798180356],[7.640965961473804,47.482734093980326],[7.607299799570857,47.48939839412024],[7.608850381582776,47.48352506892989],[7.605631268762133,47.47935909729055],[7.608148977008936,47.475213682276376],[7.604494899927722,47.47044546774548],[7.618872436050056,47.4674530520825],[7.626072253389216,47.462913883669614],[7.62217338539308,47.46195224188912],[7.616464591762502,47.445234574416695],[7.615798850305441,47.432747890966844],[7.592069133423196,47.43271179535717],[7.581206884670679,47.42878068945942],[7.578423275099778,47.434906655087865],[7.568904367023134,47.43689695884281],[7.56829539909203,47.42233486107083],[7.58074128785892,47.414703988151935],[7.525235194936931,47.41163289737562],[7.531172340312734,47.40352507464003],[7.518616677418122,47.38822295597742],[7.511295677347134,47.38974369796625],[7.502255661148456,47.384806980223004],[7.492327480628366,47.385231761698726],[7.478410241257615,47.39055778320416],[7.47746817801916,47.401277162725364],[7.464484018734026,47.40251498235377],[7.460919593518167,47.40068414452088],[7.450020783333588,47.40392739156406],[7.44951323519806,47.39975827367453],[7.443401098004909,47.40231427489849],[7.441311347159463,47.40017886074712],[7.443566657511773,47.38890284041263],[7.437324174770898,47.3808884773088],[7.411692544769116,47.38057235919037],[7.416276198506335,47.384788794341716],[7.414494030814171,47.39429988358522],[7.398935569419335,47.39683906243558],[7.395920463999715,47.40338304393273],[7.388693876865087,47.403019088497395],[7.384054886906365,47.4123601395877],[7.379679679870605,47.4128137535428],[7.375844120979309,47.41401169352981],[7.370281219482422,47.413684985326796]]],"terms_url":"http://www.geo.bl.ch/fileadmin/user_upload/Geodaten/Nutzungsbedingungen_GBD_BL_V3p1.pdf","terms_text":"Geodaten des Kantons Basel-Landschaft 2015","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":[15,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":"londrina2011","name":"Londrina Ortofoto 2011","type":"tms","template":"https://siglon.londrina.pr.gov.br/arcgis/rest/services/Imagens/Ortofotos_2011_Paranacidade/MapServer/WMTS/tile/1.0.0/Imagens_Ortofotos_2011_Paranacidade/default/GoogleMapsCompatible/{zoom}/{y}/{x}","polygon":[[[-51.10903142008701,-23.392750890870328],[-51.110147219037096,-23.39111628244602],[-51.111981850003126,-23.389599820448623],[-51.11358044657587,-23.38976722295012],[-51.120999436701226,-23.38592675938185],[-51.12224934611127,-23.385109415587607],[-51.12483499560139,-23.383504255873166],[-51.12538216624037,-23.38186953335707],[-51.12482426676533,-23.37770385409619],[-51.12445948633935,-23.375054689723584],[-51.124373655650885,-23.372297138974446],[-51.12244246516032,-23.37032742475139],[-51.12302182230749,-23.366427304263887],[-51.128557901713755,-23.36548180323493],[-51.12832186732048,-23.358843408308623],[-51.12477062258506,-23.35475580404945],[-51.12703440699343,-23.35091432623551],[-51.12411616358548,-23.34679692655685],[-51.12025378260435,-23.347811512977742],[-51.1176466754421,-23.33969460448754],[-51.11264703783877,-23.341290443649072],[-51.109396200513004,-23.33488726938344],[-51.10756156954697,-23.334089313725826],[-51.10485790286019,-23.333980949007543],[-51.10252974543546,-23.334187827029368],[-51.09986899409291,-23.331015661953632],[-51.09801290545476,-23.329360589233605],[-51.09998701128955,-23.32830645478855],[-51.10322711977927,-23.325321337105603],[-51.10472915682748,-23.323193291476684],[-51.104664783811145,-23.321291814470847],[-51.10514758143378,-23.318444474199904],[-51.1063599399084,-23.3157547161216],[-51.10660670313775,-23.31467091543279],[-51.11050127062705,-23.311665785493048],[-51.111584883068964,-23.30842411016493],[-51.099504213666904,-23.309468549142686],[-51.09740136179941,-23.308631027972474],[-51.09511611971892,-23.307448636164267],[-51.09201548609798,-23.3049360186679],[-51.09036324534495,-23.3037141796735],[-51.09204767260616,-23.29874787986134],[-51.09269140276969,-23.297496421894902],[-51.09407542262125,-23.292953629109174],[-51.10073802981369,-23.293318240761657],[-51.10101697955121,-23.28870632248831],[-51.10068438563339,-23.28837126237015],[-51.10084531817427,-23.28777997775132],[-51.09937546763423,-23.28663682004102],[-51.09631774935752,-23.277914991984613],[-51.10285161051725,-23.273016720553397],[-51.10835550341534,-23.27033590016574],[-51.11309764895328,-23.268404099092194],[-51.13160489115448,-23.265338785827712],[-51.13188384089201,-23.262007272160396],[-51.1317336371872,-23.255058136908826],[-51.13290308031759,-23.254683563301587],[-51.132956724497895,-23.250750476893938],[-51.13473771128364,-23.2512729236245],[-51.13533852610292,-23.25133206840842],[-51.13516686472599,-23.24359373640034],[-51.13534925493897,-23.24117849627157],[-51.137516479822814,-23.24219388826517],[-51.13884685549409,-23.243495156026544],[-51.14108918223035,-23.24521044413634],[-51.1471724322756,-23.243179698340864],[-51.14761231455401,-23.23828015040167],[-51.149082165094036,-23.235884531292832],[-51.14976881060179,-23.236811236789336],[-51.15138886484666,-23.23853646924079],[-51.15289090189487,-23.238842079520833],[-51.15383503946804,-23.238950521710013],[-51.15820167574391,-23.238142132361276],[-51.16045473131624,-23.238161849232945],[-51.160347442955654,-23.24658068718069],[-51.15912435564498,-23.2478326235554],[-51.16131303820094,-23.247773477219496],[-51.166591625541805,-23.245939927797],[-51.17193458589902,-23.245821633420345],[-51.17205260309565,-23.249557713480034],[-51.174241285651625,-23.248404370116877],[-51.17514250788055,-23.2493211310392],[-51.176859121649926,-23.248157927934038],[-51.179466228812196,-23.251686936561047],[-51.18135450395853,-23.253806268366073],[-51.18273852381009,-23.253628837227893],[-51.18378994974384,-23.253264116924615],[-51.18495939287424,-23.253303546194683],[-51.18626831087339,-23.252150235227905],[-51.18665454897149,-23.247477745146526],[-51.191182117788244,-23.249143693933142],[-51.19141815218154,-23.252859966234126],[-51.19369266542598,-23.252781107419985],[-51.1938428691308,-23.26073575534214],[-51.20096681627374,-23.26054847664639],[-51.20126722368338,-23.24259807127726],[-51.209936123218775,-23.242775517090898],[-51.21090171846407,-23.26988252079656],[-51.21968863519614,-23.27221839365197],[-51.225965004290465,-23.2745345140599],[-51.22934458764894,-23.27860487489667],[-51.234515886629225,-23.28160089636689],[-51.23497722657975,-23.283246708422755],[-51.235073786104266,-23.285444377831148],[-51.23371122392482,-23.285897704227196],[-51.232155542696304,-23.28801649191402],[-51.22870085748543,-23.292293383844925],[-51.227402668322334,-23.294599300809004],[-51.22679112466699,-23.295476327114592],[-51.225600223864475,-23.29657013833941],[-51.22392652543933,-23.297210654251764],[-51.220482569064515,-23.30072850975029],[-51.21863720926242,-23.301300029310937],[-51.21668456109974,-23.30211788923888],[-51.21423838647836,-23.30441378240661],[-51.210966091480465,-23.306965823153238],[-51.22328279527583,-23.318296686707587],[-51.224387865389886,-23.31459209321986],[-51.22521398576639,-23.312887551432937],[-51.22511742624187,-23.312582111000477],[-51.22521398576639,-23.312513140483127],[-51.2255251220121,-23.312532846348883],[-51.22595427545445,-23.312385052284572],[-51.22616885217561,-23.31183328632629],[-51.22935531648505,-23.314887676277397],[-51.22802494081377,-23.31661189768144],[-51.227885465945,-23.31901591762422],[-51.22767088922384,-23.320227763653186],[-51.22723100694544,-23.321508564518947],[-51.2273919394863,-23.322227778055023],[-51.22725246461755,-23.322848466059934],[-51.230331640566384,-23.325577488448165],[-51.23046038659909,-23.326710459617892],[-51.229537706698046,-23.32789268010374],[-51.229162197436,-23.330503379743732],[-51.229290943468705,-23.33178408156439],[-51.22681258233914,-23.334473515196468],[-51.2260186484708,-23.336571826694826],[-51.22473118814376,-23.33839427691611],[-51.22210262330938,-23.340226553005806],[-51.22257469209598,-23.34196029634743],[-51.22380850824271,-23.343388647432523],[-51.22384069475089,-23.345309509145306],[-51.22440932306201,-23.347003784611864],[-51.2245380690947,-23.348294177581966],[-51.22404454263601,-23.34968305981433],[-51.22350810083308,-23.35010661675208],[-51.22381923707877,-23.35076657486812],[-51.22304676088255,-23.35174173085325],[-51.22259614976809,-23.35296312824164],[-51.22586844476598,-23.35480505304304],[-51.22650144609346,-23.36705763453823],[-51.22354028734128,-23.369145582171885],[-51.22366903337377,-23.37968330666716],[-51.220375280703756,-23.381633186264455],[-51.216469984378406,-23.38170212087667],[-51.21416328462579,-23.379949201028825],[-51.2092816642191,-23.37395167630701],[-51.20738266023672,-23.368141007697016],[-51.20628831895872,-23.36723491438801],[-51.20472190889416,-23.366269721227162],[-51.198230963078665,-23.366683376299132],[-51.19297383340994,-23.366506095711998],[-51.18986247095292,-23.3654424072124],[-51.18806002649507,-23.36464463523902],[-51.18718026193825,-23.3645264463904],[-51.18579624208668,-23.363738518041337],[-51.183038931219606,-23.36359078095478],[-51.18071077379488,-23.3637582163071],[-51.179069261877906,-23.361581540240305],[-51.177642326682125,-23.35836078207346],[-51.16683838877106,-23.356262814974126],[-51.166141014427254,-23.358538073547532],[-51.16475699457568,-23.360389770338585],[-51.16076586756186,-23.359217688669915],[-51.15983245882475,-23.36660458495632],[-51.162042599052846,-23.36861374957437],[-51.16276143106877,-23.374158492021696],[-51.158448438973174,-23.37580315788644],[-51.155047397942575,-23.376305417047273],[-51.15396378550066,-23.37903334042617],[-51.15298746141932,-23.381052164536694],[-51.15118501696147,-23.382076336717283],[-51.149167995782435,-23.382509637949354],[-51.14721534761976,-23.382155118864866],[-51.14517686876862,-23.382588419839323],[-51.14410398516276,-23.38376029492248],[-51.14512322458833,-23.388083341091015],[-51.141797285410156,-23.389402876058366],[-51.14030597719799,-23.38880219385971],[-51.14068148646006,-23.391608636504017],[-51.14127157244328,-23.393538646762796],[-51.14093897852546,-23.394434713394368],[-51.140456180902824,-23.39536031431835],[-51.13939402613302,-23.395104297688697],[-51.13738773379004,-23.393154616350518],[-51.13608954462695,-23.389796764546077],[-51.13428710016909,-23.389757375749994],[-51.132162790629465,-23.390072485790583],[-51.13172290835106,-23.39285920758337],[-51.12259266886514,-23.38864463742227],[-51.12228153261944,-23.391657871809155],[-51.11882684740854,-23.393174310244916],[-51.115683298443365,-23.393351555162592],[-51.10903142008701,-23.392750890870328]],[[-51.13829432042955,-23.41600741009485],[-51.133310776080314,-23.418665600378624],[-51.132087688769644,-23.416440600302334],[-51.13002238782791,-23.418291487939495],[-51.12868664773901,-23.419010176689888],[-51.12824140104259,-23.42102839134528],[-51.12696466955051,-23.421860280620358],[-51.12532852205271,-23.422692164660027],[-51.1244541219139,-23.420969322085504],[-51.1215144208339,-23.424109801147612],[-51.12063465627703,-23.423268081315832],[-51.11970661195797,-23.423120410617486],[-51.11977098497433,-23.42156985833077],[-51.1188000253111,-23.421545246243184],[-51.11643431696008,-23.420836416154565],[-51.11942766222045,-23.419167696990424],[-51.11787198099193,-23.416775337218567],[-51.116546969738685,-23.41730697646229],[-51.115699391690086,-23.415702207051474],[-51.115120034542905,-23.413088261827834],[-51.119078975048524,-23.411114231305813],[-51.119599323597356,-23.41169512115064],[-51.12052200349841,-23.41489489238112],[-51.12147686990764,-23.417139608782644],[-51.12308619531643,-23.418626220171642],[-51.12754939111684,-23.41653905242448],[-51.12803218873949,-23.417395582795194],[-51.13119719537679,-23.415574218468866],[-51.13080022844262,-23.414766903017576],[-51.13278506311348,-23.41264029239725],[-51.13521514448077,-23.411055157619415],[-51.13585887464424,-23.410956701416854],[-51.13682446988958,-23.411188073376714],[-51.137205343569626,-23.411576974270133],[-51.13730190309418,-23.41324086645236],[-51.137430649126884,-23.414707830961888],[-51.13829432042955,-23.41600741009485]],[[-51.18929065852,-23.61469318354],[-51.18868716149,-23.61385268133],[-51.18817754178,-23.61338573333],[-51.18731118826,-23.61301708899],[-51.18628926663,-23.61314488581],[-51.18401743559,-23.61395590119],[-51.18348904042,-23.61396573165],[-51.18183143525,-23.61283522407],[-51.18140496401,-23.61344471632],[-51.18062980561,-23.61313505529],[-51.18001021533,-23.61409352754],[-51.17865838198,-23.61328742827],[-51.18064589886,-23.61060367181],[-51.17972321896,-23.61018095058],[-51.18061639456,-23.60849005203],[-51.1821157494,-23.60850479833],[-51.18260927586,-23.60775273479],[-51.18319936184,-23.60804274673],[-51.18415154605,-23.60627808786],[-51.18511177687,-23.60666149766],[-51.18649043231,-23.60469528171],[-51.18902243762,-23.60610112912],[-51.18821241049,-23.60741848294],[-51.18918873458,-23.60801816947],[-51.188899056,-23.60953211999],[-51.18962325244,-23.60992535103],[-51.1911896625,-23.6111935131],[-51.1901489654,-23.61244691705],[-51.19054056792,-23.6127565797],[-51.19029380469,-23.61377895281],[-51.18929065852,-23.61469318354]],[[-51.08005769639,-23.52984412096],[-51.07962317853,-23.52205317842],[-51.08468182473,-23.52194496764],[-51.08581908135,-23.52404030606],[-51.0858941832,-23.52703569673],[-51.08579494147,-23.52777346722],[-51.08530141501,-23.52806365581],[-51.08513511805,-23.52856533627],[-51.08512438922,-23.52981952906],[-51.08470864682,-23.53023759067],[-51.08343459754,-23.53023759067],[-51.08329512267,-23.52978018202],[-51.08005769639,-23.52984412096]]],"terms_url":"http://siglon.londrina.pr.gov.br/","terms_text":"Prefeitura do Londrinas, PR"},{"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":"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-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":"lu.geoportail.opendata.ortho2010","name":"Ortho 2010 geoportail.lu","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"},{"id":"lu.geoportail.opendata.ortho2013","name":"Ortho 2013 geoportail.lu","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"},{"id":"lu.geoportail.opendata.ortho2016","name":"Ortho 2016 geoportail.lu","type":"tms","template":"https://{switch:wmts3,wmts4}.geoportail.lu/opendata/wmts/ortho_2016/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":"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":"lu.geoportail.opendata.topo","name":"Topographical Map geoportail.lu","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":"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]],[[-170.9996252,57.4005339],[-169.0007481,57.3999462],[-168.9994704,56.3988562],[-171.0011935,56.3991836],[-170.9996252,57.4005339]]]},{"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"}];
18619 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/drag_lift":{"geometry":["line"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"drag_lift"},"name":"Drag Lift"},"aerialway/gondola":{"geometry":["line"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"gondola"},"name":"Gondola"},"aerialway/goods":{"geometry":["line"],"fields":["aerialway/capacity","aerialway/duration"],"tags":{"aerialway":"goods"},"name":"Goods Aerialway"},"aerialway/magic_carpet":{"geometry":["line"],"fields":["aerialway/capacity","aerialway/duration","aerialway/heating"],"tags":{"aerialway":"magic_carpet"},"name":"Magic Carpet Lift"},"aerialway/mixed_lift":{"geometry":["line"],"fields":["aerialway/occupancy","aerialway/capacity","aerialway/duration","aerialway/bubble","aerialway/heating"],"tags":{"aerialway":"mixed_lift"},"name":"Mixed 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":{"icon":"aerialway","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"],"fields":["ref"],"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":{"icon":"airport","geometry":["point","area"],"terms":["airport","aerodrome"],"fields":["operator","building_area"],"tags":{"aeroway":"terminal"},"name":"Airport Terminal"},"amenity/coworking_space":{"icon":"commercial","fields":["address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"tags":{"office":"coworking"},"name":"Coworking Space","searchable":false},"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":{"icon":"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/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":"drinking-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","gun","lookout","rifle","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-alt1","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":"buddhism","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":"recycling","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":{"icon":"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","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"social_facility"},"name":"Social Facility"},"amenity/social_facility/food_bank":{"fields":["operator","address","building_area","social_facility","social_facility_for","opening_hours"],"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","social_facility","social_facility_for","opening_hours","wheelchair"],"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","social_facility","social_facility_for","opening_hours","wheelchair","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":"karaoke","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":"toilet","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":"veterinary","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":"drinking-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-alt1","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/border_control":{"icon":"roadblock","fields":["access","building_area"],"geometry":["vertex","area"],"tags":{"barrier":"border_control"},"name":"Border Control"},"barrier/cattle_grid":{"icon":"barrier","geometry":["vertex"],"tags":{"barrier":"cattle_grid"},"name":"Cattle Grid"},"barrier/city_wall":{"icon":"barrier","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":"fence","fields":["fence_type","height"],"geometry":["line"],"tags":{"barrier":"fence"},"name":"Fence","matchScore":0.25},"barrier/gate":{"icon":"barrier","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":"barrier","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","building_area"],"geometry":["vertex","area"],"tags":{"barrier":"toll_booth"},"name":"Toll Booth"},"barrier/wall":{"icon":"barrier","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":"home","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-alt1","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":"building","fields":["address","levels"],"geometry":["area"],"tags":{"building":"apartments"},"matchScore":0.5,"name":"Apartments"},"building/barn":{"icon":"farm","fields":["address","levels"],"geometry":["area"],"tags":{"building":"barn"},"matchScore":0.5,"name":"Barn"},"building/cabin":{"icon":"home","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":"home","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":"garden-center","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":"home","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":"industry","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":"residential-community","fields":["address","levels"],"geometry":["area"],"tags":{"building":"residential"},"matchScore":0.5,"name":"Residential Building"},"building/retail":{"icon":"commercial","fields":["address","levels","smoking"],"geometry":["area"],"tags":{"building":"retail"},"matchScore":0.5,"name":"Retail Building"},"building/roof":{"icon":"shelter","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":"home","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":"home","fields":["address","levels"],"geometry":["area"],"tags":{"building":"shed"},"matchScore":0.5,"name":"Shed"},"building/stable":{"icon":"horse-riding","fields":["address","levels"],"geometry":["area"],"tags":{"building":"stable"},"matchScore":0.5,"name":"Stable"},"building/static_caravan":{"icon":"home","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":"restaurant","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":"attraction","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"photographer"},"name":"Photographer"},"craft/photographic_laboratory":{"icon":"attraction","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":"logging","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":{"icon":"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","fire_hydrant/position"],"geometry":["point","vertex"],"terms":["fire plug"],"tags":{"emergency":"fire_hydrant"},"name":"Fire Hydrant"},"emergency/phone":{"icon":"emergency-phone","fields":["operator"],"geometry":["point","vertex"],"tags":{"emergency":"phone"},"name":"Emergency Phone"},"entrance":{"icon":"entrance-alt1","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":"blood-bank","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","toll","ref"],"geometry":["line"],"tags":{"highway":"motorway"},"terms":["autobahn","expressway","freeway","highway","interstate","parkway","thruway","turnpike"],"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","step_count"],"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":["tracktype","surface","width","structure","access","incline","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","toll","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":{"icon":"castle","fields":["castle_type","building_area"],"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":{"icon":"landmark","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":"*"},"matchScore":0.9,"name":"Land Use"},"landuse/farm":{"icon":"farm","fields":["operator","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":{"icon":"water","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":["operator","crop"],"geometry":["area"],"tags":{"landuse":"farmland"},"terms":["crop","grow","plant"],"name":"Farmland"},"landuse/farmyard":{"icon":"farm","fields":["operator","crop"],"geometry":["area"],"tags":{"landuse":"farmyard"},"terms":["crop","grow","plant"],"name":"Farmyard"},"landuse/forest":{"icon":"park-alt1","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":"industry","geometry":["area"],"tags":{"landuse":"industrial"},"terms":[],"matchScore":0.9,"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":[],"matchScore":0.9,"name":"Military Area"},"landuse/military/airfield":{"icon":"airfield","fields":["ref","iata","icao"],"geometry":["point","area"],"tags":{"military":"airfield"},"addTags":{"landuse":"military","military":"airfield"},"removeTags":{"landuse":"military","military":"airfield"},"terms":["air force","army","base","bomb","fight","force","guard","heli*","jet","marine","navy","plane","troop","war"],"name":"Military Airfield"},"landuse/military/barracks":{"fields":["building_area"],"geometry":["point","area"],"tags":{"military":"barracks"},"addTags":{"landuse":"military","military":"barracks"},"removeTags":{"landuse":"military","military":"barracks"},"terms":["air force","army","base","fight","force","guard","marine","navy","troop","war"],"name":"Barracks"},"landuse/military/bunker":{"fields":["bunker_type","building_area"],"geometry":["point","area"],"tags":{"military":"bunker"},"addTags":{"building":"bunker","landuse":"military","military":"bunker"},"removeTags":{"building":"bunker","landuse":"military","military":"bunker"},"terms":["air force","army","base","fight","force","guard","marine","navy","troop","war"],"name":"Military Bunker"},"landuse/military/checkpoint":{"geometry":["point","vertex","area"],"tags":{"military":"checkpoint"},"addTags":{"landuse":"military","military":"checkpoint"},"removeTags":{"landuse":"military","military":"checkpoint"},"terms":["air force","army","base","force","guard","marine","navy","troop","war"],"name":"Checkpoint"},"landuse/military/danger_area":{"icon":"danger","geometry":["point","vertex","area"],"tags":{"military":"danger_area"},"addTags":{"landuse":"military","military":"danger_area"},"removeTags":{"landuse":"military","military":"danger_area"},"terms":["air force","army","base","blast","bomb","explo*","force","guard","mine","marine","navy","troop","war"],"name":"Danger Area"},"landuse/military/naval_base":{"geometry":["point","area"],"tags":{"military":"naval_base"},"addTags":{"landuse":"military","military":"naval_base"},"removeTags":{"landuse":"military","military":"naval_base"},"terms":["base","fight","force","guard","marine","navy","ship","sub","troop","war"],"name":"Naval Base"},"landuse/military/nuclear_explosion_site":{"icon":"danger","geometry":["point","vertex","area"],"tags":{"military":"nuclear_explosion_site"},"addTags":{"landuse":"military","military":"nuclear_explosion_site"},"removeTags":{"landuse":"military","military":"nuclear_explosion_site"},"terms":["atom","blast","bomb","detonat*","nuke","site","test"],"name":"Nuclear Explosion Site"},"landuse/military/obstacle_course":{"geometry":["point","area"],"tags":{"military":"obstacle_course"},"addTags":{"landuse":"military","military":"obstacle_course"},"removeTags":{"landuse":"military","military":"obstacle_course"},"terms":["army","base","force","guard","marine","navy","troop","war"],"name":"Obstacle Course"},"landuse/military/office":{"fields":["building_area"],"geometry":["point","area"],"tags":{"military":"office"},"addTags":{"landuse":"military","military":"office"},"removeTags":{"landuse":"military","military":"office"},"terms":["air force","army","base","enlist","fight","force","guard","marine","navy","recruit","troop","war"],"name":"Military Office"},"landuse/military/range":{"geometry":["point","area"],"tags":{"military":"range"},"addTags":{"landuse":"military","military":"range"},"removeTags":{"landuse":"military","military":"range"},"terms":["air force","army","base","fight","fire","force","guard","gun","marine","navy","rifle","shoot*","snip*","train","troop","war"],"name":"Military Range"},"landuse/military/training_area":{"geometry":["point","area"],"tags":{"military":"training_area"},"addTags":{"landuse":"military","military":"training_area"},"removeTags":{"landuse":"military","military":"training_area"},"terms":["air force","army","base","fight","fire","force","guard","gun","marine","navy","rifle","shoot*","snip*","train","troop","war"],"name":"Training Area"},"landuse/orchard":{"icon":"park-alt1","fields":["operator","trees"],"geometry":["area"],"tags":{"landuse":"orchard"},"terms":["fruit"],"name":"Orchard"},"landuse/plant_nursery":{"icon":"garden","fields":["operator","plant"],"geometry":["area"],"tags":{"landuse":"plant_nursery"},"terms":["flower","garden","grow","vivero"],"name":"Plant Nursery"},"landuse/quarry":{"geometry":["area"],"tags":{"landuse":"quarry"},"terms":[],"name":"Quarry"},"landuse/recreation_ground":{"icon":"pitch","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":{"fields":["operator"],"geometry":["area"],"tags":{"landuse":"vineyard"},"terms":["grape","wine"],"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/horse_riding":{"icon":"horse-riding","fields":["access_simple","operator","address","building"],"geometry":["point","area"],"terms":["equestrian","stable"],"tags":{"leisure":"horse_riding"},"name":"Horseback Riding Facility"},"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":{"icon":"picnic-site","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":{"icon":"embassy","geometry":["point"],"tags":{"man_made":"flagpole"},"name":"Flagpole"},"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":"attraction","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":"attraction","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":{"icon":"water","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":{"icon":"industry","fields":["operator","address","building_area","product"],"geometry":["point","area"],"terms":["assembly","build","brewery","car","plant","plastic","processing","manufacture","refinery"],"tags":{"man_made":"works"},"name":"Factory"},"natural":{"fields":["natural"],"geometry":["point","vertex","area"],"tags":{"natural":"*"},"name":"Natural"},"natural/bare_rock":{"geometry":["area"],"tags":{"natural":"bare_rock"},"terms":["rock"],"name":"Bare Rock"},"natural/bay":{"geometry":["point","area"],"tags":{"natural":"bay"},"terms":[],"name":"Bay"},"natural/beach":{"fields":["surface"],"geometry":["point","area"],"tags":{"natural":"beach"},"terms":["shore"],"name":"Beach"},"natural/cave_entrance":{"geometry":["point","area"],"fields":["fee","access_simple"],"tags":{"natural":"cave_entrance"},"terms":["cavern","hollow","grotto","shelter","cavity"],"name":"Cave Entrance"},"natural/cliff":{"icon":"triangle","geometry":["point","vertex","line","area"],"tags":{"natural":"cliff"},"terms":["escarpment"],"name":"Cliff"},"natural/coastline":{"geometry":["line"],"tags":{"natural":"coastline"},"terms":["shore"],"name":"Coastline"},"natural/fell":{"geometry":["area"],"tags":{"natural":"fell"},"terms":[],"name":"Fell"},"natural/glacier":{"geometry":["area"],"tags":{"natural":"glacier"},"terms":[],"name":"Glacier"},"natural/grassland":{"geometry":["area"],"tags":{"natural":"grassland"},"terms":["prairie","savanna"],"name":"Grassland"},"natural/heath":{"geometry":["area"],"tags":{"natural":"heath"},"terms":[],"name":"Heath"},"natural/peak":{"icon":"mountain","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/ridge":{"geometry":["line"],"tags":{"natural":"ridge"},"terms":["crest"],"name":"Ridge"},"natural/saddle":{"icon":"triangle-stroked","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"saddle"},"terms":["pass","mountain pass","top"],"name":"Saddle"},"natural/sand":{"geometry":["area"],"tags":{"natural":"sand"},"terms":["desert"],"name":"Sand"},"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"],"tags":{"natural":"spring"},"terms":[],"name":"Spring"},"natural/tree_row":{"icon":"park","fields":["leaf_type","leaf_cycle","denotation"],"geometry":["line"],"tags":{"natural":"tree_row"},"terms":[],"name":"Tree row"},"natural/tree":{"icon":"park","fields":["leaf_type_singular","leaf_cycle_singular","denotation"],"geometry":["point","vertex"],"tags":{"natural":"tree"},"terms":[],"name":"Tree"},"natural/volcano":{"icon":"volcano","fields":["elevation"],"geometry":["point","vertex"],"tags":{"natural":"volcano"},"terms":["mountain","crater"],"name":"Volcano"},"natural/water":{"icon":"water","fields":["water"],"geometry":["area"],"tags":{"natural":"water"},"name":"Water"},"natural/water/lake":{"icon":"water","geometry":["area"],"tags":{"natural":"water","water":"lake"},"terms":["lakelet","loch","mere"],"name":"Lake"},"natural/water/pond":{"icon":"water","geometry":["area"],"tags":{"natural":"water","water":"pond"},"terms":["lakelet","millpond","tarn","pool","mere"],"name":"Pond"},"natural/water/reservoir":{"icon":"water","geometry":["area"],"tags":{"natural":"water","water":"reservoir"},"name":"Reservoir"},"natural/wetland":{"icon":"wetland","fields":["wetland"],"geometry":["point","area"],"tags":{"natural":"wetland"},"terms":[],"name":"Wetland"},"natural/wood":{"icon":"park-alt1","fields":["leaf_type","leaf_cycle"],"geometry":["point","area"],"tags":{"natural":"wood"},"terms":["tree"],"name":"Wood"},"noexit/yes":{"icon":"barrier","geometry":["vertex"],"terms":["no exit","road end","dead end"],"tags":{"noexit":"yes"},"name":"No Exit"},"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/coworking":{"icon":"commercial","fields":["address","building_area","opening_hours","internet_access","internet_access/fee","internet_access/ssid"],"geometry":["point","area"],"terms":["coworking","office"],"tags":{"office":"coworking"},"name":"Coworking Space"},"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/lawyer/notary":{"icon":"suitcase","fields":["address","building_area","opening_hours"],"geometry":["point","vertex","area"],"tags":{"office":"lawyer","lawyer":"notary"},"terms":["clerk","signature","wills","deeds","estate"],"name":"Notary 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/square":{"geometry":["point","area"],"tags":{"place":"square"},"name":"Square"},"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":{"icon":"power-line","geometry":["line"],"tags":{"power":"line"},"name":"Power Line"},"power/minor_line":{"icon":"power-line","geometry":["line"],"tags":{"power":"minor_line"},"name":"Minor Power Line"},"power/plant":{"icon":"industry","fields":["operator"],"geometry":["area"],"tags":{"power":"plant"},"addTags":{"power":"plant","landuse":"industrial"},"removeTags":{"power":"plant","landuse":"industrial"},"terms":["coal","gas","generat*","hydro","nuclear","power","station"],"name":"Power Station Grounds"},"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":{"icon":"bus","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":{"icon":"railway-rail","geometry":["line"],"terms":["venicular","cliff railway","cable car","cable railway","funicular railway"],"fields":["structure","gauge","service_rail"],"tags":{"railway":"funicular"},"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":{"icon":"rail","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":"entrance","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":"florist","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":"garden-center","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":"mobile-phone","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":"attraction","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":"teahouse","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":"gaming","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/watches":{"icon":"shop","fields":["operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"watches"},"name":"Watches Shop"},"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":"aquarium","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":{"icon":"information","fields":["information","operator","address","building_area"],"geometry":["point","vertex","area"],"tags":{"tourism":"information"},"name":"Information"},"tourism/information/board":{"icon":"information","fields":["operator","board_type"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"board"},"name":"Information Board"},"tourism/information/guidepost":{"icon":"information","fields":["operator","ref"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"guidepost"},"name":"Guidepost"},"tourism/information/map":{"icon":"information","fields":["operator","map_type","map_size"],"geometry":["point","vertex"],"tags":{"tourism":"information","information":"map"},"name":"Map"},"tourism/information/office":{"icon":"information","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":"picnic-site","fields":["operator","address","smoking"],"geometry":["point","vertex","area"],"terms":["camp"],"tags":{"tourism":"picnic_site"},"name":"Picnic Site"},"tourism/theme_park":{"icon":"amusement-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":"drinking-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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/МТС":{"tags":{"name":"МТС","shop":"mobile_phone"},"name":"МТС","icon":"mobile-phone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Евросеть":{"tags":{"name":"Евросеть","shop":"mobile_phone"},"name":"Евросеть","icon":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Связной":{"tags":{"name":"Связной","shop":"mobile_phone"},"name":"Связной","icon":"mobile-phone","geometry":["point","area"],"fields":["operator","address","building_area","opening_hours"],"suggestion":true},"shop/mobile_phone/Мегафон":{"tags":{"name":"Мегафон","shop":"mobile_phone"},"name":"Мегафон","icon":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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":"mobile-phone","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}};
18621 var defaults = {"area":["category-landuse","category-building","category-water-area","category-natural-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","category-natural-line","power/line","line"],"point":["category-natural-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"]};
18623 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":"landuse","members":["landuse/residential","landuse/industrial","landuse/commercial","landuse/retail","landuse/farmland","landuse/farmyard","landuse/forest","landuse/meadow","landuse/cemetery","landuse/military"]},"category-natural-area":{"geometry":"area","name":"Natural Features","icon":"natural","members":["natural/water","natural/wood","natural/scrub","natural/wetland","natural/grassland","natural/heath","natural/bare_rock","natural/beach","natural/cave_entrance","natural/glacier"]},"category-natural-line":{"geometry":"line","name":"Natural Features","icon":"natural","members":["natural/coastline","natural/tree_row"]},"category-natural-point":{"geometry":"point","name":"Natural Features","icon":"natural","members":["natural/peak","natural/cliff","natural/beach","natural/cave_entrance"]},"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/living_street","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"]}};
18625 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:block_number","addr:city","addr:block_number","addr:conscriptionnumber","addr:county","addr:country","addr:county","addr:district","addr:floor","addr:hamlet","addr:housename","addr:housenumber","addr:neighbourhood","addr:place","addr:postcode","addr:province","addr:quarter","addr:state","addr:street","addr:subdistrict","addr:suburb"],"reference":{"key":"addr"},"icon":"address","universal":true,"label":"Address","strings":{"placeholders":{"block_number":"Block Number","block_number!jp":"Block No.","city":"City","city!jp":"City/Town/Village/Tokyo Special Ward","city!vn":"City/Town","conscriptionnumber":"123","country":"Country","county":"County","county!jp":"District","district":"District","district!vn":"Arrondissement/Town/District","floor":"Floor","hamlet":"Hamlet","housename":"Housename","housenumber":"123","housenumber!jp":"Building No./Lot No.","neighbourhood":"Neighbourhood","neighbourhood!jp":"Chōme/Aza/Koaza","place":"Place","postcode":"Postcode","province":"Province","province!jp":"Prefecture","quarter":"Quarter","quarter!jp":"Ōaza/Machi","state":"State","street":"Street","subdistrict":"Subdistrict","subdistrict!vn":"Ward/Commune/Townlet","suburb":"Suburb","suburb!jp":"Ward"}}},"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"},"bunker_type":{"key":"bunker_type","type":"combo","label":"Type"},"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"}}},"castle_type":{"key":"castle_type","type":"combo","label":"Type"},"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"},"email":{"key":"email","type":"email","placeholder":"example@example.com","universal":true,"label":"Email"},"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","universal":true,"placeholder":"+31 42 123 4567"},"fee":{"key":"fee","type":"check","label":"Fee"},"fence_type":{"key":"fence_type","type":"combo","label":"Type"},"fire_hydrant/position":{"key":"fire_hydrant:position","type":"combo","label":"Position","strings":{"options":{"lane":"Lane","parking_lot":"Parking Lot","sidewalk":"Sidewalk","green":"Green"}}},"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":"check","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"},"plant":{"key":"plant","type":"combo","label":"Plant"},"population":{"key":"population","type":"text","label":"Population"},"power_supply":{"key":"power_supply","type":"check","label":"Power Supply"},"power":{"key":"power","type":"typeCombo","label":"Type"},"product":{"key":"product","type":"combo","label":"Product"},"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":"combo","label":"People Served"},"social_facility":{"key":"social_facility","type":"combo","label":"Type"},"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"},"step_count":{"key":"step_count","type":"number","label":"Number of Steps"},"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"}}},"toll":{"key":"toll","type":"check","label":"Toll"},"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"}};
18627 var all = ["aerialway","airfield","airport","alcohol-shop","america-football","amusement-park","aquarium","art-gallery","attraction","bakery","bank","bar","barrier","baseball","basketball","bbq","beer","bicycle","bicycle-share","blood-bank","buddhism","building","building-alt1","bus","cafe","campsite","car","castle","cemetery","cinema","circle","circle-stroked","city","clothing-store","college","commercial","cricket","cross","dam","danger","defibrillator","dentist","doctor","dog-park","drinking-water","embassy","emergency-phone","entrance","entrance-alt1","farm","fast-food","fence","ferry","fire-station","florist","fuel","gaming","garden","garden-center","gift","golf","grocery","hairdresser","harbor","heart","heliport","home","horse-riding","hospital","ice-cream","industry","information","karaoke","landmark","landuse","laundry","library","lighthouse","lodging","logging","marker","marker-stroked","mobile-phone","monument","mountain","museum","music","natural","park","park-alt1","parking","parking-garage","pharmacy","picnic-site","pitch","place-of-worship","playground","police","post","prison","rail","rail-light","rail-metro","ranger-station","recycling","religious-christian","religious-jewish","religious-muslim","residential-community","restaurant","roadblock","rocket","school","scooter","shelter","shop","skiing","slaughterhouse","snowmobile","soccer","square","square-stroked","stadium","star","star-stroked","suitcase","sushi","swimming","teahouse","telephone","tennis","theatre","toilet","town","town-hall","triangle","triangle-stroked","veterinary","village","volcano","warehouse","waste-basket","water","wetland","wheelchair","zoo"];
18632 var all$2 = Object.freeze({
18637 var Airport = ["airfield","airport","heliport","rocket"];
18638 var Dining = ["bakery","bar","beer","cafe","fast-food","ice-cream","restaurant"];
18639 var Education = ["college","school"];
18640 var General = ["alcohol-shop","amusement-park","aquarium","art-gallery","attraction","bank","bicycle","bicycle-share","car","castle","cinema","circle","circle-stroked","clothing-store","drinking-water","embassy","fire-station","fuel","grocery","harbor","information","laundry","library","lodging","marker","monument","museum","music","place-of-worship","police","post","prison","religious-christian","religious-jewish","religious-muslim","shop","stadium","star","suitcase","swimming","theatre","toilet","town-hall","triangle","triangle-stroked","veterinary"];
18641 var Health = ["dentist","doctor","hospital","pharmacy"];
18642 var Outdoors = ["campsite","cemetery","dog-park","garden","golf","park","picnic-site","playground","zoo"];
18643 var Transit = ["bus","ferry"];
18647 Education: Education,
18650 Outdoors: Outdoors,
18652 "Mountain peak": ["mountain","volcano"],
18653 "Rail station": ["entrance","rail","rail-light","rail-metro"]
18656 var streets$1 = Object.freeze({
18659 Education: Education,
18662 Outdoors: Outdoors,
18667 var require$$0 = ( all$2 && all$1 ) || all$2;
18669 var require$$1 = ( streets$1 && streets ) || streets$1;
18674 streets: require$$1
18678 var dataFeatureIcons = index$1.layouts.all.all;
18681 imagery: dataImagery,
18684 defaults: defaults,
18685 categories: categories,
18690 function osmEntity$$1(attrs) {
18691 // For prototypal inheritance.
18692 if (this instanceof osmEntity$$1) return;
18694 // Create the appropriate subtype.
18695 if (attrs && attrs.type) {
18696 return osmEntity$$1[attrs.type].apply(this, arguments);
18697 } else if (attrs && attrs.id) {
18698 return osmEntity$$1[osmEntity$$1.id.type(attrs.id)].apply(this, arguments);
18701 // Initialize a generic Entity (used only in tests).
18702 return (new osmEntity$$1()).initialize(arguments);
18706 osmEntity$$1.id = function(type) {
18707 return osmEntity$$1.id.fromOSM(type, osmEntity$$1.id.next[type]--);
18711 osmEntity$$1.id.next = {
18712 node: -1, way: -1, relation: -1
18716 osmEntity$$1.id.fromOSM = function(type, id) {
18717 return type[0] + id;
18721 osmEntity$$1.id.toOSM = function(id) {
18722 return id.slice(1);
18726 osmEntity$$1.id.type = function(id) {
18727 return { 'n': 'node', 'w': 'way', 'r': 'relation' }[id[0]];
18731 // A function suitable for use as the second argument to d3.selection#data().
18732 osmEntity$$1.key = function(entity) {
18733 return entity.id + 'v' + (entity.v || 0);
18737 osmEntity$$1.prototype = {
18742 initialize: function(sources) {
18743 for (var i = 0; i < sources.length; ++i) {
18744 var source = sources[i];
18745 for (var prop in source) {
18746 if (Object.prototype.hasOwnProperty.call(source, prop)) {
18747 if (source[prop] === undefined) {
18750 this[prop] = source[prop];
18756 if (!this.id && this.type) {
18757 this.id = osmEntity$$1.id(this.type);
18759 if (!this.hasOwnProperty('visible')) {
18760 this.visible = true;
18764 Object.freeze(this);
18765 Object.freeze(this.tags);
18767 if (this.loc) Object.freeze(this.loc);
18768 if (this.nodes) Object.freeze(this.nodes);
18769 if (this.members) Object.freeze(this.members);
18776 copy: function(resolver, copies) {
18777 if (copies[this.id])
18778 return copies[this.id];
18780 var copy = osmEntity$$1(this, {id: undefined, user: undefined, version: undefined});
18781 copies[this.id] = copy;
18787 osmId: function() {
18788 return osmEntity$$1.id.toOSM(this.id);
18792 isNew: function() {
18793 return this.osmId() < 0;
18797 update: function(attrs) {
18798 return osmEntity$$1(this, attrs, {v: 1 + (this.v || 0)});
18802 mergeTags: function(tags) {
18803 var merged = lodash.clone(this.tags), changed = false;
18804 for (var k in tags) {
18805 var t1 = merged[k],
18810 } else if (t1 !== t2) {
18812 merged[k] = lodash.union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
18815 return changed ? this.update({tags: merged}) : this;
18819 intersects: function(extent, resolver) {
18820 return this.extent(resolver).intersects(extent);
18824 isUsed: function(resolver) {
18825 return lodash.without(Object.keys(this.tags), 'area').length > 0 ||
18826 resolver.parentRelations(this).length > 0;
18830 hasInterestingTags: function() {
18831 return lodash.keys(this.tags).some(osmIsInterestingTag);
18835 isHighwayIntersection: function() {
18839 isDegenerate: function() {
18843 deprecatedTags: function() {
18844 var tags = lodash.toPairs(this.tags);
18845 var deprecated = {};
18847 dataDeprecated.forEach(function(d) {
18848 var match = lodash.toPairs(d.old)[0];
18849 tags.forEach(function(t) {
18850 if (t[0] === match[0] &&
18851 (t[1] === match[1] || match[1] === '*')) {
18852 deprecated[t[0]] = t[1];
18861 function geoRoundCoords(c) {
18862 return [Math.floor(c[0]), Math.floor(c[1])];
18866 function geoInterp(p1, p2, t) {
18867 return [p1[0] + (p2[0] - p1[0]) * t,
18868 p1[1] + (p2[1] - p1[1]) * t];
18872 // 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
18873 // Returns a positive value, if OAB makes a counter-clockwise turn,
18874 // negative for clockwise turn, and zero if the points are collinear.
18875 function geoCross(o, a, b) {
18876 return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
18880 // http://jsperf.com/id-dist-optimization
18881 function geoEuclideanDistance(a, b) {
18882 var x = a[0] - b[0], y = a[1] - b[1];
18883 return Math.sqrt((x * x) + (y * y));
18887 // using WGS84 polar radius (6356752.314245179 m)
18888 // const = 2 * PI * r / 360
18889 function geoLatToMeters(dLat) {
18890 return dLat * 110946.257617;
18894 // using WGS84 equatorial radius (6378137.0 m)
18895 // const = 2 * PI * r / 360
18896 function geoLonToMeters(dLon, atLat) {
18897 return Math.abs(atLat) >= 90 ? 0 :
18898 dLon * 111319.490793 * Math.abs(Math.cos(atLat * (Math.PI/180)));
18902 // using WGS84 polar radius (6356752.314245179 m)
18903 // const = 2 * PI * r / 360
18904 function geoMetersToLat(m) {
18905 return m / 110946.257617;
18909 // using WGS84 equatorial radius (6378137.0 m)
18910 // const = 2 * PI * r / 360
18911 function geoMetersToLon(m, atLat) {
18912 return Math.abs(atLat) >= 90 ? 0 :
18913 m / 111319.490793 / Math.abs(Math.cos(atLat * (Math.PI/180)));
18917 function geoOffsetToMeters(offset) {
18918 var equatRadius = 6356752.314245179,
18919 polarRadius = 6378137.0,
18923 offset[0] * 2 * Math.PI * equatRadius / tileSize,
18924 -offset[1] * 2 * Math.PI * polarRadius / tileSize
18929 function geoMetersToOffset(meters) {
18930 var equatRadius = 6356752.314245179,
18931 polarRadius = 6378137.0,
18935 meters[0] * tileSize / (2 * Math.PI * equatRadius),
18936 -meters[1] * tileSize / (2 * Math.PI * polarRadius)
18941 // Equirectangular approximation of spherical distances on Earth
18942 function geoSphericalDistance(a, b) {
18943 var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2),
18944 y = geoLatToMeters(a[1] - b[1]);
18945 return Math.sqrt((x * x) + (y * y));
18949 function geoEdgeEqual(a, b) {
18950 return (a[0] === b[0] && a[1] === b[1]) ||
18951 (a[0] === b[1] && a[1] === b[0]);
18955 // Return the counterclockwise angle in the range (-pi, pi)
18956 // between the positive X axis and the line intersecting a and b.
18957 function geoAngle(a, b, projection) {
18958 a = projection(a.loc);
18959 b = projection(b.loc);
18960 return Math.atan2(b[1] - a[1], b[0] - a[0]);
18964 // Rotate all points counterclockwise around a pivot point by given angle
18965 function geoRotate(points, angle, around) {
18966 return points.map(function(point) {
18967 var radial = [point[0] - around[0], point[1] - around[1]];
18969 radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + around[0],
18970 radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + around[1]
18976 // Choose the edge with the minimal distance from `point` to its orthogonal
18977 // projection onto that edge, if such a projection exists, or the distance to
18978 // the closest vertex on that edge. Returns an object with the `index` of the
18979 // chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
18980 function geoChooseEdge(nodes, point, projection) {
18981 var dist = geoEuclideanDistance,
18982 points = nodes.map(function(n) { return projection(n.loc); }),
18986 function dot(p, q) {
18987 return p[0] * q[0] + p[1] * q[1];
18990 for (var i = 0; i < points.length - 1; i++) {
18992 s = [points[i + 1][0] - o[0],
18993 points[i + 1][1] - o[1]],
18994 v = [point[0] - o[0],
18996 proj = dot(v, s) / dot(s, s),
19001 } else if (proj > 1) {
19004 p = [o[0] + proj * s[0], o[1] + proj * s[1]];
19007 var d = dist(p, point);
19011 loc = projection.invert(p);
19023 // Return the intersection point of 2 line segments.
19024 // From https://github.com/pgkelley4/line-segments-intersect
19025 // This uses the vector cross product approach described below:
19026 // http://stackoverflow.com/a/565282/786339
19027 function geoLineIntersection(a, b) {
19028 function subtractPoints(point1, point2) {
19029 return [point1[0] - point2[0], point1[1] - point2[1]];
19031 function crossProduct(point1, point2) {
19032 return point1[0] * point2[1] - point1[1] * point2[0];
19035 var p = [a[0][0], a[0][1]],
19036 p2 = [a[1][0], a[1][1]],
19037 q = [b[0][0], b[0][1]],
19038 q2 = [b[1][0], b[1][1]],
19039 r = subtractPoints(p2, p),
19040 s = subtractPoints(q2, q),
19041 uNumerator = crossProduct(subtractPoints(q, p), r),
19042 denominator = crossProduct(r, s);
19044 if (uNumerator && denominator) {
19045 var u = uNumerator / denominator,
19046 t = crossProduct(subtractPoints(q, p), s) / denominator;
19048 if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
19049 return geoInterp(p, p2, t);
19057 function geoPathIntersections(path1, path2) {
19058 var intersections = [];
19059 for (var i = 0; i < path1.length - 1; i++) {
19060 for (var j = 0; j < path2.length - 1; j++) {
19061 var a = [ path1[i], path1[i+1] ],
19062 b = [ path2[j], path2[j+1] ],
19063 hit = geoLineIntersection(a, b);
19064 if (hit) intersections.push(hit);
19067 return intersections;
19071 // Return whether point is contained in polygon.
19073 // `point` should be a 2-item array of coordinates.
19074 // `polygon` should be an array of 2-item arrays of coordinates.
19076 // From https://github.com/substack/point-in-polygon.
19077 // ray-casting algorithm based on
19078 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
19080 function geoPointInPolygon(point, polygon) {
19085 for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
19086 var xi = polygon[i][0], yi = polygon[i][1];
19087 var xj = polygon[j][0], yj = polygon[j][1];
19089 var intersect = ((yi > y) !== (yj > y)) &&
19090 (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
19091 if (intersect) inside = !inside;
19098 function geoPolygonContainsPolygon(outer, inner) {
19099 return lodash.every(inner, function(point) {
19100 return geoPointInPolygon(point, outer);
19105 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
19106 function testSegments(outer, inner) {
19107 for (var i = 0; i < outer.length - 1; i++) {
19108 for (var j = 0; j < inner.length - 1; j++) {
19109 var a = [ outer[i], outer[i+1] ],
19110 b = [ inner[j], inner[j+1] ];
19111 if (geoLineIntersection(a, b)) return true;
19117 function testPoints(outer, inner) {
19118 return lodash.some(inner, function(point) {
19119 return geoPointInPolygon(point, outer);
19123 return testPoints(outer, inner) || (!!checkSegments && testSegments(outer, inner));
19127 function geoPathLength(path) {
19129 for (var i = 0; i < path.length - 1; i++) {
19130 length += geoEuclideanDistance(path[i], path[i + 1]);
19135 function geoExtent$$1(min, max) {
19136 if (!(this instanceof geoExtent$$1)) return new geoExtent$$1(min, max);
19137 if (min instanceof geoExtent$$1) {
19139 } else if (min && min.length === 2 && min[0].length === 2 && min[1].length === 2) {
19143 this[0] = min || [ Infinity, Infinity];
19144 this[1] = max || min || [-Infinity, -Infinity];
19148 geoExtent$$1.prototype = new Array(2);
19150 lodash.extend(geoExtent$$1.prototype, {
19152 equals: function (obj) {
19153 return this[0][0] === obj[0][0] &&
19154 this[0][1] === obj[0][1] &&
19155 this[1][0] === obj[1][0] &&
19156 this[1][1] === obj[1][1];
19160 extend: function(obj) {
19161 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19162 return geoExtent$$1(
19163 [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
19164 [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
19169 _extend: function(extent) {
19170 this[0][0] = Math.min(extent[0][0], this[0][0]);
19171 this[0][1] = Math.min(extent[0][1], this[0][1]);
19172 this[1][0] = Math.max(extent[1][0], this[1][0]);
19173 this[1][1] = Math.max(extent[1][1], this[1][1]);
19178 return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
19182 center: function() {
19183 return [(this[0][0] + this[1][0]) / 2,
19184 (this[0][1] + this[1][1]) / 2];
19188 rectangle: function() {
19189 return [this[0][0], this[0][1], this[1][0], this[1][1]];
19194 return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
19198 polygon: function() {
19200 [this[0][0], this[0][1]],
19201 [this[0][0], this[1][1]],
19202 [this[1][0], this[1][1]],
19203 [this[1][0], this[0][1]],
19204 [this[0][0], this[0][1]]
19209 contains: function(obj) {
19210 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19211 return obj[0][0] >= this[0][0] &&
19212 obj[0][1] >= this[0][1] &&
19213 obj[1][0] <= this[1][0] &&
19214 obj[1][1] <= this[1][1];
19218 intersects: function(obj) {
19219 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19220 return obj[0][0] <= this[1][0] &&
19221 obj[0][1] <= this[1][1] &&
19222 obj[1][0] >= this[0][0] &&
19223 obj[1][1] >= this[0][1];
19227 intersection: function(obj) {
19228 if (!this.intersects(obj)) return new geoExtent$$1();
19229 return new geoExtent$$1(
19230 [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
19231 [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
19236 percentContainedIn: function(obj) {
19237 if (!(obj instanceof geoExtent$$1)) obj = new geoExtent$$1(obj);
19238 var a1 = this.intersection(obj).area(),
19241 if (a1 === Infinity || a2 === Infinity || a1 === 0 || a2 === 0) {
19249 padByMeters: function(meters) {
19250 var dLat = geoMetersToLat(meters),
19251 dLon = geoMetersToLon(meters, this.center()[1]);
19252 return geoExtent$$1(
19253 [this[0][0] - dLon, this[0][1] - dLat],
19254 [this[1][0] + dLon, this[1][1] + dLat]
19259 toParam: function() {
19260 return this.rectangle().join(',');
19265 var version = "4.5.0";
19267 var ascending = function(a, b) {
19268 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
19271 var bisector = function(compare) {
19272 if (compare.length === 1) compare = ascendingComparator(compare);
19274 left: function(a, x, lo, hi) {
19275 if (lo == null) lo = 0;
19276 if (hi == null) hi = a.length;
19278 var mid = lo + hi >>> 1;
19279 if (compare(a[mid], x) < 0) lo = mid + 1;
19284 right: function(a, x, lo, hi) {
19285 if (lo == null) lo = 0;
19286 if (hi == null) hi = a.length;
19288 var mid = lo + hi >>> 1;
19289 if (compare(a[mid], x) > 0) hi = mid;
19297 function ascendingComparator(f) {
19298 return function(d, x) {
19299 return ascending(f(d), x);
19303 var ascendingBisect = bisector(ascending);
19304 var bisectRight = ascendingBisect.right;
19305 var bisectLeft = ascendingBisect.left;
19307 var descending = function(a, b) {
19308 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
19311 var number = function(x) {
19312 return x === null ? NaN : +x;
19315 var variance = function(array, f) {
19316 var n = array.length,
19326 if (!isNaN(a = number(array[i]))) {
19336 if (!isNaN(a = number(f(array[i], i, array)))) {
19344 if (j > 1) return s / (j - 1);
19347 var deviation = function(array, f) {
19348 var v = variance(array, f);
19349 return v ? Math.sqrt(v) : v;
19352 var extent = function(array, f) {
19360 while (++i < n) if ((b = array[i]) != null && b >= b) { a = c = b; break; }
19361 while (++i < n) if ((b = array[i]) != null) {
19368 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; }
19369 while (++i < n) if ((b = f(array[i], i, array)) != null) {
19378 var array = Array.prototype;
19380 var slice = array.slice;
19381 var map = array.map;
19383 var constant = function(x) {
19384 return function() {
19389 var identity = function(x) {
19393 var sequence = function(start, stop, step) {
19394 start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
19397 n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
19398 range = new Array(n);
19401 range[i] = start + i * step;
19407 var e10 = Math.sqrt(50);
19408 var e5 = Math.sqrt(10);
19409 var e2 = Math.sqrt(2);
19411 var ticks = function(start, stop, count) {
19412 var step = tickStep(start, stop, count);
19414 Math.ceil(start / step) * step,
19415 Math.floor(stop / step) * step + step / 2, // inclusive
19420 function tickStep(start, stop, count) {
19421 var step0 = Math.abs(stop - start) / Math.max(0, count),
19422 step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
19423 error = step0 / step1;
19424 if (error >= e10) step1 *= 10;
19425 else if (error >= e5) step1 *= 5;
19426 else if (error >= e2) step1 *= 2;
19427 return stop < start ? -step1 : step1;
19430 var sturges = function(values) {
19431 return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
19434 var histogram = function() {
19435 var value = identity,
19437 threshold = sturges;
19439 function histogram(data) {
19443 values = new Array(n);
19445 for (i = 0; i < n; ++i) {
19446 values[i] = value(data[i], i, data);
19449 var xz = domain(values),
19452 tz = threshold(values, x0, x1);
19454 // Convert number of thresholds into uniform thresholds.
19455 if (!Array.isArray(tz)) tz = ticks(x0, x1, tz);
19457 // Remove any thresholds outside the domain.
19459 while (tz[0] <= x0) tz.shift(), --m;
19460 while (tz[m - 1] >= x1) tz.pop(), --m;
19462 var bins = new Array(m + 1),
19465 // Initialize bins.
19466 for (i = 0; i <= m; ++i) {
19467 bin = bins[i] = [];
19468 bin.x0 = i > 0 ? tz[i - 1] : x0;
19469 bin.x1 = i < m ? tz[i] : x1;
19472 // Assign data to bins by value, ignoring any outside the domain.
19473 for (i = 0; i < n; ++i) {
19475 if (x0 <= x && x <= x1) {
19476 bins[bisectRight(tz, x, 0, m)].push(data[i]);
19483 histogram.value = function(_) {
19484 return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value;
19487 histogram.domain = function(_) {
19488 return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain;
19491 histogram.thresholds = function(_) {
19492 return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;
19498 var threshold = function(array, p, f) {
19499 if (f == null) f = number;
19500 if (!(n = array.length)) return;
19501 if ((p = +p) <= 0 || n < 2) return +f(array[0], 0, array);
19502 if (p >= 1) return +f(array[n - 1], n - 1, array);
19506 a = +f(array[i], i, array),
19507 b = +f(array[i + 1], i + 1, array);
19508 return a + (b - a) * (h - i);
19511 var freedmanDiaconis = function(values, min, max) {
19512 values = map.call(values, number).sort(ascending);
19513 return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));
19516 var scott = function(values, min, max) {
19517 return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
19520 var max = function(array, f) {
19527 while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
19528 while (++i < n) if ((b = array[i]) != null && b > a) a = b;
19532 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
19533 while (++i < n) if ((b = f(array[i], i, array)) != null && b > a) a = b;
19539 var mean = function(array, f) {
19547 while (++i < n) if (!isNaN(a = number(array[i]))) s += a; else --j;
19551 while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) s += a; else --j;
19554 if (j) return s / j;
19557 var median = function(array, f) {
19564 while (++i < n) if (!isNaN(a = number(array[i]))) numbers.push(a);
19568 while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) numbers.push(a);
19571 return threshold(numbers.sort(ascending), 0.5);
19574 var merge = function(arrays) {
19575 var n = arrays.length,
19582 while (++i < n) j += arrays[i].length;
19583 merged = new Array(j);
19589 merged[--j] = array[m];
19596 var min = function(array, f) {
19603 while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; }
19604 while (++i < n) if ((b = array[i]) != null && a > b) a = b;
19608 while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; }
19609 while (++i < n) if ((b = f(array[i], i, array)) != null && a > b) a = b;
19615 var pairs = function(array) {
19616 var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
19617 while (i < n) pairs[i] = [p, p = array[++i]];
19621 var permute = function(array, indexes) {
19622 var i = indexes.length, permutes = new Array(i);
19623 while (i--) permutes[i] = array[indexes[i]];
19627 var scan = function(array, compare) {
19628 if (!(n = array.length)) return;
19635 if (!compare) compare = ascending;
19637 while (++i < n) if (compare(xi = array[i], xj) < 0 || compare(xj, xj) !== 0) xj = xi, j = i;
19639 if (compare(xj, xj) === 0) return j;
19642 var shuffle = function(array, i0, i1) {
19643 var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),
19648 i = Math.random() * m-- | 0;
19650 array[m + i0] = array[i + i0];
19657 var sum = function(array, f) {
19664 while (++i < n) if (a = +array[i]) s += a; // Note: zero and null are equivalent.
19668 while (++i < n) if (a = +f(array[i], i, array)) s += a;
19674 var transpose = function(matrix) {
19675 if (!(n = matrix.length)) return [];
19676 for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
19677 for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
19678 row[j] = matrix[j][i];
19684 function length(d) {
19688 var zip = function() {
19689 return transpose(arguments);
19692 var slice$1 = Array.prototype.slice;
19694 var identity$1 = function(x) {
19702 var epsilon = 1e-6;
19704 function translateX(scale0, scale1, d) {
19706 return "translate(" + (isFinite(x) ? x : scale1(d)) + ",0)";
19709 function translateY(scale0, scale1, d) {
19711 return "translate(0," + (isFinite(y) ? y : scale1(d)) + ")";
19714 function center(scale) {
19715 var offset = scale.bandwidth() / 2;
19716 if (scale.round()) offset = Math.round(offset);
19717 return function(d) {
19718 return scale(d) + offset;
19722 function entering() {
19723 return !this.__axis;
19726 function axis(orient, scale) {
19727 var tickArguments = [],
19734 function axis(context) {
19735 var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
19736 format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,
19737 spacing = Math.max(tickSizeInner, 0) + tickPadding,
19738 transform = orient === top || orient === bottom ? translateX : translateY,
19739 range = scale.range(),
19740 range0 = range[0] + 0.5,
19741 range1 = range[range.length - 1] + 0.5,
19742 position = (scale.bandwidth ? center : identity$1)(scale.copy()),
19743 selection = context.selection ? context.selection() : context,
19744 path = selection.selectAll(".domain").data([null]),
19745 tick = selection.selectAll(".tick").data(values, scale).order(),
19746 tickExit = tick.exit(),
19747 tickEnter = tick.enter().append("g").attr("class", "tick"),
19748 line = tick.select("line"),
19749 text = tick.select("text"),
19750 k = orient === top || orient === left ? -1 : 1,
19751 x, y = orient === left || orient === right ? (x = "x", "y") : (x = "y", "x");
19753 path = path.merge(path.enter().insert("path", ".tick")
19754 .attr("class", "domain")
19755 .attr("stroke", "#000"));
19757 tick = tick.merge(tickEnter);
19759 line = line.merge(tickEnter.append("line")
19760 .attr("stroke", "#000")
19761 .attr(x + "2", k * tickSizeInner)
19762 .attr(y + "1", 0.5)
19763 .attr(y + "2", 0.5));
19765 text = text.merge(tickEnter.append("text")
19766 .attr("fill", "#000")
19767 .attr(x, k * spacing)
19769 .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
19771 if (context !== selection) {
19772 path = path.transition(context);
19773 tick = tick.transition(context);
19774 line = line.transition(context);
19775 text = text.transition(context);
19777 tickExit = tickExit.transition(context)
19778 .attr("opacity", epsilon)
19779 .attr("transform", function(d) { return transform(position, this.parentNode.__axis || position, d); });
19782 .attr("opacity", epsilon)
19783 .attr("transform", function(d) { return transform(this.parentNode.__axis || position, position, d); });
19789 .attr("d", orient === left || orient == right
19790 ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
19791 : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
19794 .attr("opacity", 1)
19795 .attr("transform", function(d) { return transform(position, position, d); });
19798 .attr(x + "2", k * tickSizeInner);
19801 .attr(x, k * spacing)
19804 selection.filter(entering)
19805 .attr("fill", "none")
19806 .attr("font-size", 10)
19807 .attr("font-family", "sans-serif")
19808 .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
19811 .each(function() { this.__axis = position; });
19814 axis.scale = function(_) {
19815 return arguments.length ? (scale = _, axis) : scale;
19818 axis.ticks = function() {
19819 return tickArguments = slice$1.call(arguments), axis;
19822 axis.tickArguments = function(_) {
19823 return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();
19826 axis.tickValues = function(_) {
19827 return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();
19830 axis.tickFormat = function(_) {
19831 return arguments.length ? (tickFormat = _, axis) : tickFormat;
19834 axis.tickSize = function(_) {
19835 return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
19838 axis.tickSizeInner = function(_) {
19839 return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
19842 axis.tickSizeOuter = function(_) {
19843 return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
19846 axis.tickPadding = function(_) {
19847 return arguments.length ? (tickPadding = +_, axis) : tickPadding;
19853 function axisTop(scale) {
19854 return axis(top, scale);
19857 function axisRight(scale) {
19858 return axis(right, scale);
19861 function axisBottom(scale) {
19862 return axis(bottom, scale);
19865 function axisLeft(scale) {
19866 return axis(left, scale);
19869 var noop = {value: function() {}};
19871 function dispatch() {
19872 for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
19873 if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
19876 return new Dispatch(_);
19879 function Dispatch(_) {
19883 function parseTypenames(typenames, types) {
19884 return typenames.trim().split(/^|\s+/).map(function(t) {
19885 var name = "", i = t.indexOf(".");
19886 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
19887 if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
19888 return {type: t, name: name};
19892 Dispatch.prototype = dispatch.prototype = {
19893 constructor: Dispatch,
19894 on: function(typename, callback) {
19896 T = parseTypenames(typename + "", _),
19901 // If no callback was specified, return the callback of the given type and name.
19902 if (arguments.length < 2) {
19903 while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
19907 // If a type was specified, set the callback for the given type and name.
19908 // Otherwise, if a null callback was specified, remove callbacks of the given name.
19909 if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
19911 if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
19912 else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
19918 var copy = {}, _ = this._;
19919 for (var t in _) copy[t] = _[t].slice();
19920 return new Dispatch(copy);
19922 call: function(type, that) {
19923 if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
19924 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
19925 for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
19927 apply: function(type, that, args) {
19928 if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
19929 for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
19933 function get(type, name) {
19934 for (var i = 0, n = type.length, c; i < n; ++i) {
19935 if ((c = type[i]).name === name) {
19941 function set(type, name, callback) {
19942 for (var i = 0, n = type.length; i < n; ++i) {
19943 if (type[i].name === name) {
19944 type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
19948 if (callback != null) type.push({name: name, value: callback});
19952 var xhtml = "http://www.w3.org/1999/xhtml";
19955 svg: "http://www.w3.org/2000/svg",
19957 xlink: "http://www.w3.org/1999/xlink",
19958 xml: "http://www.w3.org/XML/1998/namespace",
19959 xmlns: "http://www.w3.org/2000/xmlns/"
19962 var namespace = function(name) {
19963 var prefix = name += "", i = prefix.indexOf(":");
19964 if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
19965 return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
19968 function creatorInherit(name) {
19969 return function() {
19970 var document = this.ownerDocument,
19971 uri = this.namespaceURI;
19972 return uri === xhtml && document.documentElement.namespaceURI === xhtml
19973 ? document.createElement(name)
19974 : document.createElementNS(uri, name);
19978 function creatorFixed(fullname) {
19979 return function() {
19980 return this.ownerDocument.createElementNS(fullname.space, fullname.local);
19984 var creator = function(name) {
19985 var fullname = namespace(name);
19986 return (fullname.local
19988 : creatorInherit)(fullname);
19993 function local$1() {
19998 this._ = "@" + (++nextId).toString(36);
20001 Local.prototype = local$1.prototype = {
20002 constructor: Local,
20003 get: function(node) {
20005 while (!(id in node)) if (!(node = node.parentNode)) return;
20008 set: function(node, value) {
20009 return node[this._] = value;
20011 remove: function(node) {
20012 return this._ in node && delete node[this._];
20014 toString: function() {
20019 var matcher = function(selector) {
20020 return function() {
20021 return this.matches(selector);
20025 if (typeof document !== "undefined") {
20026 var element = document.documentElement;
20027 if (!element.matches) {
20028 var vendorMatches = element.webkitMatchesSelector
20029 || element.msMatchesSelector
20030 || element.mozMatchesSelector
20031 || element.oMatchesSelector;
20032 matcher = function(selector) {
20033 return function() {
20034 return vendorMatches.call(this, selector);
20040 var matcher$1 = matcher;
20042 var filterEvents = {};
20046 if (typeof document !== "undefined") {
20047 var element$1 = document.documentElement;
20048 if (!("onmouseenter" in element$1)) {
20049 filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
20053 function filterContextListener(listener, index, group) {
20054 listener = contextListener(listener, index, group);
20055 return function(event) {
20056 var related = event.relatedTarget;
20057 if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
20058 listener.call(this, event);
20063 function contextListener(listener, index, group) {
20064 return function(event1) {
20065 var event0 = event; // Events can be reentrant (e.g., focus).
20068 listener.call(this, this.__data__, index, group);
20075 function parseTypenames$1(typenames) {
20076 return typenames.trim().split(/^|\s+/).map(function(t) {
20077 var name = "", i = t.indexOf(".");
20078 if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
20079 return {type: t, name: name};
20083 function onRemove(typename) {
20084 return function() {
20085 var on = this.__on;
20087 for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
20088 if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
20089 this.removeEventListener(o.type, o.listener, o.capture);
20094 if (++i) on.length = i;
20095 else delete this.__on;
20099 function onAdd(typename, value, capture) {
20100 var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
20101 return function(d, i, group) {
20102 var on = this.__on, o, listener = wrap(value, i, group);
20103 if (on) for (var j = 0, m = on.length; j < m; ++j) {
20104 if ((o = on[j]).type === typename.type && o.name === typename.name) {
20105 this.removeEventListener(o.type, o.listener, o.capture);
20106 this.addEventListener(o.type, o.listener = listener, o.capture = capture);
20111 this.addEventListener(typename.type, listener, capture);
20112 o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
20113 if (!on) this.__on = [o];
20118 var selection_on = function(typename, value, capture) {
20119 var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
20121 if (arguments.length < 2) {
20122 var on = this.node().__on;
20123 if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
20124 for (i = 0, o = on[j]; i < n; ++i) {
20125 if ((t = typenames[i]).type === o.type && t.name === o.name) {
20133 on = value ? onAdd : onRemove;
20134 if (capture == null) capture = false;
20135 for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
20139 function customEvent(event1, listener, that, args) {
20140 var event0 = event;
20141 event1.sourceEvent = event;
20144 return listener.apply(that, args);
20150 var sourceEvent = function() {
20151 var current = event, source;
20152 while (source = current.sourceEvent) current = source;
20156 var point = function(node, event) {
20157 var svg = node.ownerSVGElement || node;
20159 if (svg.createSVGPoint) {
20160 var point = svg.createSVGPoint();
20161 point.x = event.clientX, point.y = event.clientY;
20162 point = point.matrixTransform(node.getScreenCTM().inverse());
20163 return [point.x, point.y];
20166 var rect = node.getBoundingClientRect();
20167 return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
20170 var mouse = function(node) {
20171 var event = sourceEvent();
20172 if (event.changedTouches) event = event.changedTouches[0];
20173 return point(node, event);
20178 var selector = function(selector) {
20179 return selector == null ? none : function() {
20180 return this.querySelector(selector);
20184 var selection_select = function(select) {
20185 if (typeof select !== "function") select = selector(select);
20187 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
20188 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
20189 if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
20190 if ("__data__" in node) subnode.__data__ = node.__data__;
20191 subgroup[i] = subnode;
20196 return new Selection(subgroups, this._parents);
20199 function empty$1() {
20203 var selectorAll = function(selector) {
20204 return selector == null ? empty$1 : function() {
20205 return this.querySelectorAll(selector);
20209 var selection_selectAll = function(select) {
20210 if (typeof select !== "function") select = selectorAll(select);
20212 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
20213 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
20214 if (node = group[i]) {
20215 subgroups.push(select.call(node, node.__data__, i, group));
20216 parents.push(node);
20221 return new Selection(subgroups, parents);
20224 var selection_filter = function(match) {
20225 if (typeof match !== "function") match = matcher$1(match);
20227 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
20228 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
20229 if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
20230 subgroup.push(node);
20235 return new Selection(subgroups, this._parents);
20238 var sparse = function(update) {
20239 return new Array(update.length);
20242 var selection_enter = function() {
20243 return new Selection(this._enter || this._groups.map(sparse), this._parents);
20246 function EnterNode(parent, datum) {
20247 this.ownerDocument = parent.ownerDocument;
20248 this.namespaceURI = parent.namespaceURI;
20250 this._parent = parent;
20251 this.__data__ = datum;
20254 EnterNode.prototype = {
20255 constructor: EnterNode,
20256 appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
20257 insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
20258 querySelector: function(selector) { return this._parent.querySelector(selector); },
20259 querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
20262 var constant$1 = function(x) {
20263 return function() {
20268 var keyPrefix = "$"; // Protect against keys like “__proto__”.
20270 function bindIndex(parent, group, enter, update, exit, data) {
20273 groupLength = group.length,
20274 dataLength = data.length;
20276 // Put any non-null nodes that fit into update.
20277 // Put any null nodes into enter.
20278 // Put any remaining data into enter.
20279 for (; i < dataLength; ++i) {
20280 if (node = group[i]) {
20281 node.__data__ = data[i];
20284 enter[i] = new EnterNode(parent, data[i]);
20288 // Put any non-null nodes that don’t fit into exit.
20289 for (; i < groupLength; ++i) {
20290 if (node = group[i]) {
20296 function bindKey(parent, group, enter, update, exit, data, key) {
20299 nodeByKeyValue = {},
20300 groupLength = group.length,
20301 dataLength = data.length,
20302 keyValues = new Array(groupLength),
20305 // Compute the key for each node.
20306 // If multiple nodes have the same key, the duplicates are added to exit.
20307 for (i = 0; i < groupLength; ++i) {
20308 if (node = group[i]) {
20309 keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
20310 if (keyValue in nodeByKeyValue) {
20313 nodeByKeyValue[keyValue] = node;
20318 // Compute the key for each datum.
20319 // If there a node associated with this key, join and add it to update.
20320 // If there is not (or the key is a duplicate), add it to enter.
20321 for (i = 0; i < dataLength; ++i) {
20322 keyValue = keyPrefix + key.call(parent, data[i], i, data);
20323 if (node = nodeByKeyValue[keyValue]) {
20325 node.__data__ = data[i];
20326 nodeByKeyValue[keyValue] = null;
20328 enter[i] = new EnterNode(parent, data[i]);
20332 // Add any remaining nodes that were not bound to data to exit.
20333 for (i = 0; i < groupLength; ++i) {
20334 if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
20340 var selection_data = function(value, key) {
20342 data = new Array(this.size()), j = -1;
20343 this.each(function(d) { data[++j] = d; });
20347 var bind = key ? bindKey : bindIndex,
20348 parents = this._parents,
20349 groups = this._groups;
20351 if (typeof value !== "function") value = constant$1(value);
20353 for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
20354 var parent = parents[j],
20356 groupLength = group.length,
20357 data = value.call(parent, parent && parent.__data__, j, parents),
20358 dataLength = data.length,
20359 enterGroup = enter[j] = new Array(dataLength),
20360 updateGroup = update[j] = new Array(dataLength),
20361 exitGroup = exit[j] = new Array(groupLength);
20363 bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
20365 // Now connect the enter nodes to their following update node, such that
20366 // appendChild can insert the materialized enter node before this node,
20367 // rather than at the end of the parent node.
20368 for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
20369 if (previous = enterGroup[i0]) {
20370 if (i0 >= i1) i1 = i0 + 1;
20371 while (!(next = updateGroup[i1]) && ++i1 < dataLength);
20372 previous._next = next || null;
20377 update = new Selection(update, parents);
20378 update._enter = enter;
20379 update._exit = exit;
20383 var selection_exit = function() {
20384 return new Selection(this._exit || this._groups.map(sparse), this._parents);
20387 var selection_merge = function(selection) {
20389 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) {
20390 for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
20391 if (node = group0[i] || group1[i]) {
20397 for (; j < m0; ++j) {
20398 merges[j] = groups0[j];
20401 return new Selection(merges, this._parents);
20404 var selection_order = function() {
20406 for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
20407 for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
20408 if (node = group[i]) {
20409 if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
20418 var selection_sort = function(compare) {
20419 if (!compare) compare = ascending$1;
20421 function compareNode(a, b) {
20422 return a && b ? compare(a.__data__, b.__data__) : !a - !b;
20425 for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
20426 for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
20427 if (node = group[i]) {
20428 sortgroup[i] = node;
20431 sortgroup.sort(compareNode);
20434 return new Selection(sortgroups, this._parents).order();
20437 function ascending$1(a, b) {
20438 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
20441 var selection_call = function() {
20442 var callback = arguments[0];
20443 arguments[0] = this;
20444 callback.apply(null, arguments);
20448 var selection_nodes = function() {
20449 var nodes = new Array(this.size()), i = -1;
20450 this.each(function() { nodes[++i] = this; });
20454 var selection_node = function() {
20456 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
20457 for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
20458 var node = group[i];
20459 if (node) return node;
20466 var selection_size = function() {
20468 this.each(function() { ++size; });
20472 var selection_empty = function() {
20473 return !this.node();
20476 var selection_each = function(callback) {
20478 for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
20479 for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
20480 if (node = group[i]) callback.call(node, node.__data__, i, group);
20487 function attrRemove(name) {
20488 return function() {
20489 this.removeAttribute(name);
20493 function attrRemoveNS(fullname) {
20494 return function() {
20495 this.removeAttributeNS(fullname.space, fullname.local);
20499 function attrConstant(name, value) {
20500 return function() {
20501 this.setAttribute(name, value);
20505 function attrConstantNS(fullname, value) {
20506 return function() {
20507 this.setAttributeNS(fullname.space, fullname.local, value);
20511 function attrFunction(name, value) {
20512 return function() {
20513 var v = value.apply(this, arguments);
20514 if (v == null) this.removeAttribute(name);
20515 else this.setAttribute(name, v);
20519 function attrFunctionNS(fullname, value) {
20520 return function() {
20521 var v = value.apply(this, arguments);
20522 if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
20523 else this.setAttributeNS(fullname.space, fullname.local, v);
20527 var selection_attr = function(name, value) {
20528 var fullname = namespace(name);
20530 if (arguments.length < 2) {
20531 var node = this.node();
20532 return fullname.local
20533 ? node.getAttributeNS(fullname.space, fullname.local)
20534 : node.getAttribute(fullname);
20537 return this.each((value == null
20538 ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
20539 ? (fullname.local ? attrFunctionNS : attrFunction)
20540 : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
20543 var window$1 = function(node) {
20544 return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
20545 || (node.document && node) // node is a Window
20546 || node.defaultView; // node is a Document
20549 function styleRemove(name) {
20550 return function() {
20551 this.style.removeProperty(name);
20555 function styleConstant(name, value, priority) {
20556 return function() {
20557 this.style.setProperty(name, value, priority);
20561 function styleFunction(name, value, priority) {
20562 return function() {
20563 var v = value.apply(this, arguments);
20564 if (v == null) this.style.removeProperty(name);
20565 else this.style.setProperty(name, v, priority);
20569 var selection_style = function(name, value, priority) {
20571 return arguments.length > 1
20572 ? this.each((value == null
20573 ? styleRemove : typeof value === "function"
20575 : styleConstant)(name, value, priority == null ? "" : priority))
20576 : window$1(node = this.node())
20577 .getComputedStyle(node, null)
20578 .getPropertyValue(name);
20581 function propertyRemove(name) {
20582 return function() {
20587 function propertyConstant(name, value) {
20588 return function() {
20589 this[name] = value;
20593 function propertyFunction(name, value) {
20594 return function() {
20595 var v = value.apply(this, arguments);
20596 if (v == null) delete this[name];
20597 else this[name] = v;
20601 var selection_property = function(name, value) {
20602 return arguments.length > 1
20603 ? this.each((value == null
20604 ? propertyRemove : typeof value === "function"
20606 : propertyConstant)(name, value))
20607 : this.node()[name];
20610 function classArray(string) {
20611 return string.trim().split(/^|\s+/);
20614 function classList(node) {
20615 return node.classList || new ClassList(node);
20618 function ClassList(node) {
20620 this._names = classArray(node.getAttribute("class") || "");
20623 ClassList.prototype = {
20624 add: function(name) {
20625 var i = this._names.indexOf(name);
20627 this._names.push(name);
20628 this._node.setAttribute("class", this._names.join(" "));
20631 remove: function(name) {
20632 var i = this._names.indexOf(name);
20634 this._names.splice(i, 1);
20635 this._node.setAttribute("class", this._names.join(" "));
20638 contains: function(name) {
20639 return this._names.indexOf(name) >= 0;
20643 function classedAdd(node, names) {
20644 var list = classList(node), i = -1, n = names.length;
20645 while (++i < n) list.add(names[i]);
20648 function classedRemove(node, names) {
20649 var list = classList(node), i = -1, n = names.length;
20650 while (++i < n) list.remove(names[i]);
20653 function classedTrue(names) {
20654 return function() {
20655 classedAdd(this, names);
20659 function classedFalse(names) {
20660 return function() {
20661 classedRemove(this, names);
20665 function classedFunction(names, value) {
20666 return function() {
20667 (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
20671 var selection_classed = function(name, value) {
20672 var names = classArray(name + "");
20674 if (arguments.length < 2) {
20675 var list = classList(this.node()), i = -1, n = names.length;
20676 while (++i < n) if (!list.contains(names[i])) return false;
20680 return this.each((typeof value === "function"
20681 ? classedFunction : value
20683 : classedFalse)(names, value));
20686 function textRemove() {
20687 this.textContent = "";
20690 function textConstant(value) {
20691 return function() {
20692 this.textContent = value;
20696 function textFunction(value) {
20697 return function() {
20698 var v = value.apply(this, arguments);
20699 this.textContent = v == null ? "" : v;
20703 var selection_text = function(value) {
20704 return arguments.length
20705 ? this.each(value == null
20706 ? textRemove : (typeof value === "function"
20708 : textConstant)(value))
20709 : this.node().textContent;
20712 function htmlRemove() {
20713 this.innerHTML = "";
20716 function htmlConstant(value) {
20717 return function() {
20718 this.innerHTML = value;
20722 function htmlFunction(value) {
20723 return function() {
20724 var v = value.apply(this, arguments);
20725 this.innerHTML = v == null ? "" : v;
20729 var selection_html = function(value) {
20730 return arguments.length
20731 ? this.each(value == null
20732 ? htmlRemove : (typeof value === "function"
20734 : htmlConstant)(value))
20735 : this.node().innerHTML;
20739 if (this.nextSibling) this.parentNode.appendChild(this);
20742 var selection_raise = function() {
20743 return this.each(raise);
20747 if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
20750 var selection_lower = function() {
20751 return this.each(lower);
20754 var selection_append = function(name) {
20755 var create = typeof name === "function" ? name : creator(name);
20756 return this.select(function() {
20757 return this.appendChild(create.apply(this, arguments));
20761 function constantNull() {
20765 var selection_insert = function(name, before) {
20766 var create = typeof name === "function" ? name : creator(name),
20767 select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
20768 return this.select(function() {
20769 return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
20773 function remove() {
20774 var parent = this.parentNode;
20775 if (parent) parent.removeChild(this);
20778 var selection_remove = function() {
20779 return this.each(remove);
20782 var selection_datum = function(value) {
20783 return arguments.length
20784 ? this.property("__data__", value)
20785 : this.node().__data__;
20788 function dispatchEvent(node, type, params) {
20789 var window = window$1(node),
20790 event = window.CustomEvent;
20793 event = new event(type, params);
20795 event = window.document.createEvent("Event");
20796 if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
20797 else event.initEvent(type, false, false);
20800 node.dispatchEvent(event);
20803 function dispatchConstant(type, params) {
20804 return function() {
20805 return dispatchEvent(this, type, params);
20809 function dispatchFunction(type, params) {
20810 return function() {
20811 return dispatchEvent(this, type, params.apply(this, arguments));
20815 var selection_dispatch = function(type, params) {
20816 return this.each((typeof params === "function"
20818 : dispatchConstant)(type, params));
20823 function Selection(groups, parents) {
20824 this._groups = groups;
20825 this._parents = parents;
20828 function selection() {
20829 return new Selection([[document.documentElement]], root);
20832 Selection.prototype = selection.prototype = {
20833 constructor: Selection,
20834 select: selection_select,
20835 selectAll: selection_selectAll,
20836 filter: selection_filter,
20837 data: selection_data,
20838 enter: selection_enter,
20839 exit: selection_exit,
20840 merge: selection_merge,
20841 order: selection_order,
20842 sort: selection_sort,
20843 call: selection_call,
20844 nodes: selection_nodes,
20845 node: selection_node,
20846 size: selection_size,
20847 empty: selection_empty,
20848 each: selection_each,
20849 attr: selection_attr,
20850 style: selection_style,
20851 property: selection_property,
20852 classed: selection_classed,
20853 text: selection_text,
20854 html: selection_html,
20855 raise: selection_raise,
20856 lower: selection_lower,
20857 append: selection_append,
20858 insert: selection_insert,
20859 remove: selection_remove,
20860 datum: selection_datum,
20862 dispatch: selection_dispatch
20865 var select = function(selector) {
20866 return typeof selector === "string"
20867 ? new Selection([[document.querySelector(selector)]], [document.documentElement])
20868 : new Selection([[selector]], root);
20871 var selectAll = function(selector) {
20872 return typeof selector === "string"
20873 ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
20874 : new Selection([selector == null ? [] : selector], root);
20877 var touch = function(node, touches, identifier) {
20878 if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
20880 for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
20881 if ((touch = touches[i]).identifier === identifier) {
20882 return point(node, touch);
20889 var touches = function(node, touches) {
20890 if (touches == null) touches = sourceEvent().touches;
20892 for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
20893 points[i] = point(node, touches[i]);
20899 function nopropagation() {
20900 event.stopImmediatePropagation();
20903 var noevent = function() {
20904 event.preventDefault();
20905 event.stopImmediatePropagation();
20908 var dragDisable = function(view) {
20909 var root = view.document.documentElement,
20910 selection$$1 = select(view).on("dragstart.drag", noevent, true);
20911 if ("onselectstart" in root) {
20912 selection$$1.on("selectstart.drag", noevent, true);
20914 root.__noselect = root.style.MozUserSelect;
20915 root.style.MozUserSelect = "none";
20919 function yesdrag(view, noclick) {
20920 var root = view.document.documentElement,
20921 selection$$1 = select(view).on("dragstart.drag", null);
20923 selection$$1.on("click.drag", noevent, true);
20924 setTimeout(function() { selection$$1.on("click.drag", null); }, 0);
20926 if ("onselectstart" in root) {
20927 selection$$1.on("selectstart.drag", null);
20929 root.style.MozUserSelect = root.__noselect;
20930 delete root.__noselect;
20934 var constant$2 = function(x) {
20935 return function() {
20940 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
20941 this.target = target;
20943 this.subject = subject;
20944 this.identifier = id;
20945 this.active = active;
20953 DragEvent.prototype.on = function() {
20954 var value = this._.on.apply(this._, arguments);
20955 return value === this._ ? this : value;
20958 // Ignore right-click, since that should open the context menu.
20959 function defaultFilter$1() {
20960 return !event.button;
20963 function defaultContainer() {
20964 return this.parentNode;
20967 function defaultSubject(d) {
20968 return d == null ? {x: event.x, y: event.y} : d;
20971 var drag = function() {
20972 var filter = defaultFilter$1,
20973 container = defaultContainer,
20974 subject = defaultSubject,
20976 listeners = dispatch("start", "drag", "end"),
20981 function drag(selection$$1) {
20983 .on("mousedown.drag", mousedowned)
20984 .on("touchstart.drag", touchstarted)
20985 .on("touchmove.drag", touchmoved)
20986 .on("touchend.drag touchcancel.drag", touchended)
20987 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
20990 function mousedowned() {
20991 if (touchending || !filter.apply(this, arguments)) return;
20992 var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments);
20993 if (!gesture) return;
20994 select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
20995 dragDisable(event.view);
20997 mousemoving = false;
21001 function mousemoved() {
21003 mousemoving = true;
21004 gestures.mouse("drag");
21007 function mouseupped() {
21008 select(event.view).on("mousemove.drag mouseup.drag", null);
21009 yesdrag(event.view, mousemoving);
21011 gestures.mouse("end");
21014 function touchstarted() {
21015 if (!filter.apply(this, arguments)) return;
21016 var touches$$1 = event.changedTouches,
21017 c = container.apply(this, arguments),
21018 n = touches$$1.length, i, gesture;
21020 for (i = 0; i < n; ++i) {
21021 if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) {
21028 function touchmoved() {
21029 var touches$$1 = event.changedTouches,
21030 n = touches$$1.length, i, gesture;
21032 for (i = 0; i < n; ++i) {
21033 if (gesture = gestures[touches$$1[i].identifier]) {
21040 function touchended() {
21041 var touches$$1 = event.changedTouches,
21042 n = touches$$1.length, i, gesture;
21044 if (touchending) clearTimeout(touchending);
21045 touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
21046 for (i = 0; i < n; ++i) {
21047 if (gesture = gestures[touches$$1[i].identifier]) {
21054 function beforestart(id, container, point, that, args) {
21055 var p = point(container, id), s, dx, dy,
21056 sublisteners = listeners.copy();
21058 if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
21059 if ((event.subject = s = subject.apply(that, args)) == null) return false;
21060 dx = s.x - p[0] || 0;
21061 dy = s.y - p[1] || 0;
21065 return function gesture(type) {
21068 case "start": gestures[id] = gesture, n = active++; break;
21069 case "end": delete gestures[id], --active; // nobreak
21070 case "drag": p = point(container, id), n = active; break;
21072 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]);
21076 drag.filter = function(_) {
21077 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter;
21080 drag.container = function(_) {
21081 return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container;
21084 drag.subject = function(_) {
21085 return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject;
21088 drag.on = function() {
21089 var value = listeners.on.apply(listeners, arguments);
21090 return value === listeners ? drag : value;
21096 var define = function(constructor, factory, prototype) {
21097 constructor.prototype = factory.prototype = prototype;
21098 prototype.constructor = constructor;
21101 function extend(parent, definition) {
21102 var prototype = Object.create(parent.prototype);
21103 for (var key in definition) prototype[key] = definition[key];
21107 function Color() {}
21110 var brighter = 1 / darker;
21112 var reI = "\\s*([+-]?\\d+)\\s*";
21113 var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*";
21114 var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
21115 var reHex3 = /^#([0-9a-f]{3})$/;
21116 var reHex6 = /^#([0-9a-f]{6})$/;
21117 var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$");
21118 var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$");
21119 var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$");
21120 var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$");
21121 var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$");
21122 var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
21125 aliceblue: 0xf0f8ff,
21126 antiquewhite: 0xfaebd7,
21128 aquamarine: 0x7fffd4,
21133 blanchedalmond: 0xffebcd,
21135 blueviolet: 0x8a2be2,
21137 burlywood: 0xdeb887,
21138 cadetblue: 0x5f9ea0,
21139 chartreuse: 0x7fff00,
21140 chocolate: 0xd2691e,
21142 cornflowerblue: 0x6495ed,
21143 cornsilk: 0xfff8dc,
21146 darkblue: 0x00008b,
21147 darkcyan: 0x008b8b,
21148 darkgoldenrod: 0xb8860b,
21149 darkgray: 0xa9a9a9,
21150 darkgreen: 0x006400,
21151 darkgrey: 0xa9a9a9,
21152 darkkhaki: 0xbdb76b,
21153 darkmagenta: 0x8b008b,
21154 darkolivegreen: 0x556b2f,
21155 darkorange: 0xff8c00,
21156 darkorchid: 0x9932cc,
21158 darksalmon: 0xe9967a,
21159 darkseagreen: 0x8fbc8f,
21160 darkslateblue: 0x483d8b,
21161 darkslategray: 0x2f4f4f,
21162 darkslategrey: 0x2f4f4f,
21163 darkturquoise: 0x00ced1,
21164 darkviolet: 0x9400d3,
21165 deeppink: 0xff1493,
21166 deepskyblue: 0x00bfff,
21169 dodgerblue: 0x1e90ff,
21170 firebrick: 0xb22222,
21171 floralwhite: 0xfffaf0,
21172 forestgreen: 0x228b22,
21174 gainsboro: 0xdcdcdc,
21175 ghostwhite: 0xf8f8ff,
21177 goldenrod: 0xdaa520,
21180 greenyellow: 0xadff2f,
21182 honeydew: 0xf0fff0,
21184 indianred: 0xcd5c5c,
21188 lavender: 0xe6e6fa,
21189 lavenderblush: 0xfff0f5,
21190 lawngreen: 0x7cfc00,
21191 lemonchiffon: 0xfffacd,
21192 lightblue: 0xadd8e6,
21193 lightcoral: 0xf08080,
21194 lightcyan: 0xe0ffff,
21195 lightgoldenrodyellow: 0xfafad2,
21196 lightgray: 0xd3d3d3,
21197 lightgreen: 0x90ee90,
21198 lightgrey: 0xd3d3d3,
21199 lightpink: 0xffb6c1,
21200 lightsalmon: 0xffa07a,
21201 lightseagreen: 0x20b2aa,
21202 lightskyblue: 0x87cefa,
21203 lightslategray: 0x778899,
21204 lightslategrey: 0x778899,
21205 lightsteelblue: 0xb0c4de,
21206 lightyellow: 0xffffe0,
21208 limegreen: 0x32cd32,
21212 mediumaquamarine: 0x66cdaa,
21213 mediumblue: 0x0000cd,
21214 mediumorchid: 0xba55d3,
21215 mediumpurple: 0x9370db,
21216 mediumseagreen: 0x3cb371,
21217 mediumslateblue: 0x7b68ee,
21218 mediumspringgreen: 0x00fa9a,
21219 mediumturquoise: 0x48d1cc,
21220 mediumvioletred: 0xc71585,
21221 midnightblue: 0x191970,
21222 mintcream: 0xf5fffa,
21223 mistyrose: 0xffe4e1,
21224 moccasin: 0xffe4b5,
21225 navajowhite: 0xffdead,
21229 olivedrab: 0x6b8e23,
21231 orangered: 0xff4500,
21233 palegoldenrod: 0xeee8aa,
21234 palegreen: 0x98fb98,
21235 paleturquoise: 0xafeeee,
21236 palevioletred: 0xdb7093,
21237 papayawhip: 0xffefd5,
21238 peachpuff: 0xffdab9,
21242 powderblue: 0xb0e0e6,
21244 rebeccapurple: 0x663399,
21246 rosybrown: 0xbc8f8f,
21247 royalblue: 0x4169e1,
21248 saddlebrown: 0x8b4513,
21250 sandybrown: 0xf4a460,
21251 seagreen: 0x2e8b57,
21252 seashell: 0xfff5ee,
21256 slateblue: 0x6a5acd,
21257 slategray: 0x708090,
21258 slategrey: 0x708090,
21260 springgreen: 0x00ff7f,
21261 steelblue: 0x4682b4,
21266 turquoise: 0x40e0d0,
21270 whitesmoke: 0xf5f5f5,
21272 yellowgreen: 0x9acd32
21275 define(Color, color, {
21276 displayable: function() {
21277 return this.rgb().displayable();
21279 toString: function() {
21280 return this.rgb() + "";
21284 function color(format) {
21286 format = (format + "").trim().toLowerCase();
21287 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
21288 : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
21289 : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
21290 : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
21291 : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
21292 : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
21293 : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
21294 : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
21295 : named.hasOwnProperty(format) ? rgbn(named[format])
21296 : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
21301 return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
21304 function rgba(r, g, b, a) {
21305 if (a <= 0) r = g = b = NaN;
21306 return new Rgb(r, g, b, a);
21309 function rgbConvert(o) {
21310 if (!(o instanceof Color)) o = color(o);
21311 if (!o) return new Rgb;
21313 return new Rgb(o.r, o.g, o.b, o.opacity);
21316 function rgb(r, g, b, opacity) {
21317 return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
21320 function Rgb(r, g, b, opacity) {
21324 this.opacity = +opacity;
21327 define(Rgb, rgb, extend(Color, {
21328 brighter: function(k) {
21329 k = k == null ? brighter : Math.pow(brighter, k);
21330 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
21332 darker: function(k) {
21333 k = k == null ? darker : Math.pow(darker, k);
21334 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
21339 displayable: function() {
21340 return (0 <= this.r && this.r <= 255)
21341 && (0 <= this.g && this.g <= 255)
21342 && (0 <= this.b && this.b <= 255)
21343 && (0 <= this.opacity && this.opacity <= 1);
21345 toString: function() {
21346 var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
21347 return (a === 1 ? "rgb(" : "rgba(")
21348 + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
21349 + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
21350 + Math.max(0, Math.min(255, Math.round(this.b) || 0))
21351 + (a === 1 ? ")" : ", " + a + ")");
21355 function hsla(h, s, l, a) {
21356 if (a <= 0) h = s = l = NaN;
21357 else if (l <= 0 || l >= 1) h = s = NaN;
21358 else if (s <= 0) h = NaN;
21359 return new Hsl(h, s, l, a);
21362 function hslConvert(o) {
21363 if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
21364 if (!(o instanceof Color)) o = color(o);
21365 if (!o) return new Hsl;
21366 if (o instanceof Hsl) return o;
21371 min = Math.min(r, g, b),
21372 max = Math.max(r, g, b),
21375 l = (max + min) / 2;
21377 if (r === max) h = (g - b) / s + (g < b) * 6;
21378 else if (g === max) h = (b - r) / s + 2;
21379 else h = (r - g) / s + 4;
21380 s /= l < 0.5 ? max + min : 2 - max - min;
21383 s = l > 0 && l < 1 ? 0 : h;
21385 return new Hsl(h, s, l, o.opacity);
21388 function hsl(h, s, l, opacity) {
21389 return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
21392 function Hsl(h, s, l, opacity) {
21396 this.opacity = +opacity;
21399 define(Hsl, hsl, extend(Color, {
21400 brighter: function(k) {
21401 k = k == null ? brighter : Math.pow(brighter, k);
21402 return new Hsl(this.h, this.s, this.l * k, this.opacity);
21404 darker: function(k) {
21405 k = k == null ? darker : Math.pow(darker, k);
21406 return new Hsl(this.h, this.s, this.l * k, this.opacity);
21409 var h = this.h % 360 + (this.h < 0) * 360,
21410 s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
21412 m2 = l + (l < 0.5 ? l : 1 - l) * s,
21415 hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
21416 hsl2rgb(h, m1, m2),
21417 hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
21421 displayable: function() {
21422 return (0 <= this.s && this.s <= 1 || isNaN(this.s))
21423 && (0 <= this.l && this.l <= 1)
21424 && (0 <= this.opacity && this.opacity <= 1);
21428 /* From FvD 13.37, CSS Color Module Level 3 */
21429 function hsl2rgb(h, m1, m2) {
21430 return (h < 60 ? m1 + (m2 - m1) * h / 60
21432 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
21436 var deg2rad = Math.PI / 180;
21437 var rad2deg = 180 / Math.PI;
21445 var t2 = 3 * t1 * t1;
21446 var t3 = t1 * t1 * t1;
21448 function labConvert(o) {
21449 if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
21450 if (o instanceof Hcl) {
21451 var h = o.h * deg2rad;
21452 return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
21454 if (!(o instanceof Rgb)) o = rgbConvert(o);
21455 var b = rgb2xyz(o.r),
21458 x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
21459 y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
21460 z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
21461 return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
21464 function lab(l, a, b, opacity) {
21465 return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
21468 function Lab(l, a, b, opacity) {
21472 this.opacity = +opacity;
21475 define(Lab, lab, extend(Color, {
21476 brighter: function(k) {
21477 return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
21479 darker: function(k) {
21480 return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
21483 var y = (this.l + 16) / 116,
21484 x = isNaN(this.a) ? y : y + this.a / 500,
21485 z = isNaN(this.b) ? y : y - this.b / 200;
21486 y = Yn * lab2xyz(y);
21487 x = Xn * lab2xyz(x);
21488 z = Zn * lab2xyz(z);
21490 xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
21491 xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
21492 xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
21498 function xyz2lab(t) {
21499 return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
21502 function lab2xyz(t) {
21503 return t > t1 ? t * t * t : t2 * (t - t0);
21506 function xyz2rgb(x) {
21507 return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
21510 function rgb2xyz(x) {
21511 return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
21514 function hclConvert(o) {
21515 if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
21516 if (!(o instanceof Lab)) o = labConvert(o);
21517 var h = Math.atan2(o.b, o.a) * rad2deg;
21518 return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
21521 function hcl(h, c, l, opacity) {
21522 return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
21525 function Hcl(h, c, l, opacity) {
21529 this.opacity = +opacity;
21532 define(Hcl, hcl, extend(Color, {
21533 brighter: function(k) {
21534 return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
21536 darker: function(k) {
21537 return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
21540 return labConvert(this).rgb();
21551 var BC_DA = B * C - D * A;
21553 function cubehelixConvert(o) {
21554 if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
21555 if (!(o instanceof Rgb)) o = rgbConvert(o);
21559 l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
21561 k = (E * (g - l) - C * bl) / D,
21562 s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
21563 h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
21564 return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
21567 function cubehelix(h, s, l, opacity) {
21568 return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
21571 function Cubehelix(h, s, l, opacity) {
21575 this.opacity = +opacity;
21578 define(Cubehelix, cubehelix, extend(Color, {
21579 brighter: function(k) {
21580 k = k == null ? brighter : Math.pow(brighter, k);
21581 return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
21583 darker: function(k) {
21584 k = k == null ? darker : Math.pow(darker, k);
21585 return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
21588 var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
21590 a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
21591 cosh = Math.cos(h),
21592 sinh = Math.sin(h);
21594 255 * (l + a * (A * cosh + B * sinh)),
21595 255 * (l + a * (C * cosh + D * sinh)),
21596 255 * (l + a * (E * cosh)),
21602 function basis(t1, v0, v1, v2, v3) {
21603 var t2 = t1 * t1, t3 = t2 * t1;
21604 return ((1 - 3 * t1 + 3 * t2 - t3) * v0
21605 + (4 - 6 * t2 + 3 * t3) * v1
21606 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
21610 var constant$3 = function(x) {
21611 return function() {
21616 function linear(a, d) {
21617 return function(t) {
21622 function exponential(a, b, y) {
21623 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
21624 return Math.pow(a + t * b, y);
21628 function hue(a, b) {
21630 return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
21633 function gamma(y) {
21634 return (y = +y) === 1 ? nogamma : function(a, b) {
21635 return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);
21639 function nogamma(a, b) {
21641 return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);
21644 var interpolateRgb = ((function rgbGamma(y) {
21645 var color$$1 = gamma(y);
21647 function rgb$$1(start, end) {
21648 var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
21649 g = color$$1(start.g, end.g),
21650 b = color$$1(start.b, end.b),
21651 opacity = color$$1(start.opacity, end.opacity);
21652 return function(t) {
21656 start.opacity = opacity(t);
21661 rgb$$1.gamma = rgbGamma;
21666 var array$1 = function(a, b) {
21667 var nb = b ? b.length : 0,
21668 na = a ? Math.min(nb, a.length) : 0,
21673 for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]);
21674 for (; i < nb; ++i) c[i] = b[i];
21676 return function(t) {
21677 for (i = 0; i < na; ++i) c[i] = x[i](t);
21682 var date = function(a, b) {
21684 return a = +a, b -= a, function(t) {
21685 return d.setTime(a + b * t), d;
21689 var reinterpolate = function(a, b) {
21690 return a = +a, b -= a, function(t) {
21695 var object = function(a, b) {
21700 if (a === null || typeof a !== "object") a = {};
21701 if (b === null || typeof b !== "object") b = {};
21705 i[k] = interpolateValue(a[k], b[k]);
21711 return function(t) {
21712 for (k in i) c[k] = i[k](t);
21717 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
21718 var reB = new RegExp(reA.source, "g");
21721 return function() {
21727 return function(t) {
21732 var interpolateString = function(a, b) {
21733 var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
21734 am, // current match in a
21735 bm, // current match in b
21736 bs, // string preceding current number in b, if any
21737 i = -1, // index in s
21738 s = [], // string constants and placeholders
21739 q = []; // number interpolators
21741 // Coerce inputs to strings.
21742 a = a + "", b = b + "";
21744 // Interpolate pairs of numbers in a & b.
21745 while ((am = reA.exec(a))
21746 && (bm = reB.exec(b))) {
21747 if ((bs = bm.index) > bi) { // a string precedes the next number in b
21748 bs = b.slice(bi, bs);
21749 if (s[i]) s[i] += bs; // coalesce with previous string
21752 if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
21753 if (s[i]) s[i] += bm; // coalesce with previous string
21755 } else { // interpolate non-matching numbers
21757 q.push({i: i, x: reinterpolate(am, bm)});
21759 bi = reB.lastIndex;
21762 // Add remains of b.
21763 if (bi < b.length) {
21765 if (s[i]) s[i] += bs; // coalesce with previous string
21769 // Special optimization for only a single match.
21770 // Otherwise, interpolate each of the numbers and rejoin the string.
21771 return s.length < 2 ? (q[0]
21774 : (b = q.length, function(t) {
21775 for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
21780 var interpolateValue = function(a, b) {
21781 var t = typeof b, c;
21782 return b == null || t === "boolean" ? constant$3(b)
21783 : (t === "number" ? reinterpolate
21784 : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)
21785 : b instanceof color ? interpolateRgb
21786 : b instanceof Date ? date
21787 : Array.isArray(b) ? array$1
21788 : isNaN(b) ? object
21789 : reinterpolate)(a, b);
21792 var interpolateRound = function(a, b) {
21793 return a = +a, b -= a, function(t) {
21794 return Math.round(a + b * t);
21798 var degrees = 180 / Math.PI;
21809 var decompose = function(a, b, c, d, e, f) {
21810 var scaleX, scaleY, skewX;
21811 if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
21812 if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
21813 if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
21814 if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
21818 rotate: Math.atan2(b, a) * degrees,
21819 skewX: Math.atan(skewX) * degrees,
21830 function parseCss(value) {
21831 if (value === "none") return identity$2;
21832 if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
21833 cssNode.style.transform = value;
21834 value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
21835 cssRoot.removeChild(cssNode);
21836 value = value.slice(7, -1).split(",");
21837 return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
21840 function parseSvg(value) {
21841 if (value == null) return identity$2;
21842 if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
21843 svgNode.setAttribute("transform", value);
21844 if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
21845 value = value.matrix;
21846 return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
21849 function interpolateTransform(parse, pxComma, pxParen, degParen) {
21852 return s.length ? s.pop() + " " : "";
21855 function translate(xa, ya, xb, yb, s, q) {
21856 if (xa !== xb || ya !== yb) {
21857 var i = s.push("translate(", null, pxComma, null, pxParen);
21858 q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});
21859 } else if (xb || yb) {
21860 s.push("translate(" + xb + pxComma + yb + pxParen);
21864 function rotate(a, b, s, q) {
21866 if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
21867 q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: reinterpolate(a, b)});
21869 s.push(pop(s) + "rotate(" + b + degParen);
21873 function skewX(a, b, s, q) {
21875 q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: reinterpolate(a, b)});
21877 s.push(pop(s) + "skewX(" + b + degParen);
21881 function scale(xa, ya, xb, yb, s, q) {
21882 if (xa !== xb || ya !== yb) {
21883 var i = s.push(pop(s) + "scale(", null, ",", null, ")");
21884 q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});
21885 } else if (xb !== 1 || yb !== 1) {
21886 s.push(pop(s) + "scale(" + xb + "," + yb + ")");
21890 return function(a, b) {
21891 var s = [], // string constants and placeholders
21892 q = []; // number interpolators
21893 a = parse(a), b = parse(b);
21894 translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
21895 rotate(a.rotate, b.rotate, s, q);
21896 skewX(a.skewX, b.skewX, s, q);
21897 scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
21898 a = b = null; // gc
21899 return function(t) {
21900 var i = -1, n = q.length, o;
21901 while (++i < n) s[(o = q[i]).i] = o.x(t);
21907 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
21908 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
21910 // p0 = [ux0, uy0, w0]
21911 // p1 = [ux1, uy1, w1]
21913 function cubehelix$1(hue$$1) {
21914 return (function cubehelixGamma(y) {
21917 function cubehelix$$1(start, end) {
21918 var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
21919 s = nogamma(start.s, end.s),
21920 l = nogamma(start.l, end.l),
21921 opacity = nogamma(start.opacity, end.opacity);
21922 return function(t) {
21925 start.l = l(Math.pow(t, y));
21926 start.opacity = opacity(t);
21931 cubehelix$$1.gamma = cubehelixGamma;
21933 return cubehelix$$1;
21938 var cubehelixLong = cubehelix$1(nogamma);
21943 var pokeDelay = 1000;
21949 var clock = typeof performance === "object" && performance.now ? performance : Date;
21950 var setFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : function(f) { setTimeout(f, 17); };
21953 return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
21956 function clearNow() {
21966 Timer.prototype = timer.prototype = {
21967 constructor: Timer,
21968 restart: function(callback, delay, time) {
21969 if (typeof callback !== "function") throw new TypeError("callback is not a function");
21970 time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
21971 if (!this._next && taskTail !== this) {
21972 if (taskTail) taskTail._next = this;
21973 else taskHead = this;
21976 this._call = callback;
21983 this._time = Infinity;
21989 function timer(callback, delay, time) {
21991 t.restart(callback, delay, time);
21995 function timerFlush() {
21996 now(); // Get the current time, if not already set.
21997 ++frame; // Pretend we’ve set an alarm, if we haven’t already.
21998 var t = taskHead, e;
22000 if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
22007 clockNow = (clockLast = clock.now()) + clockSkew;
22008 frame = timeout = 0;
22019 var now = clock.now(), delay = now - clockLast;
22020 if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
22024 var t0, t1 = taskHead, t2, time = Infinity;
22027 if (time > t1._time) time = t1._time;
22028 t0 = t1, t1 = t1._next;
22030 t2 = t1._next, t1._next = null;
22031 t1 = t0 ? t0._next = t2 : taskHead = t2;
22038 function sleep(time) {
22039 if (frame) return; // Soonest alarm already set, or will be.
22040 if (timeout) timeout = clearTimeout(timeout);
22041 var delay = time - clockNow;
22043 if (time < Infinity) timeout = setTimeout(wake, delay);
22044 if (interval) interval = clearInterval(interval);
22046 if (!interval) interval = setInterval(poke, pokeDelay);
22047 frame = 1, setFrame(wake);
22051 var timeout$1 = function(callback, delay, time) {
22053 delay = delay == null ? 0 : +delay;
22054 t.restart(function(elapsed) {
22056 callback(elapsed + delay);
22061 var emptyOn = dispatch("start", "end", "interrupt");
22062 var emptyTween = [];
22072 var schedule = function(node, name, id, index, group, timing) {
22073 var schedules = node.__transition;
22074 if (!schedules) node.__transition = {};
22075 else if (id in schedules) return;
22078 index: index, // For context during callback.
22079 group: group, // For context during callback.
22083 delay: timing.delay,
22084 duration: timing.duration,
22091 function init(node, id) {
22092 var schedule = node.__transition;
22093 if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late");
22097 function set$1(node, id) {
22098 var schedule = node.__transition;
22099 if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late");
22103 function get$1(node, id) {
22104 var schedule = node.__transition;
22105 if (!schedule || !(schedule = schedule[id])) throw new Error("too late");
22109 function create(node, id, self) {
22110 var schedules = node.__transition,
22113 // Initialize the self timer when the transition is created.
22114 // Note the actual delay is not known until the first callback!
22115 schedules[id] = self;
22116 self.timer = timer(schedule, 0, self.time);
22118 function schedule(elapsed) {
22119 self.state = SCHEDULED;
22120 self.timer.restart(start, self.delay, self.time);
22122 // If the elapsed delay is less than our first sleep, start immediately.
22123 if (self.delay <= elapsed) start(elapsed - self.delay);
22126 function start(elapsed) {
22129 // If the state is not SCHEDULED, then we previously errored on start.
22130 if (self.state !== SCHEDULED) return stop();
22132 for (i in schedules) {
22134 if (o.name !== self.name) continue;
22136 // While this element already has a starting transition during this frame,
22137 // defer starting an interrupting transition until that transition has a
22138 // chance to tick (and possibly end); see d3/d3-transition#54!
22139 if (o.state === STARTED) return timeout$1(start);
22141 // Interrupt the active transition, if any.
22142 // Dispatch the interrupt event.
22143 if (o.state === RUNNING) {
22146 o.on.call("interrupt", node, node.__data__, o.index, o.group);
22147 delete schedules[i];
22150 // Cancel any pre-empted transitions. No interrupt event is dispatched
22151 // because the cancelled transitions never started. Note that this also
22152 // removes this transition from the pending list!
22153 else if (+i < id) {
22156 delete schedules[i];
22160 // Defer the first tick to end of the current frame; see d3/d3#1576.
22161 // Note the transition may be canceled after start and before the first tick!
22162 // Note this must be scheduled before the start event; see d3/d3-transition#16!
22163 // Assuming this is successful, subsequent callbacks go straight to tick.
22164 timeout$1(function() {
22165 if (self.state === STARTED) {
22166 self.state = RUNNING;
22167 self.timer.restart(tick, self.delay, self.time);
22172 // Dispatch the start event.
22173 // Note this must be done before the tween are initialized.
22174 self.state = STARTING;
22175 self.on.call("start", node, node.__data__, self.index, self.group);
22176 if (self.state !== STARTING) return; // interrupted
22177 self.state = STARTED;
22179 // Initialize the tween, deleting null tween.
22180 tween = new Array(n = self.tween.length);
22181 for (i = 0, j = -1; i < n; ++i) {
22182 if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
22186 tween.length = j + 1;
22189 function tick(elapsed) {
22190 var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
22195 tween[i].call(null, t);
22198 // Dispatch the end event.
22199 if (self.state === ENDING) {
22200 self.on.call("end", node, node.__data__, self.index, self.group);
22206 self.state = ENDED;
22208 delete schedules[id];
22209 for (var i in schedules) return; // eslint-disable-line no-unused-vars
22210 delete node.__transition;
22214 var interrupt = function(node, name) {
22215 var schedules = node.__transition,
22221 if (!schedules) return;
22223 name = name == null ? null : name + "";
22225 for (i in schedules) {
22226 if ((schedule = schedules[i]).name !== name) { empty = false; continue; }
22227 active = schedule.state > STARTING && schedule.state < ENDING;
22228 schedule.state = ENDED;
22229 schedule.timer.stop();
22230 if (active) schedule.on.call("interrupt", node, node.__data__, schedule.index, schedule.group);
22231 delete schedules[i];
22234 if (empty) delete node.__transition;
22237 var selection_interrupt = function(name) {
22238 return this.each(function() {
22239 interrupt(this, name);
22243 function tweenRemove(id, name) {
22244 var tween0, tween1;
22245 return function() {
22246 var schedule = set$1(this, id),
22247 tween = schedule.tween;
22249 // If this node shared tween with the previous node,
22250 // just assign the updated shared tween and we’re done!
22251 // Otherwise, copy-on-write.
22252 if (tween !== tween0) {
22253 tween1 = tween0 = tween;
22254 for (var i = 0, n = tween1.length; i < n; ++i) {
22255 if (tween1[i].name === name) {
22256 tween1 = tween1.slice();
22257 tween1.splice(i, 1);
22263 schedule.tween = tween1;
22267 function tweenFunction(id, name, value) {
22268 var tween0, tween1;
22269 if (typeof value !== "function") throw new Error;
22270 return function() {
22271 var schedule = set$1(this, id),
22272 tween = schedule.tween;
22274 // If this node shared tween with the previous node,
22275 // just assign the updated shared tween and we’re done!
22276 // Otherwise, copy-on-write.
22277 if (tween !== tween0) {
22278 tween1 = (tween0 = tween).slice();
22279 for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
22280 if (tween1[i].name === name) {
22285 if (i === n) tween1.push(t);
22288 schedule.tween = tween1;
22292 var transition_tween = function(name, value) {
22297 if (arguments.length < 2) {
22298 var tween = get$1(this.node(), id).tween;
22299 for (var i = 0, n = tween.length, t; i < n; ++i) {
22300 if ((t = tween[i]).name === name) {
22307 return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
22310 function tweenValue(transition, name, value) {
22311 var id = transition._id;
22313 transition.each(function() {
22314 var schedule = set$1(this, id);
22315 (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);
22318 return function(node) {
22319 return get$1(node, id).value[name];
22323 var interpolate$$1 = function(a, b) {
22325 return (typeof b === "number" ? reinterpolate
22326 : b instanceof color ? interpolateRgb
22327 : (c = color(b)) ? (b = c, interpolateRgb)
22328 : interpolateString)(a, b);
22331 function attrRemove$1(name) {
22332 return function() {
22333 this.removeAttribute(name);
22337 function attrRemoveNS$1(fullname) {
22338 return function() {
22339 this.removeAttributeNS(fullname.space, fullname.local);
22343 function attrConstant$1(name, interpolate$$1, value1) {
22346 return function() {
22347 var value0 = this.getAttribute(name);
22348 return value0 === value1 ? null
22349 : value0 === value00 ? interpolate0
22350 : interpolate0 = interpolate$$1(value00 = value0, value1);
22354 function attrConstantNS$1(fullname, interpolate$$1, value1) {
22357 return function() {
22358 var value0 = this.getAttributeNS(fullname.space, fullname.local);
22359 return value0 === value1 ? null
22360 : value0 === value00 ? interpolate0
22361 : interpolate0 = interpolate$$1(value00 = value0, value1);
22365 function attrFunction$1(name, interpolate$$1, value) {
22369 return function() {
22370 var value0, value1 = value(this);
22371 if (value1 == null) return void this.removeAttribute(name);
22372 value0 = this.getAttribute(name);
22373 return value0 === value1 ? null
22374 : value0 === value00 && value1 === value10 ? interpolate0
22375 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
22379 function attrFunctionNS$1(fullname, interpolate$$1, value) {
22383 return function() {
22384 var value0, value1 = value(this);
22385 if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
22386 value0 = this.getAttributeNS(fullname.space, fullname.local);
22387 return value0 === value1 ? null
22388 : value0 === value00 && value1 === value10 ? interpolate0
22389 : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
22393 var transition_attr = function(name, value) {
22394 var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate$$1;
22395 return this.attrTween(name, typeof value === "function"
22396 ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
22397 : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
22398 : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value));
22401 function attrTweenNS(fullname, value) {
22403 var node = this, i = value.apply(node, arguments);
22404 return i && function(t) {
22405 node.setAttributeNS(fullname.space, fullname.local, i(t));
22408 tween._value = value;
22412 function attrTween(name, value) {
22414 var node = this, i = value.apply(node, arguments);
22415 return i && function(t) {
22416 node.setAttribute(name, i(t));
22419 tween._value = value;
22423 var transition_attrTween = function(name, value) {
22424 var key = "attr." + name;
22425 if (arguments.length < 2) return (key = this.tween(key)) && key._value;
22426 if (value == null) return this.tween(key, null);
22427 if (typeof value !== "function") throw new Error;
22428 var fullname = namespace(name);
22429 return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
22432 function delayFunction(id, value) {
22433 return function() {
22434 init(this, id).delay = +value.apply(this, arguments);
22438 function delayConstant(id, value) {
22439 return value = +value, function() {
22440 init(this, id).delay = value;
22444 var transition_delay = function(value) {
22447 return arguments.length
22448 ? this.each((typeof value === "function"
22450 : delayConstant)(id, value))
22451 : get$1(this.node(), id).delay;
22454 function durationFunction(id, value) {
22455 return function() {
22456 set$1(this, id).duration = +value.apply(this, arguments);
22460 function durationConstant(id, value) {
22461 return value = +value, function() {
22462 set$1(this, id).duration = value;
22466 var transition_duration = function(value) {
22469 return arguments.length
22470 ? this.each((typeof value === "function"
22472 : durationConstant)(id, value))
22473 : get$1(this.node(), id).duration;
22476 function easeConstant(id, value) {
22477 if (typeof value !== "function") throw new Error;
22478 return function() {
22479 set$1(this, id).ease = value;
22483 var transition_ease = function(value) {
22486 return arguments.length
22487 ? this.each(easeConstant(id, value))
22488 : get$1(this.node(), id).ease;
22491 var transition_filter = function(match) {
22492 if (typeof match !== "function") match = matcher$1(match);
22494 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
22495 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
22496 if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
22497 subgroup.push(node);
22502 return new Transition(subgroups, this._parents, this._name, this._id);
22505 var transition_merge = function(transition) {
22506 if (transition._id !== this._id) throw new Error;
22508 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) {
22509 for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
22510 if (node = group0[i] || group1[i]) {
22516 for (; j < m0; ++j) {
22517 merges[j] = groups0[j];
22520 return new Transition(merges, this._parents, this._name, this._id);
22523 function start(name) {
22524 return (name + "").trim().split(/^|\s+/).every(function(t) {
22525 var i = t.indexOf(".");
22526 if (i >= 0) t = t.slice(0, i);
22527 return !t || t === "start";
22531 function onFunction(id, name, listener) {
22532 var on0, on1, sit = start(name) ? init : set$1;
22533 return function() {
22534 var schedule = sit(this, id),
22537 // If this node shared a dispatch with the previous node,
22538 // just assign the updated shared dispatch and we’re done!
22539 // Otherwise, copy-on-write.
22540 if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
22546 var transition_on = function(name, listener) {
22549 return arguments.length < 2
22550 ? get$1(this.node(), id).on.on(name)
22551 : this.each(onFunction(id, name, listener));
22554 function removeFunction(id) {
22555 return function() {
22556 var parent = this.parentNode;
22557 for (var i in this.__transition) if (+i !== id) return;
22558 if (parent) parent.removeChild(this);
22562 var transition_remove = function() {
22563 return this.on("end.remove", removeFunction(this._id));
22566 var transition_select = function(select$$1) {
22567 var name = this._name,
22570 if (typeof select$$1 !== "function") select$$1 = selector(select$$1);
22572 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
22573 for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
22574 if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) {
22575 if ("__data__" in node) subnode.__data__ = node.__data__;
22576 subgroup[i] = subnode;
22577 schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
22582 return new Transition(subgroups, this._parents, name, id);
22585 var transition_selectAll = function(select$$1) {
22586 var name = this._name,
22589 if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1);
22591 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
22592 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
22593 if (node = group[i]) {
22594 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) {
22595 if (child = children[k]) {
22596 schedule(child, name, id, k, children, inherit);
22599 subgroups.push(children);
22600 parents.push(node);
22605 return new Transition(subgroups, parents, name, id);
22608 var Selection$1 = selection.prototype.constructor;
22610 var transition_selection = function() {
22611 return new Selection$1(this._groups, this._parents);
22614 function styleRemove$1(name, interpolate$$2) {
22618 return function() {
22619 var style = window$1(this).getComputedStyle(this, null),
22620 value0 = style.getPropertyValue(name),
22621 value1 = (this.style.removeProperty(name), style.getPropertyValue(name));
22622 return value0 === value1 ? null
22623 : value0 === value00 && value1 === value10 ? interpolate0
22624 : interpolate0 = interpolate$$2(value00 = value0, value10 = value1);
22628 function styleRemoveEnd(name) {
22629 return function() {
22630 this.style.removeProperty(name);
22634 function styleConstant$1(name, interpolate$$2, value1) {
22637 return function() {
22638 var value0 = window$1(this).getComputedStyle(this, null).getPropertyValue(name);
22639 return value0 === value1 ? null
22640 : value0 === value00 ? interpolate0
22641 : interpolate0 = interpolate$$2(value00 = value0, value1);
22645 function styleFunction$1(name, interpolate$$2, value) {
22649 return function() {
22650 var style = window$1(this).getComputedStyle(this, null),
22651 value0 = style.getPropertyValue(name),
22652 value1 = value(this);
22653 if (value1 == null) value1 = (this.style.removeProperty(name), style.getPropertyValue(name));
22654 return value0 === value1 ? null
22655 : value0 === value00 && value1 === value10 ? interpolate0
22656 : interpolate0 = interpolate$$2(value00 = value0, value10 = value1);
22660 var transition_style = function(name, value, priority) {
22661 var i = (name += "") === "transform" ? interpolateTransformCss : interpolate$$1;
22662 return value == null ? this
22663 .styleTween(name, styleRemove$1(name, i))
22664 .on("end.style." + name, styleRemoveEnd(name))
22665 : this.styleTween(name, typeof value === "function"
22666 ? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
22667 : styleConstant$1(name, i, value), priority);
22670 function styleTween(name, value, priority) {
22672 var node = this, i = value.apply(node, arguments);
22673 return i && function(t) {
22674 node.style.setProperty(name, i(t), priority);
22677 tween._value = value;
22681 var transition_styleTween = function(name, value, priority) {
22682 var key = "style." + (name += "");
22683 if (arguments.length < 2) return (key = this.tween(key)) && key._value;
22684 if (value == null) return this.tween(key, null);
22685 if (typeof value !== "function") throw new Error;
22686 return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
22689 function textConstant$1(value) {
22690 return function() {
22691 this.textContent = value;
22695 function textFunction$1(value) {
22696 return function() {
22697 var value1 = value(this);
22698 this.textContent = value1 == null ? "" : value1;
22702 var transition_text = function(value) {
22703 return this.tween("text", typeof value === "function"
22704 ? textFunction$1(tweenValue(this, "text", value))
22705 : textConstant$1(value == null ? "" : value + ""));
22708 var transition_transition = function() {
22709 var name = this._name,
22713 for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
22714 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
22715 if (node = group[i]) {
22716 var inherit = get$1(node, id0);
22717 schedule(node, name, id1, i, group, {
22718 time: inherit.time + inherit.delay + inherit.duration,
22720 duration: inherit.duration,
22727 return new Transition(groups, this._parents, name, id1);
22732 function Transition(groups, parents, name, id) {
22733 this._groups = groups;
22734 this._parents = parents;
22739 function transition(name) {
22740 return selection().transition(name);
22747 var selection_prototype = selection.prototype;
22749 Transition.prototype = transition.prototype = {
22750 constructor: Transition,
22751 select: transition_select,
22752 selectAll: transition_selectAll,
22753 filter: transition_filter,
22754 merge: transition_merge,
22755 selection: transition_selection,
22756 transition: transition_transition,
22757 call: selection_prototype.call,
22758 nodes: selection_prototype.nodes,
22759 node: selection_prototype.node,
22760 size: selection_prototype.size,
22761 empty: selection_prototype.empty,
22762 each: selection_prototype.each,
22764 attr: transition_attr,
22765 attrTween: transition_attrTween,
22766 style: transition_style,
22767 styleTween: transition_styleTween,
22768 text: transition_text,
22769 remove: transition_remove,
22770 tween: transition_tween,
22771 delay: transition_delay,
22772 duration: transition_duration,
22773 ease: transition_ease
22776 function linear$1(t) {
22780 function quadIn(t) {
22784 function quadOut(t) {
22785 return t * (2 - t);
22788 function quadInOut(t) {
22789 return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
22792 function cubicIn(t) {
22796 function cubicOut(t) {
22797 return --t * t * t + 1;
22800 function cubicInOut(t) {
22801 return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
22806 var polyIn = (function custom(e) {
22809 function polyIn(t) {
22810 return Math.pow(t, e);
22813 polyIn.exponent = custom;
22818 var polyOut = (function custom(e) {
22821 function polyOut(t) {
22822 return 1 - Math.pow(1 - t, e);
22825 polyOut.exponent = custom;
22830 var polyInOut = (function custom(e) {
22833 function polyInOut(t) {
22834 return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
22837 polyInOut.exponent = custom;
22843 var halfPi = pi / 2;
22845 function sinIn(t) {
22846 return 1 - Math.cos(t * halfPi);
22849 function sinOut(t) {
22850 return Math.sin(t * halfPi);
22853 function sinInOut(t) {
22854 return (1 - Math.cos(pi * t)) / 2;
22857 function expIn(t) {
22858 return Math.pow(2, 10 * t - 10);
22861 function expOut(t) {
22862 return 1 - Math.pow(2, -10 * t);
22865 function expInOut(t) {
22866 return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
22869 function circleIn(t) {
22870 return 1 - Math.sqrt(1 - t * t);
22873 function circleOut(t) {
22874 return Math.sqrt(1 - --t * t);
22877 function circleInOut(t) {
22878 return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
22890 var b0 = 1 / b1 / b1;
22892 function bounceIn(t) {
22893 return 1 - bounceOut(1 - t);
22896 function bounceOut(t) {
22897 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;
22900 function bounceInOut(t) {
22901 return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
22904 var overshoot = 1.70158;
22906 var backIn = (function custom(s) {
22909 function backIn(t) {
22910 return t * t * ((s + 1) * t - s);
22913 backIn.overshoot = custom;
22918 var backOut = (function custom(s) {
22921 function backOut(t) {
22922 return --t * t * ((s + 1) * t + s) + 1;
22925 backOut.overshoot = custom;
22930 var backInOut = (function custom(s) {
22933 function backInOut(t) {
22934 return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
22937 backInOut.overshoot = custom;
22942 var tau = 2 * Math.PI;
22946 var elasticIn = (function custom(a, p) {
22947 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
22949 function elasticIn(t) {
22950 return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
22953 elasticIn.amplitude = function(a) { return custom(a, p * tau); };
22954 elasticIn.period = function(p) { return custom(a, p); };
22957 })(amplitude, period);
22959 var elasticOut = (function custom(a, p) {
22960 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
22962 function elasticOut(t) {
22963 return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
22966 elasticOut.amplitude = function(a) { return custom(a, p * tau); };
22967 elasticOut.period = function(p) { return custom(a, p); };
22970 })(amplitude, period);
22972 var elasticInOut = (function custom(a, p) {
22973 var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
22975 function elasticInOut(t) {
22976 return ((t = t * 2 - 1) < 0
22977 ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
22978 : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
22981 elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
22982 elasticInOut.period = function(p) { return custom(a, p); };
22984 return elasticInOut;
22985 })(amplitude, period);
22987 var defaultTiming = {
22988 time: null, // Set on use.
22994 function inherit(node, id) {
22996 while (!(timing = node.__transition) || !(timing = timing[id])) {
22997 if (!(node = node.parentNode)) {
22998 return defaultTiming.time = now(), defaultTiming;
23004 var selection_transition = function(name) {
23008 if (name instanceof Transition) {
23009 id = name._id, name = name._name;
23011 id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
23014 for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
23015 for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
23016 if (node = group[i]) {
23017 schedule(node, name, id, i, group, timing || inherit(node, id));
23022 return new Transition(groups, this._parents, name, id);
23025 selection.prototype.interrupt = selection_interrupt;
23026 selection.prototype.transition = selection_transition;
23028 var root$1 = [null];
23030 var active = function(node, name) {
23031 var schedules = node.__transition,
23036 name = name == null ? null : name + "";
23037 for (i in schedules) {
23038 if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {
23039 return new Transition([[node]], root$1, name, +i);
23047 var constant$4 = function(x) {
23048 return function() {
23053 var BrushEvent = function(target, type, selection) {
23054 this.target = target;
23056 this.selection = selection;
23059 function nopropagation$1() {
23060 event.stopImmediatePropagation();
23063 var noevent$1 = function() {
23064 event.preventDefault();
23065 event.stopImmediatePropagation();
23068 var MODE_DRAG = {name: "drag"};
23069 var MODE_SPACE = {name: "space"};
23070 var MODE_HANDLE = {name: "handle"};
23071 var MODE_CENTER = {name: "center"};
23075 handles: ["e", "w"].map(type$2),
23076 input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
23077 output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
23082 handles: ["n", "s"].map(type$2),
23083 input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
23084 output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
23089 handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type$2),
23090 input: function(xy) { return xy; },
23091 output: function(xy) { return xy; }
23095 overlay: "crosshair",
23151 function type$2(t) {
23155 // Ignore right-click, since that should open the context menu.
23156 function defaultFilter() {
23157 return !event.button;
23160 function defaultExtent() {
23161 var svg = this.ownerSVGElement || this;
23162 return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
23165 // Like d3.local, but with the name “__brush” rather than auto-generated.
23166 function local$$1(node) {
23167 while (!node.__brush) if (!(node = node.parentNode)) return;
23168 return node.__brush;
23171 function empty(extent) {
23172 return extent[0][0] === extent[1][0]
23173 || extent[0][1] === extent[1][1];
23176 function brushSelection(node) {
23177 var state = node.__brush;
23178 return state ? state.dim.output(state.selection) : null;
23181 function brushX() {
23185 function brushY() {
23189 var brush = function() {
23190 return brush$1(XY);
23193 function brush$1(dim) {
23194 var extent = defaultExtent,
23195 filter = defaultFilter,
23196 listeners = dispatch(brush, "start", "brush", "end"),
23200 function brush(group) {
23201 var overlay = group
23202 .property("__brush", initialize)
23203 .selectAll(".overlay")
23204 .data([type$2("overlay")]);
23206 overlay.enter().append("rect")
23207 .attr("class", "overlay")
23208 .attr("pointer-events", "all")
23209 .attr("cursor", cursors.overlay)
23212 var extent = local$$1(this).extent;
23214 .attr("x", extent[0][0])
23215 .attr("y", extent[0][1])
23216 .attr("width", extent[1][0] - extent[0][0])
23217 .attr("height", extent[1][1] - extent[0][1]);
23220 group.selectAll(".selection")
23221 .data([type$2("selection")])
23222 .enter().append("rect")
23223 .attr("class", "selection")
23224 .attr("cursor", cursors.selection)
23225 .attr("fill", "#777")
23226 .attr("fill-opacity", 0.3)
23227 .attr("stroke", "#fff")
23228 .attr("shape-rendering", "crispEdges");
23230 var handle = group.selectAll(".handle")
23231 .data(dim.handles, function(d) { return d.type; });
23233 handle.exit().remove();
23235 handle.enter().append("rect")
23236 .attr("class", function(d) { return "handle handle--" + d.type; })
23237 .attr("cursor", function(d) { return cursors[d.type]; });
23241 .attr("fill", "none")
23242 .attr("pointer-events", "all")
23243 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
23244 .on("mousedown.brush touchstart.brush", started);
23247 brush.move = function(group, selection$$1) {
23248 if (group.selection) {
23250 .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
23251 .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
23252 .tween("brush", function() {
23254 state = that.__brush,
23255 emit = emitter(that, arguments),
23256 selection0 = state.selection,
23257 selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(this, arguments) : selection$$1, state.extent),
23258 i = interpolateValue(selection0, selection1);
23260 function tween(t) {
23261 state.selection = t === 1 && empty(selection1) ? null : i(t);
23266 return selection0 && selection1 ? tween : tween(1);
23273 state = that.__brush,
23274 selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(that, args) : selection$$1, state.extent),
23275 emit = emitter(that, args).beforestart();
23278 state.selection = selection1 == null || empty(selection1) ? null : selection1;
23280 emit.start().brush().end();
23285 function redraw() {
23286 var group = select(this),
23287 selection$$1 = local$$1(this).selection;
23289 if (selection$$1) {
23290 group.selectAll(".selection")
23291 .style("display", null)
23292 .attr("x", selection$$1[0][0])
23293 .attr("y", selection$$1[0][1])
23294 .attr("width", selection$$1[1][0] - selection$$1[0][0])
23295 .attr("height", selection$$1[1][1] - selection$$1[0][1]);
23297 group.selectAll(".handle")
23298 .style("display", null)
23299 .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; })
23300 .attr("y", function(d) { return d.type[0] === "s" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; })
23301 .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; })
23302 .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; });
23306 group.selectAll(".selection,.handle")
23307 .style("display", "none")
23310 .attr("width", null)
23311 .attr("height", null);
23315 function emitter(that, args) {
23316 return that.__brush.emitter || new Emitter(that, args);
23319 function Emitter(that, args) {
23322 this.state = that.__brush;
23326 Emitter.prototype = {
23327 beforestart: function() {
23328 if (++this.active === 1) this.state.emitter = this, this.starting = true;
23331 start: function() {
23332 if (this.starting) this.starting = false, this.emit("start");
23335 brush: function() {
23336 this.emit("brush");
23340 if (--this.active === 0) delete this.state.emitter, this.emit("end");
23343 emit: function(type) {
23344 customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
23348 function started() {
23349 if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$1(); }
23350 else if (touchending) return;
23351 if (!filter.apply(this, arguments)) return;
23354 type = event.target.__data__.type,
23355 mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
23356 signX = dim === Y ? null : signsX[type],
23357 signY = dim === X ? null : signsY[type],
23358 state = local$$1(that),
23359 extent = state.extent,
23360 selection$$1 = state.selection,
23361 W = extent[0][0], w0, w1,
23362 N = extent[0][1], n0, n1,
23363 E = extent[1][0], e0, e1,
23364 S = extent[1][1], s0, s1,
23368 shifting = signX && signY && event.shiftKey,
23371 point0 = mouse(that),
23373 emit = emitter(that, arguments).beforestart();
23375 if (type === "overlay") {
23376 state.selection = selection$$1 = [
23377 [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
23378 [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
23381 w0 = selection$$1[0][0];
23382 n0 = selection$$1[0][1];
23383 e0 = selection$$1[1][0];
23384 s0 = selection$$1[1][1];
23392 var group = select(that)
23393 .attr("pointer-events", "none");
23395 var overlay = group.selectAll(".overlay")
23396 .attr("cursor", cursors[type]);
23398 if (event.touches) {
23400 .on("touchmove.brush", moved, true)
23401 .on("touchend.brush touchcancel.brush", ended, true);
23403 var view = select(event.view)
23404 .on("keydown.brush", keydowned, true)
23405 .on("keyup.brush", keyupped, true)
23406 .on("mousemove.brush", moved, true)
23407 .on("mouseup.brush", ended, true);
23409 dragDisable(event.view);
23418 var point1 = mouse(that);
23419 if (shifting && !lockX && !lockY) {
23420 if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
23432 dx = point[0] - point0[0];
23433 dy = point[1] - point0[1];
23438 if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
23439 if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
23442 case MODE_HANDLE: {
23443 if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
23444 else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
23445 if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
23446 else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
23449 case MODE_CENTER: {
23450 if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
23451 if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
23458 t = w0, w0 = e0, e0 = t;
23459 t = w1, w1 = e1, e1 = t;
23460 if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
23465 t = n0, n0 = s0, s0 = t;
23466 t = n1, n1 = s1, s1 = t;
23467 if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
23470 if (state.selection) selection$$1 = state.selection; // May be set by brush.move!
23471 if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0];
23472 if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1];
23474 if (selection$$1[0][0] !== w1
23475 || selection$$1[0][1] !== n1
23476 || selection$$1[1][0] !== e1
23477 || selection$$1[1][1] !== s1) {
23478 state.selection = [[w1, n1], [e1, s1]];
23486 if (event.touches) {
23487 if (event.touches.length) return;
23488 if (touchending) clearTimeout(touchending);
23489 touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
23490 group.on("touchmove.brush touchend.brush touchcancel.brush", null);
23492 yesdrag(event.view, moving);
23493 view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
23495 group.attr("pointer-events", "all");
23496 overlay.attr("cursor", cursors.overlay);
23497 if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)!
23498 if (empty(selection$$1)) state.selection = null, redraw.call(that);
23502 function keydowned() {
23503 switch (event.keyCode) {
23504 case 16: { // SHIFT
23505 shifting = signX && signY;
23509 if (mode === MODE_HANDLE) {
23510 if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
23511 if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
23512 mode = MODE_CENTER;
23517 case 32: { // SPACE; takes priority over ALT
23518 if (mode === MODE_HANDLE || mode === MODE_CENTER) {
23519 if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
23520 if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
23522 overlay.attr("cursor", cursors.selection);
23532 function keyupped() {
23533 switch (event.keyCode) {
23534 case 16: { // SHIFT
23536 lockX = lockY = shifting = false;
23542 if (mode === MODE_CENTER) {
23543 if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
23544 if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
23545 mode = MODE_HANDLE;
23550 case 32: { // SPACE
23551 if (mode === MODE_SPACE) {
23552 if (event.altKey) {
23553 if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
23554 if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
23555 mode = MODE_CENTER;
23557 if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
23558 if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
23559 mode = MODE_HANDLE;
23561 overlay.attr("cursor", cursors[type]);
23572 function initialize() {
23573 var state = this.__brush || {selection: null};
23574 state.extent = extent.apply(this, arguments);
23579 brush.extent = function(_) {
23580 return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
23583 brush.filter = function(_) {
23584 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter;
23587 brush.handleSize = function(_) {
23588 return arguments.length ? (handleSize = +_, brush) : handleSize;
23591 brush.on = function() {
23592 var value = listeners.on.apply(listeners, arguments);
23593 return value === listeners ? brush : value;
23599 var cos = Math.cos;
23600 var sin = Math.sin;
23601 var pi$1 = Math.PI;
23602 var halfPi$1 = pi$1 / 2;
23603 var tau$1 = pi$1 * 2;
23604 var max$1 = Math.max;
23606 function compareValue(compare) {
23607 return function(a, b) {
23609 a.source.value + a.target.value,
23610 b.source.value + b.target.value
23615 var chord = function() {
23618 sortSubgroups = null,
23621 function chord(matrix) {
23622 var n = matrix.length,
23624 groupIndex = sequence(n),
23625 subgroupIndex = [],
23627 groups = chords.groups = new Array(n),
23628 subgroups = new Array(n * n),
23636 // Compute the sum.
23637 k = 0, i = -1; while (++i < n) {
23638 x = 0, j = -1; while (++j < n) {
23642 subgroupIndex.push(sequence(n));
23647 if (sortGroups) groupIndex.sort(function(a, b) {
23648 return sortGroups(groupSums[a], groupSums[b]);
23652 if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
23653 d.sort(function(a, b) {
23654 return sortSubgroups(matrix[i][a], matrix[i][b]);
23658 // Convert the sum to scaling factor for [0, 2pi].
23659 // TODO Allow start and end angle to be specified?
23660 // TODO Allow padding to be specified as percentage?
23661 k = max$1(0, tau$1 - padAngle * n) / k;
23662 dx = k ? padAngle : tau$1 / n;
23664 // Compute the start and end angle for each group and subgroup.
23665 // Note: Opera has a bug reordering object literal properties!
23666 x = 0, i = -1; while (++i < n) {
23667 x0 = x, j = -1; while (++j < n) {
23668 var di = groupIndex[i],
23669 dj = subgroupIndex[di][j],
23670 v = matrix[di][dj],
23673 subgroups[dj * n + di] = {
23685 value: groupSums[di]
23690 // Generate chords for each (non-empty) subgroup-subgroup link.
23691 i = -1; while (++i < n) {
23692 j = i - 1; while (++j < n) {
23693 var source = subgroups[j * n + i],
23694 target = subgroups[i * n + j];
23695 if (source.value || target.value) {
23696 chords.push(source.value < target.value
23697 ? {source: target, target: source}
23698 : {source: source, target: target});
23703 return sortChords ? chords.sort(sortChords) : chords;
23706 chord.padAngle = function(_) {
23707 return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
23710 chord.sortGroups = function(_) {
23711 return arguments.length ? (sortGroups = _, chord) : sortGroups;
23714 chord.sortSubgroups = function(_) {
23715 return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
23718 chord.sortChords = function(_) {
23719 return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
23725 var slice$2 = Array.prototype.slice;
23727 var constant$5 = function(x) {
23728 return function() {
23733 var pi$2 = Math.PI;
23734 var tau$2 = 2 * pi$2;
23735 var epsilon$1 = 1e-6;
23736 var tauEpsilon = tau$2 - epsilon$1;
23739 this._x0 = this._y0 = // start of current subpath
23740 this._x1 = this._y1 = null; // end of current subpath
23748 Path.prototype = path.prototype = {
23750 moveTo: function(x, y) {
23751 this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
23753 closePath: function() {
23754 if (this._x1 !== null) {
23755 this._x1 = this._x0, this._y1 = this._y0;
23759 lineTo: function(x, y) {
23760 this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
23762 quadraticCurveTo: function(x1, y1, x, y) {
23763 this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
23765 bezierCurveTo: function(x1, y1, x2, y2, x, y) {
23766 this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
23768 arcTo: function(x1, y1, x2, y2, r) {
23769 x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
23776 l01_2 = x01 * x01 + y01 * y01;
23778 // Is the radius negative? Error.
23779 if (r < 0) throw new Error("negative radius: " + r);
23781 // Is this path empty? Move to (x1,y1).
23782 if (this._x1 === null) {
23783 this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
23786 // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
23787 else if (!(l01_2 > epsilon$1)) {}
23789 // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
23790 // Equivalently, is (x1,y1) coincident with (x2,y2)?
23791 // Or, is the radius zero? Line to (x1,y1).
23792 else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {
23793 this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
23796 // Otherwise, draw an arc!
23800 l21_2 = x21 * x21 + y21 * y21,
23801 l20_2 = x20 * x20 + y20 * y20,
23802 l21 = Math.sqrt(l21_2),
23803 l01 = Math.sqrt(l01_2),
23804 l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
23808 // If the start tangent is not coincident with (x0,y0), line to.
23809 if (Math.abs(t01 - 1) > epsilon$1) {
23810 this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
23813 this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
23816 arc: function(x, y, r, a0, a1, ccw) {
23817 x = +x, y = +y, r = +r;
23818 var dx = r * Math.cos(a0),
23819 dy = r * Math.sin(a0),
23823 da = ccw ? a0 - a1 : a1 - a0;
23825 // Is the radius negative? Error.
23826 if (r < 0) throw new Error("negative radius: " + r);
23828 // Is this path empty? Move to (x0,y0).
23829 if (this._x1 === null) {
23830 this._ += "M" + x0 + "," + y0;
23833 // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
23834 else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {
23835 this._ += "L" + x0 + "," + y0;
23838 // Is this arc empty? We’re done.
23841 // Is this a complete circle? Draw two arcs to complete the circle.
23842 if (da > tauEpsilon) {
23843 this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
23846 // Otherwise, draw an arc!
23848 if (da < 0) da = da % tau$2 + tau$2;
23849 this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
23852 rect: function(x, y, w, h) {
23853 this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
23855 toString: function() {
23860 function defaultSource(d) {
23864 function defaultTarget(d) {
23868 function defaultRadius(d) {
23872 function defaultStartAngle(d) {
23873 return d.startAngle;
23876 function defaultEndAngle(d) {
23880 var ribbon = function() {
23881 var source = defaultSource,
23882 target = defaultTarget,
23883 radius = defaultRadius,
23884 startAngle = defaultStartAngle,
23885 endAngle = defaultEndAngle,
23888 function ribbon() {
23890 argv = slice$2.call(arguments),
23891 s = source.apply(this, argv),
23892 t = target.apply(this, argv),
23893 sr = +radius.apply(this, (argv[0] = s, argv)),
23894 sa0 = startAngle.apply(this, argv) - halfPi$1,
23895 sa1 = endAngle.apply(this, argv) - halfPi$1,
23896 sx0 = sr * cos(sa0),
23897 sy0 = sr * sin(sa0),
23898 tr = +radius.apply(this, (argv[0] = t, argv)),
23899 ta0 = startAngle.apply(this, argv) - halfPi$1,
23900 ta1 = endAngle.apply(this, argv) - halfPi$1;
23902 if (!context) context = buffer = path();
23904 context.moveTo(sx0, sy0);
23905 context.arc(0, 0, sr, sa0, sa1);
23906 if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
23907 context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
23908 context.arc(0, 0, tr, ta0, ta1);
23910 context.quadraticCurveTo(0, 0, sx0, sy0);
23911 context.closePath();
23913 if (buffer) return context = null, buffer + "" || null;
23916 ribbon.radius = function(_) {
23917 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius;
23920 ribbon.startAngle = function(_) {
23921 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle;
23924 ribbon.endAngle = function(_) {
23925 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle;
23928 ribbon.source = function(_) {
23929 return arguments.length ? (source = _, ribbon) : source;
23932 ribbon.target = function(_) {
23933 return arguments.length ? (target = _, ribbon) : target;
23936 ribbon.context = function(_) {
23937 return arguments.length ? ((context = _ == null ? null : _), ribbon) : context;
23947 Map.prototype = map$1.prototype = {
23949 has: function(key) {
23950 return (prefix + key) in this;
23952 get: function(key) {
23953 return this[prefix + key];
23955 set: function(key, value) {
23956 this[prefix + key] = value;
23959 remove: function(key) {
23960 var property = prefix + key;
23961 return property in this && delete this[property];
23963 clear: function() {
23964 for (var property in this) if (property[0] === prefix) delete this[property];
23968 for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
23971 values: function() {
23973 for (var property in this) if (property[0] === prefix) values.push(this[property]);
23976 entries: function() {
23978 for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
23983 for (var property in this) if (property[0] === prefix) ++size;
23986 empty: function() {
23987 for (var property in this) if (property[0] === prefix) return false;
23990 each: function(f) {
23991 for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
23995 function map$1(object, f) {
23998 // Copy constructor.
23999 if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
24001 // Index array by numeric index or specified key function.
24002 else if (Array.isArray(object)) {
24007 if (f == null) while (++i < n) map.set(i, object[i]);
24008 else while (++i < n) map.set(f(o = object[i], i, object), o);
24011 // Convert object to map.
24012 else if (object) for (var key in object) map.set(key, object[key]);
24017 var nest = function() {
24024 function apply(array, depth, createResult, setResult) {
24025 if (depth >= keys.length) return rollup != null
24026 ? rollup(array) : (sortValues != null
24027 ? array.sort(sortValues)
24032 key = keys[depth++],
24035 valuesByKey = map$1(),
24037 result = createResult();
24040 if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
24041 values.push(value);
24043 valuesByKey.set(keyValue, [value]);
24047 valuesByKey.each(function(values, key) {
24048 setResult(result, key, apply(values, depth, createResult, setResult));
24054 function entries(map, depth) {
24055 if (++depth > keys.length) return map;
24056 var array, sortKey = sortKeys[depth - 1];
24057 if (rollup != null && depth >= keys.length) array = map.entries();
24058 else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
24059 return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
24063 object: function(array) { return apply(array, 0, createObject, setObject); },
24064 map: function(array) { return apply(array, 0, createMap, setMap); },
24065 entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
24066 key: function(d) { keys.push(d); return nest; },
24067 sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
24068 sortValues: function(order) { sortValues = order; return nest; },
24069 rollup: function(f) { rollup = f; return nest; }
24073 function createObject() {
24077 function setObject(object, key, value) {
24078 object[key] = value;
24081 function createMap() {
24085 function setMap(map, key, value) {
24086 map.set(key, value);
24091 var proto = map$1.prototype;
24093 Set.prototype = set$2.prototype = {
24096 add: function(value) {
24098 this[prefix + value] = value;
24101 remove: proto.remove,
24102 clear: proto.clear,
24103 values: proto.keys,
24105 empty: proto.empty,
24109 function set$2(object, f) {
24112 // Copy constructor.
24113 if (object instanceof Set) object.each(function(value) { set.add(value); });
24115 // Otherwise, assume it’s an array.
24117 var i = -1, n = object.length;
24118 if (f == null) while (++i < n) set.add(object[i]);
24119 else while (++i < n) set.add(f(object[i], i, object));
24125 var keys = function(map) {
24127 for (var key in map) keys.push(key);
24131 var values = function(map) {
24133 for (var key in map) values.push(map[key]);
24137 var entries = function(map) {
24139 for (var key in map) entries.push({key: key, value: map[key]});
24143 function objectConverter(columns) {
24144 return new Function("d", "return {" + columns.map(function(name, i) {
24145 return JSON.stringify(name) + ": d[" + i + "]";
24146 }).join(",") + "}");
24149 function customConverter(columns, f) {
24150 var object = objectConverter(columns);
24151 return function(row, i) {
24152 return f(object(row), i, columns);
24156 // Compute unique columns in order of discovery.
24157 function inferColumns(rows) {
24158 var columnSet = Object.create(null),
24161 rows.forEach(function(row) {
24162 for (var column in row) {
24163 if (!(column in columnSet)) {
24164 columns.push(columnSet[column] = column);
24172 var dsv = function(delimiter) {
24173 var reFormat = new RegExp("[\"" + delimiter + "\n]"),
24174 delimiterCode = delimiter.charCodeAt(0);
24176 function parse(text, f) {
24177 var convert, columns, rows = parseRows(text, function(row, i) {
24178 if (convert) return convert(row, i - 1);
24179 columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
24181 rows.columns = columns;
24185 function parseRows(text, f) {
24186 var EOL = {}, // sentinel value for end-of-line
24187 EOF = {}, // sentinel value for end-of-file
24188 rows = [], // output rows
24190 I = 0, // current character index
24191 n = 0, // the current line number
24192 t, // the current token
24193 eol; // is the current token followed by EOL?
24196 if (I >= N) return EOF; // special case: end of file
24197 if (eol) return eol = false, EOL; // special case: end of line
24199 // special case: quotes
24201 if (text.charCodeAt(j) === 34) {
24204 if (text.charCodeAt(i) === 34) {
24205 if (text.charCodeAt(i + 1) !== 34) break;
24210 c = text.charCodeAt(i + 1);
24213 if (text.charCodeAt(i + 2) === 10) ++I;
24214 } else if (c === 10) {
24217 return text.slice(j + 1, i).replace(/""/g, "\"");
24220 // common case: find next delimiter or newline
24223 c = text.charCodeAt(I++);
24224 if (c === 10) eol = true; // \n
24225 else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n
24226 else if (c !== delimiterCode) continue;
24227 return text.slice(j, I - k);
24230 // special case: last token before EOF
24231 return text.slice(j);
24234 while ((t = token()) !== EOF) {
24236 while (t !== EOL && t !== EOF) {
24240 if (f && (a = f(a, n++)) == null) continue;
24247 function format(rows, columns) {
24248 if (columns == null) columns = inferColumns(rows);
24249 return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
24250 return columns.map(function(column) {
24251 return formatValue(row[column]);
24252 }).join(delimiter);
24256 function formatRows(rows) {
24257 return rows.map(formatRow).join("\n");
24260 function formatRow(row) {
24261 return row.map(formatValue).join(delimiter);
24264 function formatValue(text) {
24265 return text == null ? ""
24266 : reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\""
24272 parseRows: parseRows,
24274 formatRows: formatRows
24278 var csv = dsv(",");
24280 var csvParse = csv.parse;
24281 var csvParseRows = csv.parseRows;
24282 var csvFormat = csv.format;
24283 var csvFormatRows = csv.formatRows;
24285 var tsv = dsv("\t");
24287 var tsvParse = tsv.parse;
24288 var tsvParseRows = tsv.parseRows;
24289 var tsvFormat = tsv.format;
24290 var tsvFormatRows = tsv.formatRows;
24292 var center$1 = function(x, y) {
24295 if (x == null) x = 0;
24296 if (y == null) y = 0;
24305 for (i = 0; i < n; ++i) {
24306 node = nodes[i], sx += node.x, sy += node.y;
24309 for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
24310 node = nodes[i], node.x -= sx, node.y -= sy;
24314 force.initialize = function(_) {
24318 force.x = function(_) {
24319 return arguments.length ? (x = +_, force) : x;
24322 force.y = function(_) {
24323 return arguments.length ? (y = +_, force) : y;
24329 var constant$6 = function(x) {
24330 return function() {
24335 var jiggle = function() {
24336 return (Math.random() - 0.5) * 1e-6;
24339 var tree_add = function(d) {
24340 var x = +this._x.call(null, d),
24341 y = +this._y.call(null, d);
24342 return add(this.cover(x, y), x, y, d);
24345 function add(tree, x, y, d) {
24346 if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
24364 // If the tree is empty, initialize the root as a leaf.
24365 if (!node) return tree._root = leaf, tree;
24367 // Find the existing leaf for the new point, or add it.
24368 while (node.length) {
24369 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
24370 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
24371 if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
24374 // Is the new point is exactly coincident with the existing point?
24375 xp = +tree._x.call(null, node.data);
24376 yp = +tree._y.call(null, node.data);
24377 if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
24379 // Otherwise, split the leaf node until the old and new point are separated.
24381 parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
24382 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
24383 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
24384 } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
24385 return parent[j] = node, parent[i] = leaf, tree;
24388 function addAll(data) {
24389 var d, i, n = data.length,
24399 // Compute the points and their extent.
24400 for (i = 0; i < n; ++i) {
24401 if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
24404 if (x < x0) x0 = x;
24405 if (x > x1) x1 = x;
24406 if (y < y0) y0 = y;
24407 if (y > y1) y1 = y;
24410 // If there were no (valid) points, inherit the existing extent.
24411 if (x1 < x0) x0 = this._x0, x1 = this._x1;
24412 if (y1 < y0) y0 = this._y0, y1 = this._y1;
24414 // Expand the tree to cover the new points.
24415 this.cover(x0, y0).cover(x1, y1);
24417 // Add the new points.
24418 for (i = 0; i < n; ++i) {
24419 add(this, xz[i], yz[i], data[i]);
24425 var tree_cover = function(x, y) {
24426 if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
24433 // If the quadtree has no extent, initialize them.
24434 // Integer extent are necessary so that if we later double the extent,
24435 // the existing quadrant boundaries don’t change due to floating point error!
24437 x1 = (x0 = Math.floor(x)) + 1;
24438 y1 = (y0 = Math.floor(y)) + 1;
24441 // Otherwise, double repeatedly to cover.
24442 else if (x0 > x || x > x1 || y0 > y || y > y1) {
24448 switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
24450 do parent = new Array(4), parent[i] = node, node = parent;
24451 while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
24455 do parent = new Array(4), parent[i] = node, node = parent;
24456 while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
24460 do parent = new Array(4), parent[i] = node, node = parent;
24461 while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
24465 do parent = new Array(4), parent[i] = node, node = parent;
24466 while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
24471 if (this._root && this._root.length) this._root = node;
24474 // If the quadtree covers the point already, just return.
24484 var tree_data = function() {
24486 this.visit(function(node) {
24487 if (!node.length) do data.push(node.data); while (node = node.next)
24492 var tree_extent = function(_) {
24493 return arguments.length
24494 ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
24495 : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
24498 var Quad = function(node, x0, y0, x1, y1) {
24506 var tree_find = function(x, y, radius) {
24521 if (node) quads.push(new Quad(node, x0, y0, x3, y3));
24522 if (radius == null) radius = Infinity;
24524 x0 = x - radius, y0 = y - radius;
24525 x3 = x + radius, y3 = y + radius;
24529 while (q = quads.pop()) {
24531 // Stop searching if this quadrant can’t contain a closer node.
24532 if (!(node = q.node)
24533 || (x1 = q.x0) > x3
24534 || (y1 = q.y0) > y3
24535 || (x2 = q.x1) < x0
24536 || (y2 = q.y1) < y0) continue;
24538 // Bisect the current quadrant.
24540 var xm = (x1 + x2) / 2,
24541 ym = (y1 + y2) / 2;
24544 new Quad(node[3], xm, ym, x2, y2),
24545 new Quad(node[2], x1, ym, xm, y2),
24546 new Quad(node[1], xm, y1, x2, ym),
24547 new Quad(node[0], x1, y1, xm, ym)
24550 // Visit the closest quadrant first.
24551 if (i = (y >= ym) << 1 | (x >= xm)) {
24552 q = quads[quads.length - 1];
24553 quads[quads.length - 1] = quads[quads.length - 1 - i];
24554 quads[quads.length - 1 - i] = q;
24558 // Visit this point. (Visiting coincident points isn’t necessary!)
24560 var dx = x - +this._x.call(null, node.data),
24561 dy = y - +this._y.call(null, node.data),
24562 d2 = dx * dx + dy * dy;
24564 var d = Math.sqrt(radius = d2);
24565 x0 = x - d, y0 = y - d;
24566 x3 = x + d, y3 = y + d;
24575 var tree_remove = function(d) {
24576 if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
24596 // If the tree is empty, initialize the root as a leaf.
24597 if (!node) return this;
24599 // Find the leaf node for the point.
24600 // While descending, also retain the deepest parent with a non-removed sibling.
24601 if (node.length) while (true) {
24602 if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
24603 if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
24604 if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
24605 if (!node.length) break;
24606 if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
24609 // Find the point to remove.
24610 while (node.data !== d) if (!(previous = node, node = node.next)) return this;
24611 if (next = node.next) delete node.next;
24613 // If there are multiple coincident points, remove just the point.
24614 if (previous) return (next ? previous.next = next : delete previous.next), this;
24616 // If this is the root point, remove it.
24617 if (!parent) return this._root = next, this;
24619 // Remove this leaf.
24620 next ? parent[i] = next : delete parent[i];
24622 // If the parent now contains exactly one leaf, collapse superfluous parents.
24623 if ((node = parent[0] || parent[1] || parent[2] || parent[3])
24624 && node === (parent[3] || parent[2] || parent[1] || parent[0])
24626 if (retainer) retainer[j] = node;
24627 else this._root = node;
24633 function removeAll(data) {
24634 for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
24638 var tree_root = function() {
24642 var tree_size = function() {
24644 this.visit(function(node) {
24645 if (!node.length) do ++size; while (node = node.next)
24650 var tree_visit = function(callback) {
24651 var quads = [], q, node = this._root, child, x0, y0, x1, y1;
24652 if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
24653 while (q = quads.pop()) {
24654 if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
24655 var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
24656 if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
24657 if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
24658 if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
24659 if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
24665 var tree_visitAfter = function(callback) {
24666 var quads = [], next = [], q;
24667 if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
24668 while (q = quads.pop()) {
24671 var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
24672 if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
24673 if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
24674 if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
24675 if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
24679 while (q = next.pop()) {
24680 callback(q.node, q.x0, q.y0, q.x1, q.y1);
24685 function defaultX(d) {
24689 var tree_x = function(_) {
24690 return arguments.length ? (this._x = _, this) : this._x;
24693 function defaultY(d) {
24697 var tree_y = function(_) {
24698 return arguments.length ? (this._y = _, this) : this._y;
24701 function quadtree(nodes, x, y) {
24702 var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
24703 return nodes == null ? tree : tree.addAll(nodes);
24706 function Quadtree(x, y, x0, y0, x1, y1) {
24713 this._root = undefined;
24716 function leaf_copy(leaf) {
24717 var copy = {data: leaf.data}, next = copy;
24718 while (leaf = leaf.next) next = next.next = {data: leaf.data};
24722 var treeProto = quadtree.prototype = Quadtree.prototype;
24724 treeProto.copy = function() {
24725 var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
24730 if (!node) return copy;
24732 if (!node.length) return copy._root = leaf_copy(node), copy;
24734 nodes = [{source: node, target: copy._root = new Array(4)}];
24735 while (node = nodes.pop()) {
24736 for (var i = 0; i < 4; ++i) {
24737 if (child = node.source[i]) {
24738 if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
24739 else node.target[i] = leaf_copy(child);
24747 treeProto.add = tree_add;
24748 treeProto.addAll = addAll;
24749 treeProto.cover = tree_cover;
24750 treeProto.data = tree_data;
24751 treeProto.extent = tree_extent;
24752 treeProto.find = tree_find;
24753 treeProto.remove = tree_remove;
24754 treeProto.removeAll = removeAll;
24755 treeProto.root = tree_root;
24756 treeProto.size = tree_size;
24757 treeProto.visit = tree_visit;
24758 treeProto.visitAfter = tree_visitAfter;
24759 treeProto.x = tree_x;
24760 treeProto.y = tree_y;
24770 var collide = function(radius) {
24776 if (typeof radius !== "function") radius = constant$6(radius == null ? 1 : +radius);
24779 var i, n = nodes.length,
24787 for (var k = 0; k < iterations; ++k) {
24788 tree = quadtree(nodes, x, y).visitAfter(prepare);
24789 for (i = 0; i < n; ++i) {
24791 ri = radii[node.index], ri2 = ri * ri;
24792 xi = node.x + node.vx;
24793 yi = node.y + node.vy;
24798 function apply(quad, x0, y0, x1, y1) {
24799 var data = quad.data, rj = quad.r, r = ri + rj;
24801 if (data.index > node.index) {
24802 var x = xi - data.x - data.vx,
24803 y = yi - data.y - data.vy,
24806 if (x === 0) x = jiggle(), l += x * x;
24807 if (y === 0) y = jiggle(), l += y * y;
24808 l = (r - (l = Math.sqrt(l))) / l * strength;
24809 node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
24810 node.vy += (y *= l) * r;
24811 data.vx -= x * (r = 1 - r);
24817 return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
24821 function prepare(quad) {
24822 if (quad.data) return quad.r = radii[quad.data.index];
24823 for (var i = quad.r = 0; i < 4; ++i) {
24824 if (quad[i] && quad[i].r > quad.r) {
24825 quad.r = quad[i].r;
24830 function initialize() {
24831 if (!nodes) return;
24832 var i, n = nodes.length, node;
24833 radii = new Array(n);
24834 for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
24837 force.initialize = function(_) {
24842 force.iterations = function(_) {
24843 return arguments.length ? (iterations = +_, force) : iterations;
24846 force.strength = function(_) {
24847 return arguments.length ? (strength = +_, force) : strength;
24850 force.radius = function(_) {
24851 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
24857 function index$3(d) {
24861 function find(nodeById, nodeId) {
24862 var node = nodeById.get(nodeId);
24863 if (!node) throw new Error("missing: " + nodeId);
24867 var link = function(links) {
24869 strength = defaultStrength,
24871 distance = constant$6(30),
24878 if (links == null) links = [];
24880 function defaultStrength(link) {
24881 return 1 / Math.min(count[link.source.index], count[link.target.index]);
24884 function force(alpha) {
24885 for (var k = 0, n = links.length; k < iterations; ++k) {
24886 for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
24887 link = links[i], source = link.source, target = link.target;
24888 x = target.x + target.vx - source.x - source.vx || jiggle();
24889 y = target.y + target.vy - source.y - source.vy || jiggle();
24890 l = Math.sqrt(x * x + y * y);
24891 l = (l - distances[i]) / l * alpha * strengths[i];
24893 target.vx -= x * (b = bias[i]);
24894 target.vy -= y * b;
24895 source.vx += x * (b = 1 - b);
24896 source.vy += y * b;
24901 function initialize() {
24902 if (!nodes) return;
24907 nodeById = map$1(nodes, id),
24910 for (i = 0, count = new Array(n); i < m; ++i) {
24911 link = links[i], link.index = i;
24912 if (typeof link.source !== "object") link.source = find(nodeById, link.source);
24913 if (typeof link.target !== "object") link.target = find(nodeById, link.target);
24914 count[link.source.index] = (count[link.source.index] || 0) + 1;
24915 count[link.target.index] = (count[link.target.index] || 0) + 1;
24918 for (i = 0, bias = new Array(m); i < m; ++i) {
24919 link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
24922 strengths = new Array(m), initializeStrength();
24923 distances = new Array(m), initializeDistance();
24926 function initializeStrength() {
24927 if (!nodes) return;
24929 for (var i = 0, n = links.length; i < n; ++i) {
24930 strengths[i] = +strength(links[i], i, links);
24934 function initializeDistance() {
24935 if (!nodes) return;
24937 for (var i = 0, n = links.length; i < n; ++i) {
24938 distances[i] = +distance(links[i], i, links);
24942 force.initialize = function(_) {
24947 force.links = function(_) {
24948 return arguments.length ? (links = _, initialize(), force) : links;
24951 force.id = function(_) {
24952 return arguments.length ? (id = _, force) : id;
24955 force.iterations = function(_) {
24956 return arguments.length ? (iterations = +_, force) : iterations;
24959 force.strength = function(_) {
24960 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initializeStrength(), force) : strength;
24963 force.distance = function(_) {
24964 return arguments.length ? (distance = typeof _ === "function" ? _ : constant$6(+_), initializeDistance(), force) : distance;
24978 var initialRadius = 10;
24979 var initialAngle = Math.PI * (3 - Math.sqrt(5));
24981 var simulation = function(nodes) {
24985 alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
24987 velocityDecay = 0.6,
24989 stepper = timer(step),
24990 event = dispatch("tick", "end");
24992 if (nodes == null) nodes = [];
24996 event.call("tick", simulation);
24997 if (alpha < alphaMin) {
24999 event.call("end", simulation);
25004 var i, n = nodes.length, node;
25006 alpha += (alphaTarget - alpha) * alphaDecay;
25008 forces.each(function(force) {
25012 for (i = 0; i < n; ++i) {
25014 if (node.fx == null) node.x += node.vx *= velocityDecay;
25015 else node.x = node.fx, node.vx = 0;
25016 if (node.fy == null) node.y += node.vy *= velocityDecay;
25017 else node.y = node.fy, node.vy = 0;
25021 function initializeNodes() {
25022 for (var i = 0, n = nodes.length, node; i < n; ++i) {
25023 node = nodes[i], node.index = i;
25024 if (isNaN(node.x) || isNaN(node.y)) {
25025 var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
25026 node.x = radius * Math.cos(angle);
25027 node.y = radius * Math.sin(angle);
25029 if (isNaN(node.vx) || isNaN(node.vy)) {
25030 node.vx = node.vy = 0;
25035 function initializeForce(force) {
25036 if (force.initialize) force.initialize(nodes);
25042 return simulation = {
25045 restart: function() {
25046 return stepper.restart(step), simulation;
25050 return stepper.stop(), simulation;
25053 nodes: function(_) {
25054 return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
25057 alpha: function(_) {
25058 return arguments.length ? (alpha = +_, simulation) : alpha;
25061 alphaMin: function(_) {
25062 return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
25065 alphaDecay: function(_) {
25066 return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
25069 alphaTarget: function(_) {
25070 return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
25073 velocityDecay: function(_) {
25074 return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
25077 force: function(name, _) {
25078 return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
25081 find: function(x, y, radius) {
25090 if (radius == null) radius = Infinity;
25091 else radius *= radius;
25093 for (i = 0; i < n; ++i) {
25097 d2 = dx * dx + dy * dy;
25098 if (d2 < radius) closest = node, radius = d2;
25104 on: function(name, _) {
25105 return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
25110 var manyBody = function() {
25114 strength = constant$6(-30),
25117 distanceMax2 = Infinity,
25120 function force(_) {
25121 var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);
25122 for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
25125 function initialize() {
25126 if (!nodes) return;
25127 var i, n = nodes.length, node;
25128 strengths = new Array(n);
25129 for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
25132 function accumulate(quad) {
25133 var strength = 0, q, c, x$$1, y$$1, i;
25135 // For internal nodes, accumulate forces from child quadrants.
25137 for (x$$1 = y$$1 = i = 0; i < 4; ++i) {
25138 if ((q = quad[i]) && (c = q.value)) {
25139 strength += c, x$$1 += c * q.x, y$$1 += c * q.y;
25142 quad.x = x$$1 / strength;
25143 quad.y = y$$1 / strength;
25146 // For leaf nodes, accumulate forces from coincident quadrants.
25151 do strength += strengths[q.data.index];
25152 while (q = q.next);
25155 quad.value = strength;
25158 function apply(quad, x1, _, x2) {
25159 if (!quad.value) return true;
25161 var x$$1 = quad.x - node.x,
25162 y$$1 = quad.y - node.y,
25164 l = x$$1 * x$$1 + y$$1 * y$$1;
25166 // Apply the Barnes-Hut approximation if possible.
25167 // Limit forces for very close nodes; randomize direction if coincident.
25168 if (w * w / theta2 < l) {
25169 if (l < distanceMax2) {
25170 if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
25171 if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
25172 if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
25173 node.vx += x$$1 * quad.value * alpha / l;
25174 node.vy += y$$1 * quad.value * alpha / l;
25179 // Otherwise, process points directly.
25180 else if (quad.length || l >= distanceMax2) return;
25182 // Limit forces for very close nodes; randomize direction if coincident.
25183 if (quad.data !== node || quad.next) {
25184 if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
25185 if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
25186 if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
25189 do if (quad.data !== node) {
25190 w = strengths[quad.data.index] * alpha / l;
25191 node.vx += x$$1 * w;
25192 node.vy += y$$1 * w;
25193 } while (quad = quad.next);
25196 force.initialize = function(_) {
25201 force.strength = function(_) {
25202 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
25205 force.distanceMin = function(_) {
25206 return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
25209 force.distanceMax = function(_) {
25210 return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
25213 force.theta = function(_) {
25214 return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
25220 var x$2 = function(x) {
25221 var strength = constant$6(0.1),
25226 if (typeof x !== "function") x = constant$6(x == null ? 0 : +x);
25228 function force(alpha) {
25229 for (var i = 0, n = nodes.length, node; i < n; ++i) {
25230 node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
25234 function initialize() {
25235 if (!nodes) return;
25236 var i, n = nodes.length;
25237 strengths = new Array(n);
25239 for (i = 0; i < n; ++i) {
25240 strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
25244 force.initialize = function(_) {
25249 force.strength = function(_) {
25250 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
25253 force.x = function(_) {
25254 return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : x;
25260 var y$2 = function(y) {
25261 var strength = constant$6(0.1),
25266 if (typeof y !== "function") y = constant$6(y == null ? 0 : +y);
25268 function force(alpha) {
25269 for (var i = 0, n = nodes.length, node; i < n; ++i) {
25270 node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
25274 function initialize() {
25275 if (!nodes) return;
25276 var i, n = nodes.length;
25277 strengths = new Array(n);
25279 for (i = 0; i < n; ++i) {
25280 strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
25284 force.initialize = function(_) {
25289 force.strength = function(_) {
25290 return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
25293 force.y = function(_) {
25294 return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : y;
25300 // Computes the decimal coefficient and exponent of the specified number x with
25301 // significant digits p, where x is positive and p is in [1, 21] or undefined.
25302 // For example, formatDecimal(1.23) returns ["123", 0].
25303 var formatDecimal = function(x, p) {
25304 if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
25305 var i, coefficient = x.slice(0, i);
25307 // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
25308 // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
25310 coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
25315 var exponent$1 = function(x) {
25316 return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
25319 var formatGroup = function(grouping, thousands) {
25320 return function(value, width) {
25321 var i = value.length,
25327 while (i > 0 && g > 0) {
25328 if (length + g + 1 > width) g = Math.max(1, width - length);
25329 t.push(value.substring(i -= g, i + g));
25330 if ((length += g + 1) > width) break;
25331 g = grouping[j = (j + 1) % grouping.length];
25334 return t.reverse().join(thousands);
25338 var formatDefault = function(x, p) {
25339 x = x.toPrecision(p);
25341 out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
25343 case ".": i0 = i1 = i; break;
25344 case "0": if (i0 === 0) i0 = i; i1 = i; break;
25345 case "e": break out;
25346 default: if (i0 > 0) i0 = 0; break;
25350 return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
25353 var prefixExponent;
25355 var formatPrefixAuto = function(x, p) {
25356 var d = formatDecimal(x, p);
25357 if (!d) return x + "";
25358 var coefficient = d[0],
25360 i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
25361 n = coefficient.length;
25362 return i === n ? coefficient
25363 : i > n ? coefficient + new Array(i - n + 1).join("0")
25364 : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
25365 : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
25368 var formatRounded = function(x, p) {
25369 var d = formatDecimal(x, p);
25370 if (!d) return x + "";
25371 var coefficient = d[0],
25373 return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
25374 : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
25375 : coefficient + new Array(exponent - coefficient.length + 2).join("0");
25378 var formatTypes = {
25380 "%": function(x, p) { return (x * 100).toFixed(p); },
25381 "b": function(x) { return Math.round(x).toString(2); },
25382 "c": function(x) { return x + ""; },
25383 "d": function(x) { return Math.round(x).toString(10); },
25384 "e": function(x, p) { return x.toExponential(p); },
25385 "f": function(x, p) { return x.toFixed(p); },
25386 "g": function(x, p) { return x.toPrecision(p); },
25387 "o": function(x) { return Math.round(x).toString(8); },
25388 "p": function(x, p) { return formatRounded(x * 100, p); },
25389 "r": formatRounded,
25390 "s": formatPrefixAuto,
25391 "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
25392 "x": function(x) { return Math.round(x).toString(16); }
25395 // [[fill]align][sign][symbol][0][width][,][.precision][type]
25396 var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
25398 var formatSpecifier = function(specifier) {
25399 return new FormatSpecifier(specifier);
25402 function FormatSpecifier(specifier) {
25403 if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
25406 fill = match[1] || " ",
25407 align = match[2] || ">",
25408 sign = match[3] || "-",
25409 symbol = match[4] || "",
25411 width = match[6] && +match[6],
25412 comma = !!match[7],
25413 precision = match[8] && +match[8].slice(1),
25414 type = match[9] || "";
25416 // The "n" type is an alias for ",g".
25417 if (type === "n") comma = true, type = "g";
25419 // Map invalid types to the default format.
25420 else if (!formatTypes[type]) type = "";
25422 // If zero fill is specified, padding goes after sign and before digits.
25423 if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
25426 this.align = align;
25428 this.symbol = symbol;
25430 this.width = width;
25431 this.comma = comma;
25432 this.precision = precision;
25436 FormatSpecifier.prototype.toString = function() {
25441 + (this.zero ? "0" : "")
25442 + (this.width == null ? "" : Math.max(1, this.width | 0))
25443 + (this.comma ? "," : "")
25444 + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
25448 var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
25450 function identity$3(x) {
25454 var formatLocale = function(locale) {
25455 var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
25456 currency = locale.currency,
25457 decimal = locale.decimal;
25459 function newFormat(specifier) {
25460 specifier = formatSpecifier(specifier);
25462 var fill = specifier.fill,
25463 align = specifier.align,
25464 sign = specifier.sign,
25465 symbol = specifier.symbol,
25466 zero = specifier.zero,
25467 width = specifier.width,
25468 comma = specifier.comma,
25469 precision = specifier.precision,
25470 type = specifier.type;
25472 // Compute the prefix and suffix.
25473 // For SI-prefix, the suffix is lazily computed.
25474 var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
25475 suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : "";
25477 // What format function should we use?
25478 // Is this an integer type?
25479 // Can this type generate exponential notation?
25480 var formatType = formatTypes[type],
25481 maybeSuffix = !type || /[defgprs%]/.test(type);
25483 // Set the default precision if not specified,
25484 // or clamp the specified precision to the supported range.
25485 // For significant precision, it must be in [1, 21].
25486 // For fixed precision, it must be in [0, 20].
25487 precision = precision == null ? (type ? 6 : 12)
25488 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
25489 : Math.max(0, Math.min(20, precision));
25491 function format(value) {
25492 var valuePrefix = prefix,
25493 valueSuffix = suffix,
25496 if (type === "c") {
25497 valueSuffix = formatType(value) + valueSuffix;
25502 // Convert negative to positive, and compute the prefix.
25503 // Note that -0 is not less than 0, but 1 / -0 is!
25504 var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true);
25506 // Perform the initial formatting.
25507 value = formatType(value, precision);
25509 // If the original value was negative, it may be rounded to zero during
25510 // formatting; treat this as (positive) zero.
25511 if (valueNegative) {
25512 i = -1, n = value.length;
25513 valueNegative = false;
25515 if (c = value.charCodeAt(i), (48 < c && c < 58)
25516 || (type === "x" && 96 < c && c < 103)
25517 || (type === "X" && 64 < c && c < 71)) {
25518 valueNegative = true;
25524 // Compute the prefix and suffix.
25525 valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
25526 valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
25528 // Break the formatted value into the integer “value” part that can be
25529 // grouped, and fractional or exponential “suffix” part that is not.
25531 i = -1, n = value.length;
25533 if (c = value.charCodeAt(i), 48 > c || c > 57) {
25534 valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
25535 value = value.slice(0, i);
25542 // If the fill character is not "0", grouping is applied before padding.
25543 if (comma && !zero) value = group(value, Infinity);
25545 // Compute the padding.
25546 var length = valuePrefix.length + value.length + valueSuffix.length,
25547 padding = length < width ? new Array(width - length + 1).join(fill) : "";
25549 // If the fill character is "0", grouping is applied after padding.
25550 if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
25552 // Reconstruct the final output based on the desired alignment.
25554 case "<": return valuePrefix + value + valueSuffix + padding;
25555 case "=": return valuePrefix + padding + value + valueSuffix;
25556 case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
25558 return padding + valuePrefix + value + valueSuffix;
25561 format.toString = function() {
25562 return specifier + "";
25568 function formatPrefix(specifier, value) {
25569 var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
25570 e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
25571 k = Math.pow(10, -e),
25572 prefix = prefixes[8 + e / 3];
25573 return function(value) {
25574 return f(k * value) + prefix;
25580 formatPrefix: formatPrefix
25592 currency: ["$", ""]
25595 function defaultLocale(definition) {
25596 locale$1 = formatLocale(definition);
25597 format = locale$1.format;
25598 formatPrefix = locale$1.formatPrefix;
25602 var precisionFixed = function(step) {
25603 return Math.max(0, -exponent$1(Math.abs(step)));
25606 var precisionPrefix = function(step, value) {
25607 return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
25610 var precisionRound = function(step, max) {
25611 step = Math.abs(step), max = Math.abs(max) - step;
25612 return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
25615 // Adds floating point numbers with twice the normal precision.
25616 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
25617 // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
25619 // Code adapted from GeographicLib by Charles F. F. Karney,
25620 // http://geographiclib.sourceforge.net/
25622 var adder = function() {
25630 Adder.prototype = {
25631 constructor: Adder,
25632 reset: function() {
25633 this.s = // rounded value
25634 this.t = 0; // exact error
25637 add$1(temp, y, this.t);
25638 add$1(this, temp.s, this.s);
25639 if (this.s) this.t += temp.t;
25640 else this.s = temp.t;
25642 valueOf: function() {
25647 var temp = new Adder;
25649 function add$1(adder, a, b) {
25650 var x = adder.s = a + b,
25653 adder.t = (a - av) + (b - bv);
25656 var epsilon$2 = 1e-6;
25657 var epsilon2$1 = 1e-12;
25658 var pi$3 = Math.PI;
25659 var halfPi$2 = pi$3 / 2;
25660 var quarterPi = pi$3 / 4;
25661 var tau$3 = pi$3 * 2;
25663 var degrees$1 = 180 / pi$3;
25664 var radians = pi$3 / 180;
25666 var abs = Math.abs;
25667 var atan = Math.atan;
25668 var atan2 = Math.atan2;
25669 var cos$1 = Math.cos;
25670 var ceil = Math.ceil;
25671 var exp = Math.exp;
25673 var log = Math.log;
25674 var pow = Math.pow;
25675 var sin$1 = Math.sin;
25676 var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
25677 var sqrt = Math.sqrt;
25678 var tan = Math.tan;
25681 return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);
25685 return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);
25688 function haversin(x) {
25689 return (x = sin$1(x / 2)) * x;
25692 function noop$1() {}
25694 function streamGeometry(geometry, stream) {
25695 if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
25696 streamGeometryType[geometry.type](geometry, stream);
25700 var streamObjectType = {
25701 Feature: function(feature, stream) {
25702 streamGeometry(feature.geometry, stream);
25704 FeatureCollection: function(object, stream) {
25705 var features = object.features, i = -1, n = features.length;
25706 while (++i < n) streamGeometry(features[i].geometry, stream);
25710 var streamGeometryType = {
25711 Sphere: function(object, stream) {
25714 Point: function(object, stream) {
25715 object = object.coordinates;
25716 stream.point(object[0], object[1], object[2]);
25718 MultiPoint: function(object, stream) {
25719 var coordinates = object.coordinates, i = -1, n = coordinates.length;
25720 while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
25722 LineString: function(object, stream) {
25723 streamLine(object.coordinates, stream, 0);
25725 MultiLineString: function(object, stream) {
25726 var coordinates = object.coordinates, i = -1, n = coordinates.length;
25727 while (++i < n) streamLine(coordinates[i], stream, 0);
25729 Polygon: function(object, stream) {
25730 streamPolygon(object.coordinates, stream);
25732 MultiPolygon: function(object, stream) {
25733 var coordinates = object.coordinates, i = -1, n = coordinates.length;
25734 while (++i < n) streamPolygon(coordinates[i], stream);
25736 GeometryCollection: function(object, stream) {
25737 var geometries = object.geometries, i = -1, n = geometries.length;
25738 while (++i < n) streamGeometry(geometries[i], stream);
25742 function streamLine(coordinates, stream, closed) {
25743 var i = -1, n = coordinates.length - closed, coordinate;
25744 stream.lineStart();
25745 while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
25749 function streamPolygon(coordinates, stream) {
25750 var i = -1, n = coordinates.length;
25751 stream.polygonStart();
25752 while (++i < n) streamLine(coordinates[i], stream, 1);
25753 stream.polygonEnd();
25756 var geoStream = function(object, stream) {
25757 if (object && streamObjectType.hasOwnProperty(object.type)) {
25758 streamObjectType[object.type](object, stream);
25760 streamGeometry(object, stream);
25764 var areaRingSum = adder();
25766 var areaSum = adder();
25777 polygonStart: function() {
25778 areaRingSum.reset();
25779 areaStream.lineStart = areaRingStart;
25780 areaStream.lineEnd = areaRingEnd;
25782 polygonEnd: function() {
25783 var areaRing = +areaRingSum;
25784 areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);
25785 this.lineStart = this.lineEnd = this.point = noop$1;
25787 sphere: function() {
25788 areaSum.add(tau$3);
25792 function areaRingStart() {
25793 areaStream.point = areaPointFirst;
25796 function areaRingEnd() {
25797 areaPoint(lambda00, phi00);
25800 function areaPointFirst(lambda, phi) {
25801 areaStream.point = areaPoint;
25802 lambda00 = lambda, phi00 = phi;
25803 lambda *= radians, phi *= radians;
25804 lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
25807 function areaPoint(lambda, phi) {
25808 lambda *= radians, phi *= radians;
25809 phi = phi / 2 + quarterPi; // half the angular distance from south pole
25811 // Spherical excess E for a spherical triangle with vertices: south pole,
25812 // previous point, current point. Uses a formula derived from Cagnoli’s
25813 // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
25814 var dLambda = lambda - lambda0,
25815 sdLambda = dLambda >= 0 ? 1 : -1,
25816 adLambda = sdLambda * dLambda,
25817 cosPhi = cos$1(phi),
25818 sinPhi = sin$1(phi),
25819 k = sinPhi0 * sinPhi,
25820 u = cosPhi0 * cosPhi + k * cos$1(adLambda),
25821 v = k * sdLambda * sin$1(adLambda);
25822 areaRingSum.add(atan2(v, u));
25824 // Advance the previous points.
25825 lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
25828 var area = function(object) {
25830 geoStream(object, areaStream);
25831 return areaSum * 2;
25834 function spherical(cartesian) {
25835 return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
25838 function cartesian(spherical) {
25839 var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
25840 return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
25843 function cartesianDot(a, b) {
25844 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
25847 function cartesianCross(a, b) {
25848 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]];
25852 function cartesianAddInPlace(a, b) {
25853 a[0] += b[0], a[1] += b[1], a[2] += b[2];
25856 function cartesianScale(vector, k) {
25857 return [vector[0] * k, vector[1] * k, vector[2] * k];
25861 function cartesianNormalizeInPlace(d) {
25862 var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
25863 d[0] /= l, d[1] /= l, d[2] /= l;
25874 var deltaSum = adder();
25878 var boundsStream = {
25879 point: boundsPoint,
25880 lineStart: boundsLineStart,
25881 lineEnd: boundsLineEnd,
25882 polygonStart: function() {
25883 boundsStream.point = boundsRingPoint;
25884 boundsStream.lineStart = boundsRingStart;
25885 boundsStream.lineEnd = boundsRingEnd;
25887 areaStream.polygonStart();
25889 polygonEnd: function() {
25890 areaStream.polygonEnd();
25891 boundsStream.point = boundsPoint;
25892 boundsStream.lineStart = boundsLineStart;
25893 boundsStream.lineEnd = boundsLineEnd;
25894 if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
25895 else if (deltaSum > epsilon$2) phi1 = 90;
25896 else if (deltaSum < -epsilon$2) phi0 = -90;
25897 range[0] = lambda0$1, range[1] = lambda1;
25901 function boundsPoint(lambda, phi) {
25902 ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
25903 if (phi < phi0) phi0 = phi;
25904 if (phi > phi1) phi1 = phi;
25907 function linePoint(lambda, phi) {
25908 var p = cartesian([lambda * radians, phi * radians]);
25910 var normal = cartesianCross(p0, p),
25911 equatorial = [normal[1], -normal[0], 0],
25912 inflection = cartesianCross(equatorial, normal);
25913 cartesianNormalizeInPlace(inflection);
25914 inflection = spherical(inflection);
25915 var delta = lambda - lambda2,
25916 sign$$1 = delta > 0 ? 1 : -1,
25917 lambdai = inflection[0] * degrees$1 * sign$$1,
25919 antimeridian = abs(delta) > 180;
25920 if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
25921 phii = inflection[1] * degrees$1;
25922 if (phii > phi1) phi1 = phii;
25923 } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
25924 phii = -inflection[1] * degrees$1;
25925 if (phii < phi0) phi0 = phii;
25927 if (phi < phi0) phi0 = phi;
25928 if (phi > phi1) phi1 = phi;
25930 if (antimeridian) {
25931 if (lambda < lambda2) {
25932 if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
25934 if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
25937 if (lambda1 >= lambda0$1) {
25938 if (lambda < lambda0$1) lambda0$1 = lambda;
25939 if (lambda > lambda1) lambda1 = lambda;
25941 if (lambda > lambda2) {
25942 if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
25944 if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
25949 boundsPoint(lambda, phi);
25951 p0 = p, lambda2 = lambda;
25954 function boundsLineStart() {
25955 boundsStream.point = linePoint;
25958 function boundsLineEnd() {
25959 range[0] = lambda0$1, range[1] = lambda1;
25960 boundsStream.point = boundsPoint;
25964 function boundsRingPoint(lambda, phi) {
25966 var delta = lambda - lambda2;
25967 deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
25969 lambda00$1 = lambda, phi00$1 = phi;
25971 areaStream.point(lambda, phi);
25972 linePoint(lambda, phi);
25975 function boundsRingStart() {
25976 areaStream.lineStart();
25979 function boundsRingEnd() {
25980 boundsRingPoint(lambda00$1, phi00$1);
25981 areaStream.lineEnd();
25982 if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);
25983 range[0] = lambda0$1, range[1] = lambda1;
25987 // Finds the left-right distance between two longitudes.
25988 // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
25989 // the distance between ±180° to be 360°.
25990 function angle(lambda0, lambda1) {
25991 return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
25994 function rangeCompare(a, b) {
25995 return a[0] - b[0];
25998 function rangeContains(range, x) {
25999 return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
26002 var bounds = function(feature) {
26003 var i, n, a, b, merged, deltaMax, delta;
26005 phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
26007 geoStream(feature, boundsStream);
26009 // First, sort ranges by their minimum longitudes.
26010 if (n = ranges.length) {
26011 ranges.sort(rangeCompare);
26013 // Then, merge any ranges that overlap.
26014 for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
26016 if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
26017 if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
26018 if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
26020 merged.push(a = b);
26024 // Finally, find the largest gap between the merged ranges.
26025 // The final bounding box will be the inverse of this gap.
26026 for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
26028 if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
26032 ranges = range = null;
26034 return lambda0$1 === Infinity || phi0 === Infinity
26035 ? [[NaN, NaN], [NaN, NaN]]
26036 : [[lambda0$1, phi0], [lambda1, phi1]];
26054 var z0; // previous point
26056 var centroidStream = {
26058 point: centroidPoint,
26059 lineStart: centroidLineStart,
26060 lineEnd: centroidLineEnd,
26061 polygonStart: function() {
26062 centroidStream.lineStart = centroidRingStart;
26063 centroidStream.lineEnd = centroidRingEnd;
26065 polygonEnd: function() {
26066 centroidStream.lineStart = centroidLineStart;
26067 centroidStream.lineEnd = centroidLineEnd;
26071 // Arithmetic mean of Cartesian vectors.
26072 function centroidPoint(lambda, phi) {
26073 lambda *= radians, phi *= radians;
26074 var cosPhi = cos$1(phi);
26075 centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
26078 function centroidPointCartesian(x, y, z) {
26080 X0 += (x - X0) / W0;
26081 Y0 += (y - Y0) / W0;
26082 Z0 += (z - Z0) / W0;
26085 function centroidLineStart() {
26086 centroidStream.point = centroidLinePointFirst;
26089 function centroidLinePointFirst(lambda, phi) {
26090 lambda *= radians, phi *= radians;
26091 var cosPhi = cos$1(phi);
26092 x0 = cosPhi * cos$1(lambda);
26093 y0 = cosPhi * sin$1(lambda);
26095 centroidStream.point = centroidLinePoint;
26096 centroidPointCartesian(x0, y0, z0);
26099 function centroidLinePoint(lambda, phi) {
26100 lambda *= radians, phi *= radians;
26101 var cosPhi = cos$1(phi),
26102 x = cosPhi * cos$1(lambda),
26103 y = cosPhi * sin$1(lambda),
26105 w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
26107 X1 += w * (x0 + (x0 = x));
26108 Y1 += w * (y0 + (y0 = y));
26109 Z1 += w * (z0 + (z0 = z));
26110 centroidPointCartesian(x0, y0, z0);
26113 function centroidLineEnd() {
26114 centroidStream.point = centroidPoint;
26117 // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
26118 // J. Applied Mechanics 42, 239 (1975).
26119 function centroidRingStart() {
26120 centroidStream.point = centroidRingPointFirst;
26123 function centroidRingEnd() {
26124 centroidRingPoint(lambda00$2, phi00$2);
26125 centroidStream.point = centroidPoint;
26128 function centroidRingPointFirst(lambda, phi) {
26129 lambda00$2 = lambda, phi00$2 = phi;
26130 lambda *= radians, phi *= radians;
26131 centroidStream.point = centroidRingPoint;
26132 var cosPhi = cos$1(phi);
26133 x0 = cosPhi * cos$1(lambda);
26134 y0 = cosPhi * sin$1(lambda);
26136 centroidPointCartesian(x0, y0, z0);
26139 function centroidRingPoint(lambda, phi) {
26140 lambda *= radians, phi *= radians;
26141 var cosPhi = cos$1(phi),
26142 x = cosPhi * cos$1(lambda),
26143 y = cosPhi * sin$1(lambda),
26145 cx = y0 * z - z0 * y,
26146 cy = z0 * x - x0 * z,
26147 cz = x0 * y - y0 * x,
26148 m = sqrt(cx * cx + cy * cy + cz * cz),
26149 u = x0 * x + y0 * y + z0 * z,
26150 v = m && -acos(u) / m, // area weight
26151 w = atan2(m, u); // line weight
26156 X1 += w * (x0 + (x0 = x));
26157 Y1 += w * (y0 + (y0 = y));
26158 Z1 += w * (z0 + (z0 = z));
26159 centroidPointCartesian(x0, y0, z0);
26162 var d3GeoCentroid = function(object) {
26167 geoStream(object, centroidStream);
26172 m = x * x + y * y + z * z;
26174 // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
26175 if (m < epsilon2$1) {
26176 x = X1, y = Y1, z = Z1;
26177 // If the feature has zero length, fall back to arithmetic mean of point vectors.
26178 if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;
26179 m = x * x + y * y + z * z;
26180 // If the feature still has an undefined ccentroid, then return.
26181 if (m < epsilon2$1) return [NaN, NaN];
26184 return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];
26187 var constant$7 = function(x) {
26188 return function() {
26193 var compose = function(a, b) {
26195 function compose(x, y) {
26196 return x = a(x, y), b(x[0], x[1]);
26199 if (a.invert && b.invert) compose.invert = function(x, y) {
26200 return x = b.invert(x, y), x && a.invert(x[0], x[1]);
26206 function rotationIdentity(lambda, phi) {
26207 return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
26210 rotationIdentity.invert = rotationIdentity;
26212 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
26213 return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
26214 : rotationLambda(deltaLambda))
26215 : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
26216 : rotationIdentity);
26219 function forwardRotationLambda(deltaLambda) {
26220 return function(lambda, phi) {
26221 return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
26225 function rotationLambda(deltaLambda) {
26226 var rotation = forwardRotationLambda(deltaLambda);
26227 rotation.invert = forwardRotationLambda(-deltaLambda);
26231 function rotationPhiGamma(deltaPhi, deltaGamma) {
26232 var cosDeltaPhi = cos$1(deltaPhi),
26233 sinDeltaPhi = sin$1(deltaPhi),
26234 cosDeltaGamma = cos$1(deltaGamma),
26235 sinDeltaGamma = sin$1(deltaGamma);
26237 function rotation(lambda, phi) {
26238 var cosPhi = cos$1(phi),
26239 x = cos$1(lambda) * cosPhi,
26240 y = sin$1(lambda) * cosPhi,
26242 k = z * cosDeltaPhi + x * sinDeltaPhi;
26244 atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
26245 asin(k * cosDeltaGamma + y * sinDeltaGamma)
26249 rotation.invert = function(lambda, phi) {
26250 var cosPhi = cos$1(phi),
26251 x = cos$1(lambda) * cosPhi,
26252 y = sin$1(lambda) * cosPhi,
26254 k = z * cosDeltaGamma - y * sinDeltaGamma;
26256 atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
26257 asin(k * cosDeltaPhi - x * sinDeltaPhi)
26264 var rotation = function(rotate) {
26265 rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
26267 function forward(coordinates) {
26268 coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
26269 return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
26272 forward.invert = function(coordinates) {
26273 coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
26274 return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
26280 // Generates a circle centered at [0°, 0°], with a given radius and precision.
26281 function circleStream(stream, radius, delta, direction, t0, t1) {
26282 if (!delta) return;
26283 var cosRadius = cos$1(radius),
26284 sinRadius = sin$1(radius),
26285 step = direction * delta;
26287 t0 = radius + direction * tau$3;
26288 t1 = radius - step / 2;
26290 t0 = circleRadius(cosRadius, t0);
26291 t1 = circleRadius(cosRadius, t1);
26292 if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;
26294 for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
26295 point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
26296 stream.point(point[0], point[1]);
26300 // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
26301 function circleRadius(cosRadius, point) {
26302 point = cartesian(point), point[0] -= cosRadius;
26303 cartesianNormalizeInPlace(point);
26304 var radius = acos(-point[1]);
26305 return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;
26308 var circle = function() {
26309 var center = constant$7([0, 0]),
26310 radius = constant$7(90),
26311 precision = constant$7(6),
26314 stream = {point: point};
26316 function point(x, y) {
26317 ring.push(x = rotate(x, y));
26318 x[0] *= degrees$1, x[1] *= degrees$1;
26321 function circle() {
26322 var c = center.apply(this, arguments),
26323 r = radius.apply(this, arguments) * radians,
26324 p = precision.apply(this, arguments) * radians;
26326 rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
26327 circleStream(stream, r, p, 1);
26328 c = {type: "Polygon", coordinates: [ring]};
26329 ring = rotate = null;
26333 circle.center = function(_) {
26334 return arguments.length ? (center = typeof _ === "function" ? _ : constant$7([+_[0], +_[1]]), circle) : center;
26337 circle.radius = function(_) {
26338 return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), circle) : radius;
26341 circle.precision = function(_) {
26342 return arguments.length ? (precision = typeof _ === "function" ? _ : constant$7(+_), circle) : precision;
26348 var clipBuffer = function() {
26352 point: function(x, y) {
26355 lineStart: function() {
26356 lines.push(line = []);
26359 rejoin: function() {
26360 if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
26362 result: function() {
26363 var result = lines;
26371 var clipLine = function(a, b, x0, y0, x1, y1) {
26383 if (!dx && r > 0) return;
26386 if (r < t0) return;
26387 if (r < t1) t1 = r;
26388 } else if (dx > 0) {
26389 if (r > t1) return;
26390 if (r > t0) t0 = r;
26394 if (!dx && r < 0) return;
26397 if (r > t1) return;
26398 if (r > t0) t0 = r;
26399 } else if (dx > 0) {
26400 if (r < t0) return;
26401 if (r < t1) t1 = r;
26405 if (!dy && r > 0) return;
26408 if (r < t0) return;
26409 if (r < t1) t1 = r;
26410 } else if (dy > 0) {
26411 if (r > t1) return;
26412 if (r > t0) t0 = r;
26416 if (!dy && r < 0) return;
26419 if (r > t1) return;
26420 if (r > t0) t0 = r;
26421 } else if (dy > 0) {
26422 if (r < t0) return;
26423 if (r < t1) t1 = r;
26426 if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
26427 if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
26431 var pointEqual = function(a, b) {
26432 return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;
26435 function Intersection(point, points, other, entry) {
26438 this.o = other; // another intersection
26439 this.e = entry; // is an entry?
26440 this.v = false; // visited
26441 this.n = this.p = null; // next & previous
26444 // A generalized polygon clipping algorithm: given a polygon that has been cut
26445 // into its visible line segments, and rejoins the segments by interpolating
26446 // along the clip edge.
26447 var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) {
26453 segments.forEach(function(segment) {
26454 if ((n = segment.length - 1) <= 0) return;
26455 var n, p0 = segment[0], p1 = segment[n], x;
26457 // If the first and last points of a segment are coincident, then treat as a
26458 // closed ring. TODO if all rings are closed, then the winding order of the
26459 // exterior ring should be checked.
26460 if (pointEqual(p0, p1)) {
26461 stream.lineStart();
26462 for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
26467 subject.push(x = new Intersection(p0, segment, null, true));
26468 clip.push(x.o = new Intersection(p0, null, x, false));
26469 subject.push(x = new Intersection(p1, segment, null, false));
26470 clip.push(x.o = new Intersection(p1, null, x, true));
26473 if (!subject.length) return;
26475 clip.sort(compareIntersection);
26479 for (i = 0, n = clip.length; i < n; ++i) {
26480 clip[i].e = startInside = !startInside;
26483 var start = subject[0],
26488 // Find first unvisited intersection.
26489 var current = start,
26491 while (current.v) if ((current = current.n) === start) return;
26492 points = current.z;
26493 stream.lineStart();
26495 current.v = current.o.v = true;
26498 for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
26500 interpolate(current.x, current.n.x, 1, stream);
26502 current = current.n;
26505 points = current.p.z;
26506 for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
26508 interpolate(current.x, current.p.x, -1, stream);
26510 current = current.p;
26512 current = current.o;
26513 points = current.z;
26514 isSubject = !isSubject;
26515 } while (!current.v);
26520 function link$1(array) {
26521 if (!(n = array.length)) return;
26527 a.n = b = array[i];
26531 a.n = b = array[0];
26536 var clipMin = -clipMax;
26538 // TODO Use d3-polygon’s polygonContains here for the ring check?
26539 // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
26541 function clipExtent(x0, y0, x1, y1) {
26543 function visible(x, y) {
26544 return x0 <= x && x <= x1 && y0 <= y && y <= y1;
26547 function interpolate(from, to, direction, stream) {
26550 || (a = corner(from, direction)) !== (a1 = corner(to, direction))
26551 || comparePoint(from, to) < 0 ^ direction > 0) {
26552 do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
26553 while ((a = (a + direction + 4) % 4) !== a1);
26555 stream.point(to[0], to[1]);
26559 function corner(p, direction) {
26560 return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3
26561 : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1
26562 : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0
26563 : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
26566 function compareIntersection(a, b) {
26567 return comparePoint(a.x, b.x);
26570 function comparePoint(a, b) {
26571 var ca = corner(a, 1),
26573 return ca !== cb ? ca - cb
26574 : ca === 0 ? b[1] - a[1]
26575 : ca === 1 ? a[0] - b[0]
26576 : ca === 2 ? a[1] - b[1]
26580 return function(stream) {
26581 var activeStream = stream,
26582 bufferStream = clipBuffer(),
26586 x__, y__, v__, // first point
26587 x_, y_, v_, // previous point
26593 lineStart: lineStart,
26595 polygonStart: polygonStart,
26596 polygonEnd: polygonEnd
26599 function point(x, y) {
26600 if (visible(x, y)) activeStream.point(x, y);
26603 function polygonInside() {
26606 for (var i = 0, n = polygon.length; i < n; ++i) {
26607 for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
26608 a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
26609 if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
26610 else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
26617 // Buffer geometry within a polygon and then clip it en masse.
26618 function polygonStart() {
26619 activeStream = bufferStream, segments = [], polygon = [], clean = true;
26622 function polygonEnd() {
26623 var startInside = polygonInside(),
26624 cleanInside = clean && startInside,
26625 visible = (segments = merge(segments)).length;
26626 if (cleanInside || visible) {
26627 stream.polygonStart();
26629 stream.lineStart();
26630 interpolate(null, null, 1, stream);
26634 clipPolygon(segments, compareIntersection, startInside, interpolate, stream);
26636 stream.polygonEnd();
26638 activeStream = stream, segments = polygon = ring = null;
26641 function lineStart() {
26642 clipStream.point = linePoint;
26643 if (polygon) polygon.push(ring = []);
26649 // TODO rather than special-case polygons, simply handle them separately.
26650 // Ideally, coincident intersection points should be jittered to avoid
26651 // clipping issues.
26652 function lineEnd() {
26654 linePoint(x__, y__);
26655 if (v__ && v_) bufferStream.rejoin();
26656 segments.push(bufferStream.result());
26658 clipStream.point = point;
26659 if (v_) activeStream.lineEnd();
26662 function linePoint(x, y) {
26663 var v = visible(x, y);
26664 if (polygon) ring.push([x, y]);
26666 x__ = x, y__ = y, v__ = v;
26669 activeStream.lineStart();
26670 activeStream.point(x, y);
26673 if (v && v_) activeStream.point(x, y);
26675 var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
26676 b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
26677 if (clipLine(a, b, x0, y0, x1, y1)) {
26679 activeStream.lineStart();
26680 activeStream.point(a[0], a[1]);
26682 activeStream.point(b[0], b[1]);
26683 if (!v) activeStream.lineEnd();
26686 activeStream.lineStart();
26687 activeStream.point(x, y);
26692 x_ = x, y_ = y, v_ = v;
26699 var extent$1 = function() {
26709 stream: function(stream) {
26710 return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream);
26712 extent: function(_) {
26713 return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
26718 var lengthSum = adder();
26723 var lengthStream = {
26726 lineStart: lengthLineStart,
26728 polygonStart: noop$1,
26732 function lengthLineStart() {
26733 lengthStream.point = lengthPointFirst;
26734 lengthStream.lineEnd = lengthLineEnd;
26737 function lengthLineEnd() {
26738 lengthStream.point = lengthStream.lineEnd = noop$1;
26741 function lengthPointFirst(lambda, phi) {
26742 lambda *= radians, phi *= radians;
26743 lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
26744 lengthStream.point = lengthPoint;
26747 function lengthPoint(lambda, phi) {
26748 lambda *= radians, phi *= radians;
26749 var sinPhi = sin$1(phi),
26750 cosPhi = cos$1(phi),
26751 delta = abs(lambda - lambda0$2),
26752 cosDelta = cos$1(delta),
26753 sinDelta = sin$1(delta),
26754 x = cosPhi * sinDelta,
26755 y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
26756 z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
26757 lengthSum.add(atan2(sqrt(x * x + y * y), z));
26758 lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
26761 var d3GeoLength = function(object) {
26763 geoStream(object, lengthStream);
26767 var coordinates = [null, null];
26768 var object$1 = {type: "LineString", coordinates: coordinates};
26770 var distance = function(a, b) {
26771 coordinates[0] = a;
26772 coordinates[1] = b;
26773 return d3GeoLength(object$1);
26776 function graticuleX(y0, y1, dy) {
26777 var y = sequence(y0, y1 - epsilon$2, dy).concat(y1);
26778 return function(x) { return y.map(function(y) { return [x, y]; }); };
26781 function graticuleY(x0, x1, dx) {
26782 var x = sequence(x0, x1 - epsilon$2, dx).concat(x1);
26783 return function(y) { return x.map(function(x) { return [x, y]; }); };
26786 function graticule() {
26787 var x1, x0, X1, X0,
26789 dx = 10, dy = dx, DX = 90, DY = 360,
26793 function graticule() {
26794 return {type: "MultiLineString", coordinates: lines()};
26798 return sequence(ceil(X0 / DX) * DX, X1, DX).map(X)
26799 .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
26800 .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))
26801 .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));
26804 graticule.lines = function() {
26805 return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
26808 graticule.outline = function() {
26814 X(X1).reverse().slice(1),
26815 Y(Y0).reverse().slice(1))
26820 graticule.extent = function(_) {
26821 if (!arguments.length) return graticule.extentMinor();
26822 return graticule.extentMajor(_).extentMinor(_);
26825 graticule.extentMajor = function(_) {
26826 if (!arguments.length) return [[X0, Y0], [X1, Y1]];
26827 X0 = +_[0][0], X1 = +_[1][0];
26828 Y0 = +_[0][1], Y1 = +_[1][1];
26829 if (X0 > X1) _ = X0, X0 = X1, X1 = _;
26830 if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
26831 return graticule.precision(precision);
26834 graticule.extentMinor = function(_) {
26835 if (!arguments.length) return [[x0, y0], [x1, y1]];
26836 x0 = +_[0][0], x1 = +_[1][0];
26837 y0 = +_[0][1], y1 = +_[1][1];
26838 if (x0 > x1) _ = x0, x0 = x1, x1 = _;
26839 if (y0 > y1) _ = y0, y0 = y1, y1 = _;
26840 return graticule.precision(precision);
26843 graticule.step = function(_) {
26844 if (!arguments.length) return graticule.stepMinor();
26845 return graticule.stepMajor(_).stepMinor(_);
26848 graticule.stepMajor = function(_) {
26849 if (!arguments.length) return [DX, DY];
26850 DX = +_[0], DY = +_[1];
26854 graticule.stepMinor = function(_) {
26855 if (!arguments.length) return [dx, dy];
26856 dx = +_[0], dy = +_[1];
26860 graticule.precision = function(_) {
26861 if (!arguments.length) return precision;
26863 x = graticuleX(y0, y1, 90);
26864 y = graticuleY(x0, x1, precision);
26865 X = graticuleX(Y0, Y1, 90);
26866 Y = graticuleY(X0, X1, precision);
26871 .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])
26872 .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);
26875 function graticule10() {
26876 return graticule()();
26879 var interpolate$1 = function(a, b) {
26880 var x0 = a[0] * radians,
26881 y0 = a[1] * radians,
26882 x1 = b[0] * radians,
26883 y1 = b[1] * radians,
26888 kx0 = cy0 * cos$1(x0),
26889 ky0 = cy0 * sin$1(x0),
26890 kx1 = cy1 * cos$1(x1),
26891 ky1 = cy1 * sin$1(x1),
26892 d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
26895 var interpolate = d ? function(t) {
26896 var B = sin$1(t *= d) / k,
26897 A = sin$1(d - t) / k,
26898 x = A * kx0 + B * kx1,
26899 y = A * ky0 + B * ky1,
26900 z = A * sy0 + B * sy1;
26902 atan2(y, x) * degrees$1,
26903 atan2(z, sqrt(x * x + y * y)) * degrees$1
26906 return [x0 * degrees$1, y0 * degrees$1];
26909 interpolate.distance = d;
26911 return interpolate;
26914 var identity$4 = function(x) {
26918 var areaSum$1 = adder();
26919 var areaRingSum$1 = adder();
26925 var areaStream$1 = {
26929 polygonStart: function() {
26930 areaStream$1.lineStart = areaRingStart$1;
26931 areaStream$1.lineEnd = areaRingEnd$1;
26933 polygonEnd: function() {
26934 areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;
26935 areaSum$1.add(abs(areaRingSum$1));
26936 areaRingSum$1.reset();
26938 result: function() {
26939 var area = areaSum$1 / 2;
26945 function areaRingStart$1() {
26946 areaStream$1.point = areaPointFirst$1;
26949 function areaPointFirst$1(x, y) {
26950 areaStream$1.point = areaPoint$1;
26951 x00 = x0$1 = x, y00 = y0$1 = y;
26954 function areaPoint$1(x, y) {
26955 areaRingSum$1.add(y0$1 * x - x0$1 * y);
26956 x0$1 = x, y0$1 = y;
26959 function areaRingEnd$1() {
26960 areaPoint$1(x00, y00);
26963 var x0$2 = Infinity;
26968 var boundsStream$1 = {
26969 point: boundsPoint$1,
26972 polygonStart: noop$1,
26973 polygonEnd: noop$1,
26974 result: function() {
26975 var bounds = [[x0$2, y0$2], [x1, y1]];
26976 x1 = y1 = -(y0$2 = x0$2 = Infinity);
26981 function boundsPoint$1(x, y) {
26982 if (x < x0$2) x0$2 = x;
26983 if (x > x1) x1 = x;
26984 if (y < y0$2) y0$2 = y;
26985 if (y > y1) y1 = y;
26988 // TODO Enforce positive area for exterior, negative area for interior?
27004 var centroidStream$1 = {
27005 point: centroidPoint$1,
27006 lineStart: centroidLineStart$1,
27007 lineEnd: centroidLineEnd$1,
27008 polygonStart: function() {
27009 centroidStream$1.lineStart = centroidRingStart$1;
27010 centroidStream$1.lineEnd = centroidRingEnd$1;
27012 polygonEnd: function() {
27013 centroidStream$1.point = centroidPoint$1;
27014 centroidStream$1.lineStart = centroidLineStart$1;
27015 centroidStream$1.lineEnd = centroidLineEnd$1;
27017 result: function() {
27018 var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
27019 : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
27020 : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
27022 X0$1 = Y0$1 = Z0$1 =
27023 X1$1 = Y1$1 = Z1$1 =
27024 X2$1 = Y2$1 = Z2$1 = 0;
27029 function centroidPoint$1(x, y) {
27035 function centroidLineStart$1() {
27036 centroidStream$1.point = centroidPointFirstLine;
27039 function centroidPointFirstLine(x, y) {
27040 centroidStream$1.point = centroidPointLine;
27041 centroidPoint$1(x0$3 = x, y0$3 = y);
27044 function centroidPointLine(x, y) {
27045 var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);
27046 X1$1 += z * (x0$3 + x) / 2;
27047 Y1$1 += z * (y0$3 + y) / 2;
27049 centroidPoint$1(x0$3 = x, y0$3 = y);
27052 function centroidLineEnd$1() {
27053 centroidStream$1.point = centroidPoint$1;
27056 function centroidRingStart$1() {
27057 centroidStream$1.point = centroidPointFirstRing;
27060 function centroidRingEnd$1() {
27061 centroidPointRing(x00$1, y00$1);
27064 function centroidPointFirstRing(x, y) {
27065 centroidStream$1.point = centroidPointRing;
27066 centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
27069 function centroidPointRing(x, y) {
27072 z = sqrt(dx * dx + dy * dy);
27074 X1$1 += z * (x0$3 + x) / 2;
27075 Y1$1 += z * (y0$3 + y) / 2;
27078 z = y0$3 * x - x0$3 * y;
27079 X2$1 += z * (x0$3 + x);
27080 Y2$1 += z * (y0$3 + y);
27082 centroidPoint$1(x0$3 = x, y0$3 = y);
27085 function PathContext(context) {
27086 this._context = context;
27089 PathContext.prototype = {
27091 pointRadius: function(_) {
27092 return this._radius = _, this;
27094 polygonStart: function() {
27097 polygonEnd: function() {
27100 lineStart: function() {
27103 lineEnd: function() {
27104 if (this._line === 0) this._context.closePath();
27107 point: function(x, y) {
27108 switch (this._point) {
27110 this._context.moveTo(x, y);
27115 this._context.lineTo(x, y);
27119 this._context.moveTo(x + this._radius, y);
27120 this._context.arc(x, y, this._radius, 0, tau$3);
27128 function PathString() {
27132 PathString.prototype = {
27133 _circle: circle$1(4.5),
27134 pointRadius: function(_) {
27135 return this._circle = circle$1(_), this;
27137 polygonStart: function() {
27140 polygonEnd: function() {
27143 lineStart: function() {
27146 lineEnd: function() {
27147 if (this._line === 0) this._string.push("Z");
27150 point: function(x, y) {
27151 switch (this._point) {
27153 this._string.push("M", x, ",", y);
27158 this._string.push("L", x, ",", y);
27162 this._string.push("M", x, ",", y, this._circle);
27167 result: function() {
27168 if (this._string.length) {
27169 var result = this._string.join("");
27176 function circle$1(radius) {
27177 return "m0," + radius
27178 + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
27179 + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
27183 var index$4 = function(projection, context) {
27184 var pointRadius = 4.5,
27188 function path(object) {
27190 if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
27191 geoStream(object, projectionStream(contextStream));
27193 return contextStream.result();
27196 path.area = function(object) {
27197 geoStream(object, projectionStream(areaStream$1));
27198 return areaStream$1.result();
27201 path.bounds = function(object) {
27202 geoStream(object, projectionStream(boundsStream$1));
27203 return boundsStream$1.result();
27206 path.centroid = function(object) {
27207 geoStream(object, projectionStream(centroidStream$1));
27208 return centroidStream$1.result();
27211 path.projection = function(_) {
27212 return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;
27215 path.context = function(_) {
27216 if (!arguments.length) return context;
27217 contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
27218 if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
27222 path.pointRadius = function(_) {
27223 if (!arguments.length) return pointRadius;
27224 pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
27228 return path.projection(projection).context(context);
27231 var sum$1 = adder();
27233 var polygonContains = function(polygon, point) {
27234 var lambda = point[0],
27236 normal = [sin$1(lambda), -cos$1(lambda), 0],
27242 for (var i = 0, n = polygon.length; i < n; ++i) {
27243 if (!(m = (ring = polygon[i]).length)) continue;
27246 point0 = ring[m - 1],
27247 lambda0 = point0[0],
27248 phi0 = point0[1] / 2 + quarterPi,
27249 sinPhi0 = sin$1(phi0),
27250 cosPhi0 = cos$1(phi0);
27252 for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
27253 var point1 = ring[j],
27254 lambda1 = point1[0],
27255 phi1 = point1[1] / 2 + quarterPi,
27256 sinPhi1 = sin$1(phi1),
27257 cosPhi1 = cos$1(phi1),
27258 delta = lambda1 - lambda0,
27259 sign$$1 = delta >= 0 ? 1 : -1,
27260 absDelta = sign$$1 * delta,
27261 antimeridian = absDelta > pi$3,
27262 k = sinPhi0 * sinPhi1;
27264 sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
27265 angle += antimeridian ? delta + sign$$1 * tau$3 : delta;
27267 // Are the longitudes either side of the point’s meridian (lambda),
27268 // and are the latitudes smaller than the parallel (phi)?
27269 if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
27270 var arc = cartesianCross(cartesian(point0), cartesian(point1));
27271 cartesianNormalizeInPlace(arc);
27272 var intersection = cartesianCross(normal, arc);
27273 cartesianNormalizeInPlace(intersection);
27274 var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
27275 if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
27276 winding += antimeridian ^ delta >= 0 ? 1 : -1;
27282 // First, determine whether the South pole is inside or outside:
27284 // It is inside if:
27285 // * the polygon winds around it in a clockwise direction.
27286 // * the polygon does not (cumulatively) wind around it, but has a negative
27287 // (counter-clockwise) area.
27289 // Second, count the (signed) number of times a segment crosses a lambda
27290 // from the point to the South pole. If it is zero, then the point is the
27291 // same side as the South pole.
27293 return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);
27296 var clip = function(pointVisible, clipLine, interpolate, start) {
27297 return function(rotate, sink) {
27298 var line = clipLine(sink),
27299 rotatedStart = rotate.invert(start[0], start[1]),
27300 ringBuffer = clipBuffer(),
27301 ringSink = clipLine(ringBuffer),
27302 polygonStarted = false,
27309 lineStart: lineStart,
27311 polygonStart: function() {
27312 clip.point = pointRing;
27313 clip.lineStart = ringStart;
27314 clip.lineEnd = ringEnd;
27318 polygonEnd: function() {
27319 clip.point = point;
27320 clip.lineStart = lineStart;
27321 clip.lineEnd = lineEnd;
27322 segments = merge(segments);
27323 var startInside = polygonContains(polygon, rotatedStart);
27324 if (segments.length) {
27325 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
27326 clipPolygon(segments, compareIntersection, startInside, interpolate, sink);
27327 } else if (startInside) {
27328 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
27330 interpolate(null, null, 1, sink);
27333 if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
27334 segments = polygon = null;
27336 sphere: function() {
27337 sink.polygonStart();
27339 interpolate(null, null, 1, sink);
27345 function point(lambda, phi) {
27346 var point = rotate(lambda, phi);
27347 if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);
27350 function pointLine(lambda, phi) {
27351 var point = rotate(lambda, phi);
27352 line.point(point[0], point[1]);
27355 function lineStart() {
27356 clip.point = pointLine;
27360 function lineEnd() {
27361 clip.point = point;
27365 function pointRing(lambda, phi) {
27366 ring.push([lambda, phi]);
27367 var point = rotate(lambda, phi);
27368 ringSink.point(point[0], point[1]);
27371 function ringStart() {
27372 ringSink.lineStart();
27376 function ringEnd() {
27377 pointRing(ring[0][0], ring[0][1]);
27378 ringSink.lineEnd();
27380 var clean = ringSink.clean(),
27381 ringSegments = ringBuffer.result(),
27382 i, n = ringSegments.length, m,
27387 polygon.push(ring);
27392 // No intersections.
27394 segment = ringSegments[0];
27395 if ((m = segment.length - 1) > 0) {
27396 if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
27398 for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
27404 // Rejoin connected segments.
27405 // TODO reuse ringBuffer.rejoin()?
27406 if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
27408 segments.push(ringSegments.filter(validSegment));
27415 function validSegment(segment) {
27416 return segment.length > 1;
27419 // Intersections are sorted along the clip edge. For both antimeridian cutting
27420 // and circle clipping, the same comparison is used.
27421 function compareIntersection(a, b) {
27422 return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])
27423 - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);
27426 var clipAntimeridian = clip(
27427 function() { return true; },
27428 clipAntimeridianLine,
27429 clipAntimeridianInterpolate,
27433 // Takes a line and cuts into visible segments. Return values: 0 - there were
27434 // intersections or the line was empty; 1 - no intersections; 2 - there were
27435 // intersections, and the first and last segments should be rejoined.
27436 function clipAntimeridianLine(stream) {
27440 clean; // no intersections
27443 lineStart: function() {
27444 stream.lineStart();
27447 point: function(lambda1, phi1) {
27448 var sign1 = lambda1 > 0 ? pi$3 : -pi$3,
27449 delta = abs(lambda1 - lambda0);
27450 if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole
27451 stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);
27452 stream.point(sign0, phi0);
27454 stream.lineStart();
27455 stream.point(sign1, phi0);
27456 stream.point(lambda1, phi0);
27458 } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian
27459 if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies
27460 if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;
27461 phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
27462 stream.point(sign0, phi0);
27464 stream.lineStart();
27465 stream.point(sign1, phi0);
27468 stream.point(lambda0 = lambda1, phi0 = phi1);
27471 lineEnd: function() {
27473 lambda0 = phi0 = NaN;
27475 clean: function() {
27476 return 2 - clean; // if intersections, rejoin first and last segments
27481 function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
27484 sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
27485 return abs(sinLambda0Lambda1) > epsilon$2
27486 ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
27487 - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
27488 / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
27489 : (phi0 + phi1) / 2;
27492 function clipAntimeridianInterpolate(from, to, direction, stream) {
27494 if (from == null) {
27495 phi = direction * halfPi$2;
27496 stream.point(-pi$3, phi);
27497 stream.point(0, phi);
27498 stream.point(pi$3, phi);
27499 stream.point(pi$3, 0);
27500 stream.point(pi$3, -phi);
27501 stream.point(0, -phi);
27502 stream.point(-pi$3, -phi);
27503 stream.point(-pi$3, 0);
27504 stream.point(-pi$3, phi);
27505 } else if (abs(from[0] - to[0]) > epsilon$2) {
27506 var lambda = from[0] < to[0] ? pi$3 : -pi$3;
27507 phi = direction * lambda / 2;
27508 stream.point(-lambda, phi);
27509 stream.point(0, phi);
27510 stream.point(lambda, phi);
27512 stream.point(to[0], to[1]);
27516 var clipCircle = function(radius, delta) {
27517 var cr = cos$1(radius),
27518 smallRadius = cr > 0,
27519 notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case
27521 function interpolate(from, to, direction, stream) {
27522 circleStream(stream, radius, delta, direction, from, to);
27525 function visible(lambda, phi) {
27526 return cos$1(lambda) * cos$1(phi) > cr;
27529 // Takes a line and cuts into visible segments. Return values used for polygon
27530 // clipping: 0 - there were intersections or the line was empty; 1 - no
27531 // intersections 2 - there were intersections, and the first and last segments
27532 // should be rejoined.
27533 function clipLine(stream) {
27534 var point0, // previous point
27535 c0, // code for previous point
27536 v0, // visibility of previous point
27537 v00, // visibility of first point
27538 clean; // no intersections
27540 lineStart: function() {
27544 point: function(lambda, phi) {
27545 var point1 = [lambda, phi],
27547 v = visible(lambda, phi),
27549 ? v ? 0 : code(lambda, phi)
27550 : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;
27551 if (!point0 && (v00 = v0 = v)) stream.lineStart();
27552 // Handle degeneracies.
27553 // TODO ignore if not clipping polygons.
27555 point2 = intersect(point0, point1);
27556 if (pointEqual(point0, point2) || pointEqual(point1, point2)) {
27557 point1[0] += epsilon$2;
27558 point1[1] += epsilon$2;
27559 v = visible(point1[0], point1[1]);
27565 // outside going in
27566 stream.lineStart();
27567 point2 = intersect(point1, point0);
27568 stream.point(point2[0], point2[1]);
27570 // inside going out
27571 point2 = intersect(point0, point1);
27572 stream.point(point2[0], point2[1]);
27576 } else if (notHemisphere && point0 && smallRadius ^ v) {
27578 // If the codes for two points are different, or are both zero,
27579 // and there this segment intersects with the small circle.
27580 if (!(c & c0) && (t = intersect(point1, point0, true))) {
27583 stream.lineStart();
27584 stream.point(t[0][0], t[0][1]);
27585 stream.point(t[1][0], t[1][1]);
27588 stream.point(t[1][0], t[1][1]);
27590 stream.lineStart();
27591 stream.point(t[0][0], t[0][1]);
27595 if (v && (!point0 || !pointEqual(point0, point1))) {
27596 stream.point(point1[0], point1[1]);
27598 point0 = point1, v0 = v, c0 = c;
27600 lineEnd: function() {
27601 if (v0) stream.lineEnd();
27604 // Rejoin first and last segments if there were intersections and the first
27605 // and last points were visible.
27606 clean: function() {
27607 return clean | ((v00 && v0) << 1);
27612 // Intersects the great circle between a and b with the clip circle.
27613 function intersect(a, b, two) {
27614 var pa = cartesian(a),
27617 // We have two planes, n1.p = d1 and n2.p = d2.
27618 // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
27619 var n1 = [1, 0, 0], // normal
27620 n2 = cartesianCross(pa, pb),
27621 n2n2 = cartesianDot(n2, n2),
27622 n1n2 = n2[0], // cartesianDot(n1, n2),
27623 determinant = n2n2 - n1n2 * n1n2;
27625 // Two polar points.
27626 if (!determinant) return !two && a;
27628 var c1 = cr * n2n2 / determinant,
27629 c2 = -cr * n1n2 / determinant,
27630 n1xn2 = cartesianCross(n1, n2),
27631 A = cartesianScale(n1, c1),
27632 B = cartesianScale(n2, c2);
27633 cartesianAddInPlace(A, B);
27635 // Solve |p(t)|^2 = 1.
27637 w = cartesianDot(A, u),
27638 uu = cartesianDot(u, u),
27639 t2 = w * w - uu * (cartesianDot(A, A) - 1);
27641 if (t2 < 0) return;
27644 q = cartesianScale(u, (-w - t) / uu);
27645 cartesianAddInPlace(q, A);
27648 if (!two) return q;
27650 // Two intersection points.
27651 var lambda0 = a[0],
27657 if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
27659 var delta = lambda1 - lambda0,
27660 polar = abs(delta - pi$3) < epsilon$2,
27661 meridian = polar || delta < epsilon$2;
27663 if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
27665 // Check that the first point is between a and b.
27668 ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)
27669 : phi0 <= q[1] && q[1] <= phi1
27670 : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
27671 var q1 = cartesianScale(u, (-w + t) / uu);
27672 cartesianAddInPlace(q1, A);
27673 return [q, spherical(q1)];
27677 // Generates a 4-bit vector representing the location of a point relative to
27678 // the small circle's bounding box.
27679 function code(lambda, phi) {
27680 var r = smallRadius ? radius : pi$3 - radius,
27682 if (lambda < -r) code |= 1; // left
27683 else if (lambda > r) code |= 2; // right
27684 if (phi < -r) code |= 4; // below
27685 else if (phi > r) code |= 8; // above
27689 return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);
27692 var transform = function(methods) {
27694 stream: transformer(methods)
27698 function transformer(methods) {
27699 return function(stream) {
27700 var s = new TransformStream;
27701 for (var key in methods) s[key] = methods[key];
27707 function TransformStream() {}
27709 TransformStream.prototype = {
27710 constructor: TransformStream,
27711 point: function(x, y) { this.stream.point(x, y); },
27712 sphere: function() { this.stream.sphere(); },
27713 lineStart: function() { this.stream.lineStart(); },
27714 lineEnd: function() { this.stream.lineEnd(); },
27715 polygonStart: function() { this.stream.polygonStart(); },
27716 polygonEnd: function() { this.stream.polygonEnd(); }
27719 function fitExtent(projection, extent, object) {
27720 var w = extent[1][0] - extent[0][0],
27721 h = extent[1][1] - extent[0][1],
27722 clip = projection.clipExtent && projection.clipExtent();
27726 .translate([0, 0]);
27728 if (clip != null) projection.clipExtent(null);
27730 geoStream(object, projection.stream(boundsStream$1));
27732 var b = boundsStream$1.result(),
27733 k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
27734 x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
27735 y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
27737 if (clip != null) projection.clipExtent(clip);
27741 .translate([x, y]);
27744 function fitSize(projection, size, object) {
27745 return fitExtent(projection, [[0, 0], size], object);
27749 var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
27751 var resample = function(project, delta2) {
27752 return +delta2 ? resample$1(project, delta2) : resampleNone(project);
27755 function resampleNone(project) {
27756 return transformer({
27757 point: function(x, y) {
27759 this.stream.point(x[0], x[1]);
27764 function resample$1(project, delta2) {
27766 function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
27769 d2 = dx * dx + dy * dy;
27770 if (d2 > 4 * delta2 && depth--) {
27774 m = sqrt(a * a + b * b + c * c),
27775 phi2 = asin(c /= m),
27776 lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),
27777 p = project(lambda2, phi2),
27782 dz = dy * dx2 - dx * dy2;
27783 if (dz * dz / d2 > delta2 // perpendicular projected distance
27784 || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
27785 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
27786 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
27787 stream.point(x2, y2);
27788 resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
27792 return function(stream) {
27793 var lambda00, x00, y00, a00, b00, c00, // first point
27794 lambda0, x0, y0, a0, b0, c0; // previous point
27796 var resampleStream = {
27798 lineStart: lineStart,
27800 polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
27801 polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
27804 function point(x, y) {
27806 stream.point(x[0], x[1]);
27809 function lineStart() {
27811 resampleStream.point = linePoint;
27812 stream.lineStart();
27815 function linePoint(lambda, phi) {
27816 var c = cartesian([lambda, phi]), p = project(lambda, phi);
27817 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);
27818 stream.point(x0, y0);
27821 function lineEnd() {
27822 resampleStream.point = point;
27826 function ringStart() {
27828 resampleStream.point = ringPoint;
27829 resampleStream.lineEnd = ringEnd;
27832 function ringPoint(lambda, phi) {
27833 linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
27834 resampleStream.point = linePoint;
27837 function ringEnd() {
27838 resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
27839 resampleStream.lineEnd = lineEnd;
27843 return resampleStream;
27847 var transformRadians = transformer({
27848 point: function(x, y) {
27849 this.stream.point(x * radians, y * radians);
27853 function projection(project) {
27854 return projectionMutator(function() { return project; })();
27857 function projectionMutator(projectAt) {
27860 x = 480, y = 250, // translate
27861 dx, dy, lambda = 0, phi = 0, // center
27862 deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
27863 theta = null, preclip = clipAntimeridian, // clip angle
27864 x0 = null, y0, x1, y1, postclip = identity$4, // clip extent
27865 delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
27869 function projection(point) {
27870 point = projectRotate(point[0] * radians, point[1] * radians);
27871 return [point[0] * k + dx, dy - point[1] * k];
27874 function invert(point) {
27875 point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
27876 return point && [point[0] * degrees$1, point[1] * degrees$1];
27879 function projectTransform(x, y) {
27880 return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
27883 projection.stream = function(stream) {
27884 return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));
27887 projection.clipAngle = function(_) {
27888 return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
27891 projection.clipExtent = function(_) {
27892 return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
27895 projection.scale = function(_) {
27896 return arguments.length ? (k = +_, recenter()) : k;
27899 projection.translate = function(_) {
27900 return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
27903 projection.center = function(_) {
27904 return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
27907 projection.rotate = function(_) {
27908 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];
27911 projection.precision = function(_) {
27912 return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
27915 projection.fitExtent = function(extent, object) {
27916 return fitExtent(projection, extent, object);
27919 projection.fitSize = function(size, object) {
27920 return fitSize(projection, size, object);
27923 function recenter() {
27924 projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
27925 var center = project(lambda, phi);
27926 dx = x - center[0] * k;
27927 dy = y + center[1] * k;
27932 cache = cacheStream = null;
27936 return function() {
27937 project = projectAt.apply(this, arguments);
27938 projection.invert = project.invert && invert;
27943 function conicProjection(projectAt) {
27946 m = projectionMutator(projectAt),
27949 p.parallels = function(_) {
27950 return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
27956 function cylindricalEqualAreaRaw(phi0) {
27957 var cosPhi0 = cos$1(phi0);
27959 function forward(lambda, phi) {
27960 return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
27963 forward.invert = function(x, y) {
27964 return [x / cosPhi0, asin(y * cosPhi0)];
27970 function conicEqualAreaRaw(y0, y1) {
27971 var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
27973 // Are the parallels symmetrical around the Equator?
27974 if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);
27976 var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
27978 function project(x, y) {
27979 var r = sqrt(c - 2 * n * sin$1(y)) / n;
27980 return [r * sin$1(x *= n), r0 - r * cos$1(x)];
27983 project.invert = function(x, y) {
27985 return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
27991 var conicEqualArea = function() {
27992 return conicProjection(conicEqualAreaRaw)
27994 .center([0, 33.6442]);
27997 var albers = function() {
27998 return conicEqualArea()
27999 .parallels([29.5, 45.5])
28001 .translate([480, 250])
28003 .center([-0.6, 38.7]);
28006 // The projections must have mutually exclusive clip regions on the sphere,
28007 // as this will avoid emitting interleaving lines and polygons.
28008 function multiplex(streams) {
28009 var n = streams.length;
28011 point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
28012 sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
28013 lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
28014 lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
28015 polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
28016 polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
28020 // A composite projection for the United States, configured by default for
28021 // 960×500. The projection also works quite well at 960×600 if you change the
28022 // scale to 1285 and adjust the translate accordingly. The set of standard
28023 // parallels for each region comes from USGS, which is published here:
28024 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
28025 var albersUsa = function() {
28028 lower48 = albers(), lower48Point,
28029 alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
28030 hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
28031 point, pointStream = {point: function(x, y) { point = [x, y]; }};
28033 function albersUsa(coordinates) {
28034 var x = coordinates[0], y = coordinates[1];
28035 return point = null,
28036 (lower48Point.point(x, y), point)
28037 || (alaskaPoint.point(x, y), point)
28038 || (hawaiiPoint.point(x, y), point);
28041 albersUsa.invert = function(coordinates) {
28042 var k = lower48.scale(),
28043 t = lower48.translate(),
28044 x = (coordinates[0] - t[0]) / k,
28045 y = (coordinates[1] - t[1]) / k;
28046 return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
28047 : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
28048 : lower48).invert(coordinates);
28051 albersUsa.stream = function(stream) {
28052 return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
28055 albersUsa.precision = function(_) {
28056 if (!arguments.length) return lower48.precision();
28057 lower48.precision(_), alaska.precision(_), hawaii.precision(_);
28061 albersUsa.scale = function(_) {
28062 if (!arguments.length) return lower48.scale();
28063 lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
28064 return albersUsa.translate(lower48.translate());
28067 albersUsa.translate = function(_) {
28068 if (!arguments.length) return lower48.translate();
28069 var k = lower48.scale(), x = +_[0], y = +_[1];
28071 lower48Point = lower48
28073 .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
28074 .stream(pointStream);
28076 alaskaPoint = alaska
28077 .translate([x - 0.307 * k, y + 0.201 * k])
28078 .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
28079 .stream(pointStream);
28081 hawaiiPoint = hawaii
28082 .translate([x - 0.205 * k, y + 0.212 * k])
28083 .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
28084 .stream(pointStream);
28089 albersUsa.fitExtent = function(extent, object) {
28090 return fitExtent(albersUsa, extent, object);
28093 albersUsa.fitSize = function(size, object) {
28094 return fitSize(albersUsa, size, object);
28098 cache = cacheStream = null;
28102 return albersUsa.scale(1070);
28105 function azimuthalRaw(scale) {
28106 return function(x, y) {
28109 k = scale(cx * cy);
28117 function azimuthalInvert(angle) {
28118 return function(x, y) {
28119 var z = sqrt(x * x + y * y),
28124 atan2(x * sc, z * cc),
28125 asin(z && y * sc / z)
28130 var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
28131 return sqrt(2 / (1 + cxcy));
28134 azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
28135 return 2 * asin(z / 2);
28138 var azimuthalEqualArea = function() {
28139 return projection(azimuthalEqualAreaRaw)
28141 .clipAngle(180 - 1e-3);
28144 var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
28145 return (c = acos(c)) && c / sin$1(c);
28148 azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
28152 var azimuthalEquidistant = function() {
28153 return projection(azimuthalEquidistantRaw)
28155 .clipAngle(180 - 1e-3);
28158 function mercatorRaw(lambda, phi) {
28159 return [lambda, log(tan((halfPi$2 + phi) / 2))];
28162 mercatorRaw.invert = function(x, y) {
28163 return [x, 2 * atan(exp(y)) - halfPi$2];
28166 var mercator = function() {
28167 return mercatorProjection(mercatorRaw)
28168 .scale(961 / tau$3);
28171 function mercatorProjection(project) {
28172 var m = projection(project),
28174 translate = m.translate,
28175 clipExtent = m.clipExtent,
28178 m.scale = function(_) {
28179 return arguments.length ? (scale(_), clipAuto && m.clipExtent(null), m) : scale();
28182 m.translate = function(_) {
28183 return arguments.length ? (translate(_), clipAuto && m.clipExtent(null), m) : translate();
28186 m.clipExtent = function(_) {
28187 if (!arguments.length) return clipAuto ? null : clipExtent();
28188 if (clipAuto = _ == null) {
28189 var k = pi$3 * scale(),
28191 _ = [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]];
28197 return m.clipExtent(null);
28201 return tan((halfPi$2 + y) / 2);
28204 function conicConformalRaw(y0, y1) {
28205 var cy0 = cos$1(y0),
28206 n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),
28207 f = cy0 * pow(tany(y0), n) / n;
28209 if (!n) return mercatorRaw;
28211 function project(x, y) {
28212 if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }
28213 else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }
28214 var r = f / pow(tany(y), n);
28215 return [r * sin$1(n * x), f - r * cos$1(n * x)];
28218 project.invert = function(x, y) {
28219 var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);
28220 return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];
28226 var conicConformal = function() {
28227 return conicProjection(conicConformalRaw)
28229 .parallels([30, 30]);
28232 function equirectangularRaw(lambda, phi) {
28233 return [lambda, phi];
28236 equirectangularRaw.invert = equirectangularRaw;
28238 var equirectangular = function() {
28239 return projection(equirectangularRaw)
28243 function conicEquidistantRaw(y0, y1) {
28244 var cy0 = cos$1(y0),
28245 n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
28248 if (abs(n) < epsilon$2) return equirectangularRaw;
28250 function project(x, y) {
28251 var gy = g - y, nx = n * x;
28252 return [gy * sin$1(nx), g - gy * cos$1(nx)];
28255 project.invert = function(x, y) {
28257 return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];
28263 var conicEquidistant = function() {
28264 return conicProjection(conicEquidistantRaw)
28266 .center([0, 13.9389]);
28269 function gnomonicRaw(x, y) {
28270 var cy = cos$1(y), k = cos$1(x) * cy;
28271 return [cy * sin$1(x) / k, sin$1(y) / k];
28274 gnomonicRaw.invert = azimuthalInvert(atan);
28276 var gnomonic = function() {
28277 return projection(gnomonicRaw)
28282 function scaleTranslate(kx, ky, tx, ty) {
28283 return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({
28284 point: function(x, y) {
28285 this.stream.point(x * kx + tx, y * ky + ty);
28290 var identity$5 = function() {
28291 var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$4, // scale, translate and reflect
28292 x0 = null, y0, x1, y1, clip = identity$4, // clip extent
28298 cache = cacheStream = null;
28302 return projection = {
28303 stream: function(stream) {
28304 return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream));
28306 clipExtent: function(_) {
28307 return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
28309 scale: function(_) {
28310 return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;
28312 translate: function(_) {
28313 return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
28315 reflectX: function(_) {
28316 return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
28318 reflectY: function(_) {
28319 return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;
28321 fitExtent: function(extent, object) {
28322 return fitExtent(projection, extent, object);
28324 fitSize: function(size, object) {
28325 return fitSize(projection, size, object);
28330 function orthographicRaw(x, y) {
28331 return [cos$1(y) * sin$1(x), sin$1(y)];
28334 orthographicRaw.invert = azimuthalInvert(asin);
28336 var orthographic = function() {
28337 return projection(orthographicRaw)
28339 .clipAngle(90 + epsilon$2);
28342 function stereographicRaw(x, y) {
28343 var cy = cos$1(y), k = 1 + cos$1(x) * cy;
28344 return [cy * sin$1(x) / k, sin$1(y) / k];
28347 stereographicRaw.invert = azimuthalInvert(function(z) {
28348 return 2 * atan(z);
28351 var stereographic = function() {
28352 return projection(stereographicRaw)
28357 function transverseMercatorRaw(lambda, phi) {
28358 return [log(tan((halfPi$2 + phi) / 2)), -lambda];
28361 transverseMercatorRaw.invert = function(x, y) {
28362 return [-y, 2 * atan(exp(x)) - halfPi$2];
28365 var transverseMercator = function() {
28366 var m = mercatorProjection(transverseMercatorRaw),
28370 m.center = function(_) {
28371 return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
28374 m.rotate = function(_) {
28375 return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
28378 return rotate([0, 0, 90])
28382 function defaultSeparation(a, b) {
28383 return a.parent === b.parent ? 1 : 2;
28386 function meanX(children) {
28387 return children.reduce(meanXReduce, 0) / children.length;
28390 function meanXReduce(x, c) {
28394 function maxY(children) {
28395 return 1 + children.reduce(maxYReduce, 0);
28398 function maxYReduce(y, c) {
28399 return Math.max(y, c.y);
28402 function leafLeft(node) {
28404 while (children = node.children) node = children[0];
28408 function leafRight(node) {
28410 while (children = node.children) node = children[children.length - 1];
28414 var cluster = function() {
28415 var separation = defaultSeparation,
28420 function cluster(root) {
28424 // First walk, computing the initial x & y values.
28425 root.eachAfter(function(node) {
28426 var children = node.children;
28428 node.x = meanX(children);
28429 node.y = maxY(children);
28431 node.x = previousNode ? x += separation(node, previousNode) : 0;
28433 previousNode = node;
28437 var left = leafLeft(root),
28438 right = leafRight(root),
28439 x0 = left.x - separation(left, right) / 2,
28440 x1 = right.x + separation(right, left) / 2;
28442 // Second walk, normalizing x & y to the desired size.
28443 return root.eachAfter(nodeSize ? function(node) {
28444 node.x = (node.x - root.x) * dx;
28445 node.y = (root.y - node.y) * dy;
28446 } : function(node) {
28447 node.x = (node.x - x0) / (x1 - x0) * dx;
28448 node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
28452 cluster.separation = function(x) {
28453 return arguments.length ? (separation = x, cluster) : separation;
28456 cluster.size = function(x) {
28457 return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
28460 cluster.nodeSize = function(x) {
28461 return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
28467 function count(node) {
28469 children = node.children,
28470 i = children && children.length;
28472 else while (--i >= 0) sum += children[i].value;
28476 var node_count = function() {
28477 return this.eachAfter(count);
28480 var node_each = function(callback) {
28481 var node = this, current, next = [node], children, i, n;
28483 current = next.reverse(), next = [];
28484 while (node = current.pop()) {
28485 callback(node), children = node.children;
28486 if (children) for (i = 0, n = children.length; i < n; ++i) {
28487 next.push(children[i]);
28490 } while (next.length);
28494 var node_eachBefore = function(callback) {
28495 var node = this, nodes = [node], children, i;
28496 while (node = nodes.pop()) {
28497 callback(node), children = node.children;
28498 if (children) for (i = children.length - 1; i >= 0; --i) {
28499 nodes.push(children[i]);
28505 var node_eachAfter = function(callback) {
28506 var node = this, nodes = [node], next = [], children, i, n;
28507 while (node = nodes.pop()) {
28508 next.push(node), children = node.children;
28509 if (children) for (i = 0, n = children.length; i < n; ++i) {
28510 nodes.push(children[i]);
28513 while (node = next.pop()) {
28519 var node_sum = function(value) {
28520 return this.eachAfter(function(node) {
28521 var sum = +value(node.data) || 0,
28522 children = node.children,
28523 i = children && children.length;
28524 while (--i >= 0) sum += children[i].value;
28529 var node_sort = function(compare) {
28530 return this.eachBefore(function(node) {
28531 if (node.children) {
28532 node.children.sort(compare);
28537 var node_path = function(end) {
28539 ancestor = leastCommonAncestor(start, end),
28541 while (start !== ancestor) {
28542 start = start.parent;
28545 var k = nodes.length;
28546 while (end !== ancestor) {
28547 nodes.splice(k, 0, end);
28553 function leastCommonAncestor(a, b) {
28554 if (a === b) return a;
28555 var aNodes = a.ancestors(),
28556 bNodes = b.ancestors(),
28568 var node_ancestors = function() {
28569 var node = this, nodes = [node];
28570 while (node = node.parent) {
28576 var node_descendants = function() {
28578 this.each(function(node) {
28584 var node_leaves = function() {
28586 this.eachBefore(function(node) {
28587 if (!node.children) {
28594 var node_links = function() {
28595 var root = this, links = [];
28596 root.each(function(node) {
28597 if (node !== root) { // Don’t include the root’s parent, if any.
28598 links.push({source: node.parent, target: node});
28604 function hierarchy(data, children) {
28605 var root = new Node(data),
28606 valued = +data.value && (root.value = data.value),
28614 if (children == null) children = defaultChildren;
28616 while (node = nodes.pop()) {
28617 if (valued) node.value = +node.data.value;
28618 if ((childs = children(node.data)) && (n = childs.length)) {
28619 node.children = new Array(n);
28620 for (i = n - 1; i >= 0; --i) {
28621 nodes.push(child = node.children[i] = new Node(childs[i]));
28622 child.parent = node;
28623 child.depth = node.depth + 1;
28628 return root.eachBefore(computeHeight);
28631 function node_copy() {
28632 return hierarchy(this).eachBefore(copyData);
28635 function defaultChildren(d) {
28639 function copyData(node) {
28640 node.data = node.data.data;
28643 function computeHeight(node) {
28645 do node.height = height;
28646 while ((node = node.parent) && (node.height < ++height));
28649 function Node(data) {
28653 this.parent = null;
28656 Node.prototype = hierarchy.prototype = {
28660 eachAfter: node_eachAfter,
28661 eachBefore: node_eachBefore,
28665 ancestors: node_ancestors,
28666 descendants: node_descendants,
28667 leaves: node_leaves,
28672 function Node$2(value) {
28677 var shuffle$1 = function(array) {
28679 n = (array = array.slice()).length,
28684 var next = new Node$2(array[n - 1]);
28685 if (node) node = node.next = next;
28686 else node = head = next;
28687 array[i] = array[--n];
28696 var enclose = function(circles) {
28697 return encloseN(shuffle$1(circles), []);
28700 function encloses(a, b) {
28701 var dx = b.x - a.x,
28704 return dr * dr + 1e-6 > dx * dx + dy * dy;
28707 // Returns the smallest circle that contains circles L and intersects circles B.
28708 function encloseN(L, B) {
28715 switch (B.length) {
28716 case 1: circle = enclose1(B[0]); break;
28717 case 2: circle = enclose2(B[0], B[1]); break;
28718 case 3: circle = enclose3(B[0], B[1], B[2]); break;
28722 p1 = l1._, l2 = l1.next;
28723 if (!circle || !encloses(circle, p1)) {
28725 // Temporarily truncate L before l1.
28726 if (l0) L.tail = l0, l0.next = null;
28727 else L.head = L.tail = null;
28730 circle = encloseN(L, B); // Note: reorders L!
28733 // Move l1 to the front of L and reconnect the truncated list L.
28734 if (L.head) l1.next = L.head, L.head = l1;
28735 else l1.next = null, L.head = L.tail = l1;
28736 l0 = L.tail, l0.next = l2;
28748 function enclose1(a) {
28756 function enclose2(a, b) {
28757 var x1 = a.x, y1 = a.y, r1 = a.r,
28758 x2 = b.x, y2 = b.y, r2 = b.r,
28759 x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
28760 l = Math.sqrt(x21 * x21 + y21 * y21);
28762 x: (x1 + x2 + x21 / l * r21) / 2,
28763 y: (y1 + y2 + y21 / l * r21) / 2,
28764 r: (l + r1 + r2) / 2
28768 function enclose3(a, b, c) {
28769 var x1 = a.x, y1 = a.y, r1 = a.r,
28770 x2 = b.x, y2 = b.y, r2 = b.r,
28771 x3 = c.x, y3 = c.y, r3 = c.r,
28772 a2 = 2 * (x1 - x2),
28773 b2 = 2 * (y1 - y2),
28774 c2 = 2 * (r2 - r1),
28775 d2 = x1 * x1 + y1 * y1 - r1 * r1 - x2 * x2 - y2 * y2 + r2 * r2,
28776 a3 = 2 * (x1 - x3),
28777 b3 = 2 * (y1 - y3),
28778 c3 = 2 * (r3 - r1),
28779 d3 = x1 * x1 + y1 * y1 - r1 * r1 - x3 * x3 - y3 * y3 + r3 * r3,
28780 ab = a3 * b2 - a2 * b3,
28781 xa = (b2 * d3 - b3 * d2) / ab - x1,
28782 xb = (b3 * c2 - b2 * c3) / ab,
28783 ya = (a3 * d2 - a2 * d3) / ab - y1,
28784 yb = (a2 * c3 - a3 * c2) / ab,
28785 A = xb * xb + yb * yb - 1,
28786 B = 2 * (xa * xb + ya * yb + r1),
28787 C = xa * xa + ya * ya - r1 * r1,
28788 r = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A);
28790 x: xa + xb * r + x1,
28791 y: ya + yb * r + y1,
28796 function place(a, b, c) {
28803 dc = dx * dx + dy * dy;
28805 var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
28806 y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
28807 c.x = ax + x * dx + y * dy;
28808 c.y = ay + x * dy - y * dx;
28815 function intersects(a, b) {
28816 var dx = b.x - a.x,
28819 return dr * dr - 1e-6 > dx * dx + dy * dy;
28822 function distance1(a, b) {
28824 while (a !== b) l += 2 * (a = a.next)._.r;
28828 function distance2(circle, x, y) {
28829 var dx = circle.x - x,
28831 return dx * dx + dy * dy;
28834 function Node$1(circle) {
28837 this.previous = null;
28840 function packEnclose(circles) {
28841 if (!(n = circles.length)) return 0;
28845 // Place the first circle.
28846 a = circles[0], a.x = 0, a.y = 0;
28847 if (!(n > 1)) return a.r;
28849 // Place the second circle.
28850 b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
28851 if (!(n > 2)) return a.r + b.r;
28853 // Place the third circle.
28854 place(b, a, c = circles[2]);
28856 // Initialize the weighted centroid.
28857 var aa = a.r * a.r,
28861 ox = aa * a.x + ba * b.x + ca * c.x,
28862 oy = aa * a.y + ba * b.y + ca * c.y,
28863 cx, cy, i, j, k, sj, sk;
28865 // Initialize the front-chain using the first three circles a, b and c.
28866 a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
28867 a.next = c.previous = b;
28868 b.next = a.previous = c;
28869 c.next = b.previous = a;
28871 // Attempt to place each remaining circle…
28872 pack: for (i = 3; i < n; ++i) {
28873 place(a._, b._, c = circles[i]), c = new Node$1(c);
28875 // Find the closest intersecting circle on the front-chain, if any.
28876 // “Closeness” is determined by linear distance along the front-chain.
28877 // “Ahead” or “behind” is likewise determined by linear distance.
28878 j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
28881 if (intersects(j._, c._)) {
28882 if (sj + a._.r + b._.r > distance1(j, b)) a = j; else b = j;
28883 a.next = b, b.previous = a, --i;
28886 sj += j._.r, j = j.next;
28888 if (intersects(k._, c._)) {
28889 if (distance1(a, k) > sk + a._.r + b._.r) a = k; else b = k;
28890 a.next = b, b.previous = a, --i;
28893 sk += k._.r, k = k.previous;
28895 } while (j !== k.next);
28897 // Success! Insert the new circle c between a and b.
28898 c.previous = a, c.next = b, a.next = b.previous = b = c;
28900 // Update the weighted centroid.
28901 oa += ca = c._.r * c._.r;
28905 // Compute the new closest circle a to centroid.
28906 aa = distance2(a._, cx = ox / oa, cy = oy / oa);
28907 while ((c = c.next) !== b) {
28908 if ((ca = distance2(c._, cx, cy)) < aa) {
28915 // Compute the enclosing circle of the front chain.
28916 a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
28918 // Translate the circles to put the enclosing circle around the origin.
28919 for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
28924 var siblings = function(circles) {
28925 packEnclose(circles);
28929 function optional(f) {
28930 return f == null ? null : required(f);
28933 function required(f) {
28934 if (typeof f !== "function") throw new Error;
28938 function constantZero() {
28942 var constant$8 = function(x) {
28943 return function() {
28948 function defaultRadius$1(d) {
28949 return Math.sqrt(d.value);
28952 var index$5 = function() {
28956 padding = constantZero;
28958 function pack(root) {
28959 root.x = dx / 2, root.y = dy / 2;
28961 root.eachBefore(radiusLeaf(radius))
28962 .eachAfter(packChildren(padding, 0.5))
28963 .eachBefore(translateChild(1));
28965 root.eachBefore(radiusLeaf(defaultRadius$1))
28966 .eachAfter(packChildren(constantZero, 1))
28967 .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
28968 .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
28973 pack.radius = function(x) {
28974 return arguments.length ? (radius = optional(x), pack) : radius;
28977 pack.size = function(x) {
28978 return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
28981 pack.padding = function(x) {
28982 return arguments.length ? (padding = typeof x === "function" ? x : constant$8(+x), pack) : padding;
28988 function radiusLeaf(radius) {
28989 return function(node) {
28990 if (!node.children) {
28991 node.r = Math.max(0, +radius(node) || 0);
28996 function packChildren(padding, k) {
28997 return function(node) {
28998 if (children = node.children) {
29001 n = children.length,
29002 r = padding(node) * k || 0,
29005 if (r) for (i = 0; i < n; ++i) children[i].r += r;
29006 e = packEnclose(children);
29007 if (r) for (i = 0; i < n; ++i) children[i].r -= r;
29013 function translateChild(k) {
29014 return function(node) {
29015 var parent = node.parent;
29018 node.x = parent.x + k * node.x;
29019 node.y = parent.y + k * node.y;
29024 var roundNode = function(node) {
29025 node.x0 = Math.round(node.x0);
29026 node.y0 = Math.round(node.y0);
29027 node.x1 = Math.round(node.x1);
29028 node.y1 = Math.round(node.y1);
29031 var treemapDice = function(parent, x0, y0, x1, y1) {
29032 var nodes = parent.children,
29036 k = parent.value && (x1 - x0) / parent.value;
29039 node = nodes[i], node.y0 = y0, node.y1 = y1;
29040 node.x0 = x0, node.x1 = x0 += node.value * k;
29044 var partition = function() {
29050 function partition(root) {
29051 var n = root.height + 1;
29056 root.eachBefore(positionNode(dy, n));
29057 if (round) root.eachBefore(roundNode);
29061 function positionNode(dy, n) {
29062 return function(node) {
29063 if (node.children) {
29064 treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
29068 x1 = node.x1 - padding,
29069 y1 = node.y1 - padding;
29070 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29071 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29079 partition.round = function(x) {
29080 return arguments.length ? (round = !!x, partition) : round;
29083 partition.size = function(x) {
29084 return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
29087 partition.padding = function(x) {
29088 return arguments.length ? (padding = +x, partition) : padding;
29094 var keyPrefix$1 = "$";
29095 var preroot = {depth: -1};
29096 var ambiguous = {};
29098 function defaultId(d) {
29102 function defaultParentId(d) {
29106 var stratify = function() {
29107 var id = defaultId,
29108 parentId = defaultParentId;
29110 function stratify(data) {
29117 nodes = new Array(n),
29122 for (i = 0; i < n; ++i) {
29123 d = data[i], node = nodes[i] = new Node(d);
29124 if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
29125 nodeKey = keyPrefix$1 + (node.id = nodeId);
29126 nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
29130 for (i = 0; i < n; ++i) {
29131 node = nodes[i], nodeId = parentId(data[i], i, data);
29132 if (nodeId == null || !(nodeId += "")) {
29133 if (root) throw new Error("multiple roots");
29136 parent = nodeByKey[keyPrefix$1 + nodeId];
29137 if (!parent) throw new Error("missing: " + nodeId);
29138 if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
29139 if (parent.children) parent.children.push(node);
29140 else parent.children = [node];
29141 node.parent = parent;
29145 if (!root) throw new Error("no root");
29146 root.parent = preroot;
29147 root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
29148 root.parent = null;
29149 if (n > 0) throw new Error("cycle");
29154 stratify.id = function(x) {
29155 return arguments.length ? (id = required(x), stratify) : id;
29158 stratify.parentId = function(x) {
29159 return arguments.length ? (parentId = required(x), stratify) : parentId;
29165 function defaultSeparation$1(a, b) {
29166 return a.parent === b.parent ? 1 : 2;
29169 // function radialSeparation(a, b) {
29170 // return (a.parent === b.parent ? 1 : 2) / a.depth;
29173 // This function is used to traverse the left contour of a subtree (or
29174 // subforest). It returns the successor of v on this contour. This successor is
29175 // either given by the leftmost child of v or by the thread of v. The function
29176 // returns null if and only if v is on the highest level of its subtree.
29177 function nextLeft(v) {
29178 var children = v.children;
29179 return children ? children[0] : v.t;
29182 // This function works analogously to nextLeft.
29183 function nextRight(v) {
29184 var children = v.children;
29185 return children ? children[children.length - 1] : v.t;
29188 // Shifts the current subtree rooted at w+. This is done by increasing
29189 // prelim(w+) and mod(w+) by shift.
29190 function moveSubtree(wm, wp, shift) {
29191 var change = shift / (wp.i - wm.i);
29199 // All other shifts, applied to the smaller subtrees between w- and w+, are
29200 // performed by this function. To prepare the shifts, we have to adjust
29201 // change(w+), shift(w+), and change(w-).
29202 function executeShifts(v) {
29205 children = v.children,
29206 i = children.length,
29212 shift += w.s + (change += w.c);
29216 // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
29217 // returns the specified (default) ancestor.
29218 function nextAncestor(vim, v, ancestor) {
29219 return vim.a.parent === v.parent ? vim.a : ancestor;
29222 function TreeNode(node, i) {
29224 this.parent = null;
29225 this.children = null;
29226 this.A = null; // default ancestor
29227 this.a = this; // ancestor
29228 this.z = 0; // prelim
29230 this.c = 0; // change
29231 this.s = 0; // shift
29232 this.t = null; // thread
29233 this.i = i; // number
29236 TreeNode.prototype = Object.create(Node.prototype);
29238 function treeRoot(root) {
29239 var tree = new TreeNode(root, 0),
29247 while (node = nodes.pop()) {
29248 if (children = node._.children) {
29249 node.children = new Array(n = children.length);
29250 for (i = n - 1; i >= 0; --i) {
29251 nodes.push(child = node.children[i] = new TreeNode(children[i], i));
29252 child.parent = node;
29257 (tree.parent = new TreeNode(null, 0)).children = [tree];
29261 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
29262 var tree = function() {
29263 var separation = defaultSeparation$1,
29268 function tree(root) {
29269 var t = treeRoot(root);
29271 // Compute the layout using Buchheim et al.’s algorithm.
29272 t.eachAfter(firstWalk), t.parent.m = -t.z;
29273 t.eachBefore(secondWalk);
29275 // If a fixed node size is specified, scale x and y.
29276 if (nodeSize) root.eachBefore(sizeNode);
29278 // If a fixed tree size is specified, scale x and y based on the extent.
29279 // Compute the left-most, right-most, and depth-most nodes for extents.
29284 root.eachBefore(function(node) {
29285 if (node.x < left.x) left = node;
29286 if (node.x > right.x) right = node;
29287 if (node.depth > bottom.depth) bottom = node;
29289 var s = left === right ? 1 : separation(left, right) / 2,
29291 kx = dx / (right.x + s + tx),
29292 ky = dy / (bottom.depth || 1);
29293 root.eachBefore(function(node) {
29294 node.x = (node.x + tx) * kx;
29295 node.y = node.depth * ky;
29302 // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
29303 // applied recursively to the children of v, as well as the function
29304 // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
29305 // node v is placed to the midpoint of its outermost children.
29306 function firstWalk(v) {
29307 var children = v.children,
29308 siblings = v.parent.children,
29309 w = v.i ? siblings[v.i - 1] : null;
29312 var midpoint = (children[0].z + children[children.length - 1].z) / 2;
29314 v.z = w.z + separation(v._, w._);
29315 v.m = v.z - midpoint;
29320 v.z = w.z + separation(v._, w._);
29322 v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
29325 // Computes all real x-coordinates by summing up the modifiers recursively.
29326 function secondWalk(v) {
29327 v._.x = v.z + v.parent.m;
29331 // The core of the algorithm. Here, a new subtree is combined with the
29332 // previous subtrees. Threads are used to traverse the inside and outside
29333 // contours of the left and right subtree up to the highest common level. The
29334 // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
29335 // superscript o means outside and i means inside, the subscript - means left
29336 // subtree and + means right subtree. For summing up the modifiers along the
29337 // contour, we use respective variables si+, si-, so-, and so+. Whenever two
29338 // nodes of the inside contours conflict, we compute the left one of the
29339 // greatest uncommon ancestors using the function ANCESTOR and call MOVE
29340 // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
29341 // Finally, we add a new thread (if necessary).
29342 function apportion(v, w, ancestor) {
29347 vom = vip.parent.children[0],
29353 while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
29354 vom = nextLeft(vom);
29355 vop = nextRight(vop);
29357 shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
29359 moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
29368 if (vim && !nextRight(vop)) {
29370 vop.m += sim - sop;
29372 if (vip && !nextLeft(vom)) {
29374 vom.m += sip - som;
29381 function sizeNode(node) {
29383 node.y = node.depth * dy;
29386 tree.separation = function(x) {
29387 return arguments.length ? (separation = x, tree) : separation;
29390 tree.size = function(x) {
29391 return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
29394 tree.nodeSize = function(x) {
29395 return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
29401 var treemapSlice = function(parent, x0, y0, x1, y1) {
29402 var nodes = parent.children,
29406 k = parent.value && (y1 - y0) / parent.value;
29409 node = nodes[i], node.x0 = x0, node.x1 = x1;
29410 node.y0 = y0, node.y1 = y0 += node.value * k;
29414 var phi = (1 + Math.sqrt(5)) / 2;
29416 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
29418 nodes = parent.children,
29425 value = parent.value,
29435 dx = x1 - x0, dy = y1 - y0;
29437 // Find the next non-empty node.
29438 do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
29439 minValue = maxValue = sumValue;
29440 alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
29441 beta = sumValue * sumValue * alpha;
29442 minRatio = Math.max(maxValue / beta, beta / minValue);
29444 // Keep adding nodes while the aspect ratio maintains or improves.
29445 for (; i1 < n; ++i1) {
29446 sumValue += nodeValue = nodes[i1].value;
29447 if (nodeValue < minValue) minValue = nodeValue;
29448 if (nodeValue > maxValue) maxValue = nodeValue;
29449 beta = sumValue * sumValue * alpha;
29450 newRatio = Math.max(maxValue / beta, beta / minValue);
29451 if (newRatio > minRatio) { sumValue -= nodeValue; break; }
29452 minRatio = newRatio;
29455 // Position and record the row orientation.
29456 rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
29457 if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
29458 else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
29459 value -= sumValue, i0 = i1;
29465 var squarify = ((function custom(ratio) {
29467 function squarify(parent, x0, y0, x1, y1) {
29468 squarifyRatio(ratio, parent, x0, y0, x1, y1);
29471 squarify.ratio = function(x) {
29472 return custom((x = +x) > 1 ? x : 1);
29478 var index$6 = function() {
29479 var tile = squarify,
29483 paddingStack = [0],
29484 paddingInner = constantZero,
29485 paddingTop = constantZero,
29486 paddingRight = constantZero,
29487 paddingBottom = constantZero,
29488 paddingLeft = constantZero;
29490 function treemap(root) {
29495 root.eachBefore(positionNode);
29496 paddingStack = [0];
29497 if (round) root.eachBefore(roundNode);
29501 function positionNode(node) {
29502 var p = paddingStack[node.depth],
29507 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29508 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29513 if (node.children) {
29514 p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
29515 x0 += paddingLeft(node) - p;
29516 y0 += paddingTop(node) - p;
29517 x1 -= paddingRight(node) - p;
29518 y1 -= paddingBottom(node) - p;
29519 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
29520 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
29521 tile(node, x0, y0, x1, y1);
29525 treemap.round = function(x) {
29526 return arguments.length ? (round = !!x, treemap) : round;
29529 treemap.size = function(x) {
29530 return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
29533 treemap.tile = function(x) {
29534 return arguments.length ? (tile = required(x), treemap) : tile;
29537 treemap.padding = function(x) {
29538 return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
29541 treemap.paddingInner = function(x) {
29542 return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$8(+x), treemap) : paddingInner;
29545 treemap.paddingOuter = function(x) {
29546 return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
29549 treemap.paddingTop = function(x) {
29550 return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$8(+x), treemap) : paddingTop;
29553 treemap.paddingRight = function(x) {
29554 return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$8(+x), treemap) : paddingRight;
29557 treemap.paddingBottom = function(x) {
29558 return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$8(+x), treemap) : paddingBottom;
29561 treemap.paddingLeft = function(x) {
29562 return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$8(+x), treemap) : paddingLeft;
29568 var binary = function(parent, x0, y0, x1, y1) {
29569 var nodes = parent.children,
29570 i, n = nodes.length,
29571 sum, sums = new Array(n + 1);
29573 for (sums[0] = sum = i = 0; i < n; ++i) {
29574 sums[i + 1] = sum += nodes[i].value;
29577 partition(0, n, parent.value, x0, y0, x1, y1);
29579 function partition(i, j, value, x0, y0, x1, y1) {
29581 var node = nodes[i];
29582 node.x0 = x0, node.y0 = y0;
29583 node.x1 = x1, node.y1 = y1;
29587 var valueOffset = sums[i],
29588 valueTarget = (value / 2) + valueOffset,
29593 var mid = k + hi >>> 1;
29594 if (sums[mid] < valueTarget) k = mid + 1;
29598 var valueLeft = sums[k] - valueOffset,
29599 valueRight = value - valueLeft;
29601 if ((y1 - y0) > (x1 - x0)) {
29602 var yk = (y0 * valueRight + y1 * valueLeft) / value;
29603 partition(i, k, valueLeft, x0, y0, x1, yk);
29604 partition(k, j, valueRight, x0, yk, x1, y1);
29606 var xk = (x0 * valueRight + x1 * valueLeft) / value;
29607 partition(i, k, valueLeft, x0, y0, xk, y1);
29608 partition(k, j, valueRight, xk, y0, x1, y1);
29613 var sliceDice = function(parent, x0, y0, x1, y1) {
29614 (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
29617 var resquarify = ((function custom(ratio) {
29619 function resquarify(parent, x0, y0, x1, y1) {
29620 if ((rows = parent._squarify) && (rows.ratio === ratio)) {
29628 value = parent.value;
29631 row = rows[j], nodes = row.children;
29632 for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
29633 if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
29634 else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
29635 value -= row.value;
29638 parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
29639 rows.ratio = ratio;
29643 resquarify.ratio = function(x) {
29644 return custom((x = +x) > 1 ? x : 1);
29650 function basis$2(t1, v0, v1, v2, v3) {
29651 var t2 = t1 * t1, t3 = t2 * t1;
29652 return ((1 - 3 * t1 + 3 * t2 - t3) * v0
29653 + (4 - 6 * t2 + 3 * t3) * v1
29654 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
29658 var basis$3 = function(values) {
29659 var n = values.length - 1;
29660 return function(t) {
29661 var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
29663 v2 = values[i + 1],
29664 v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
29665 v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
29666 return basis$2((t - i / n) * n, v0, v1, v2, v3);
29670 var basisClosed$1 = function(values) {
29671 var n = values.length;
29672 return function(t) {
29673 var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
29674 v0 = values[(i + n - 1) % n],
29675 v1 = values[i % n],
29676 v2 = values[(i + 1) % n],
29677 v3 = values[(i + 2) % n];
29678 return basis$2((t - i / n) * n, v0, v1, v2, v3);
29682 var constant$9 = function(x) {
29683 return function() {
29688 function linear$2(a, d) {
29689 return function(t) {
29694 function exponential$1(a, b, y) {
29695 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
29696 return Math.pow(a + t * b, y);
29700 function hue$1(a, b) {
29702 return d ? linear$2(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$9(isNaN(a) ? b : a);
29705 function gamma$1(y) {
29706 return (y = +y) === 1 ? nogamma$1 : function(a, b) {
29707 return b - a ? exponential$1(a, b, y) : constant$9(isNaN(a) ? b : a);
29711 function nogamma$1(a, b) {
29713 return d ? linear$2(a, d) : constant$9(isNaN(a) ? b : a);
29716 var rgb$1 = ((function rgbGamma(y) {
29717 var color$$1 = gamma$1(y);
29719 function rgb$$1(start, end) {
29720 var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
29721 g = color$$1(start.g, end.g),
29722 b = color$$1(start.b, end.b),
29723 opacity = nogamma$1(start.opacity, end.opacity);
29724 return function(t) {
29728 start.opacity = opacity(t);
29733 rgb$$1.gamma = rgbGamma;
29738 function rgbSpline$1(spline) {
29739 return function(colors) {
29740 var n = colors.length,
29745 for (i = 0; i < n; ++i) {
29746 color$$1 = rgb(colors[i]);
29747 r[i] = color$$1.r || 0;
29748 g[i] = color$$1.g || 0;
29749 b[i] = color$$1.b || 0;
29754 color$$1.opacity = 1;
29755 return function(t) {
29759 return color$$1 + "";
29764 var rgbBasis$1 = rgbSpline$1(basis$3);
29765 var rgbBasisClosed$1 = rgbSpline$1(basisClosed$1);
29767 var array$2 = function(a, b) {
29768 var nb = b ? b.length : 0,
29769 na = a ? Math.min(nb, a.length) : 0,
29774 for (i = 0; i < na; ++i) x[i] = value$1(a[i], b[i]);
29775 for (; i < nb; ++i) c[i] = b[i];
29777 return function(t) {
29778 for (i = 0; i < na; ++i) c[i] = x[i](t);
29783 var date$1 = function(a, b) {
29785 return a = +a, b -= a, function(t) {
29786 return d.setTime(a + b * t), d;
29790 var number$1 = function(a, b) {
29791 return a = +a, b -= a, function(t) {
29796 var object$2 = function(a, b) {
29801 if (a === null || typeof a !== "object") a = {};
29802 if (b === null || typeof b !== "object") b = {};
29806 i[k] = value$1(a[k], b[k]);
29812 return function(t) {
29813 for (k in i) c[k] = i[k](t);
29818 var reA$1 = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
29819 var reB$1 = new RegExp(reA$1.source, "g");
29821 function zero$1(b) {
29822 return function() {
29827 function one$1(b) {
29828 return function(t) {
29833 var string = function(a, b) {
29834 var bi = reA$1.lastIndex = reB$1.lastIndex = 0, // scan index for next number in b
29835 am, // current match in a
29836 bm, // current match in b
29837 bs, // string preceding current number in b, if any
29838 i = -1, // index in s
29839 s = [], // string constants and placeholders
29840 q = []; // number interpolators
29842 // Coerce inputs to strings.
29843 a = a + "", b = b + "";
29845 // Interpolate pairs of numbers in a & b.
29846 while ((am = reA$1.exec(a))
29847 && (bm = reB$1.exec(b))) {
29848 if ((bs = bm.index) > bi) { // a string precedes the next number in b
29849 bs = b.slice(bi, bs);
29850 if (s[i]) s[i] += bs; // coalesce with previous string
29853 if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
29854 if (s[i]) s[i] += bm; // coalesce with previous string
29856 } else { // interpolate non-matching numbers
29858 q.push({i: i, x: number$1(am, bm)});
29860 bi = reB$1.lastIndex;
29863 // Add remains of b.
29864 if (bi < b.length) {
29866 if (s[i]) s[i] += bs; // coalesce with previous string
29870 // Special optimization for only a single match.
29871 // Otherwise, interpolate each of the numbers and rejoin the string.
29872 return s.length < 2 ? (q[0]
29875 : (b = q.length, function(t) {
29876 for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
29881 var value$1 = function(a, b) {
29882 var t = typeof b, c;
29883 return b == null || t === "boolean" ? constant$9(b)
29884 : (t === "number" ? number$1
29885 : t === "string" ? ((c = color(b)) ? (b = c, rgb$1) : string)
29886 : b instanceof color ? rgb$1
29887 : b instanceof Date ? date$1
29888 : Array.isArray(b) ? array$2
29889 : isNaN(b) ? object$2
29893 var round = function(a, b) {
29894 return a = +a, b -= a, function(t) {
29895 return Math.round(a + b * t);
29899 var degrees$2 = 180 / Math.PI;
29910 var decompose$1 = function(a, b, c, d, e, f) {
29911 var scaleX, scaleY, skewX;
29912 if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
29913 if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
29914 if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
29915 if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
29919 rotate: Math.atan2(b, a) * degrees$2,
29920 skewX: Math.atan(skewX) * degrees$2,
29931 function parseCss$1(value) {
29932 if (value === "none") return identity$6;
29933 if (!cssNode$1) cssNode$1 = document.createElement("DIV"), cssRoot$1 = document.documentElement, cssView$1 = document.defaultView;
29934 cssNode$1.style.transform = value;
29935 value = cssView$1.getComputedStyle(cssRoot$1.appendChild(cssNode$1), null).getPropertyValue("transform");
29936 cssRoot$1.removeChild(cssNode$1);
29937 value = value.slice(7, -1).split(",");
29938 return decompose$1(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
29941 function parseSvg$1(value) {
29942 if (value == null) return identity$6;
29943 if (!svgNode$1) svgNode$1 = document.createElementNS("http://www.w3.org/2000/svg", "g");
29944 svgNode$1.setAttribute("transform", value);
29945 if (!(value = svgNode$1.transform.baseVal.consolidate())) return identity$6;
29946 value = value.matrix;
29947 return decompose$1(value.a, value.b, value.c, value.d, value.e, value.f);
29950 function interpolateTransform$1(parse, pxComma, pxParen, degParen) {
29953 return s.length ? s.pop() + " " : "";
29956 function translate(xa, ya, xb, yb, s, q) {
29957 if (xa !== xb || ya !== yb) {
29958 var i = s.push("translate(", null, pxComma, null, pxParen);
29959 q.push({i: i - 4, x: number$1(xa, xb)}, {i: i - 2, x: number$1(ya, yb)});
29960 } else if (xb || yb) {
29961 s.push("translate(" + xb + pxComma + yb + pxParen);
29965 function rotate(a, b, s, q) {
29967 if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
29968 q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number$1(a, b)});
29970 s.push(pop(s) + "rotate(" + b + degParen);
29974 function skewX(a, b, s, q) {
29976 q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number$1(a, b)});
29978 s.push(pop(s) + "skewX(" + b + degParen);
29982 function scale(xa, ya, xb, yb, s, q) {
29983 if (xa !== xb || ya !== yb) {
29984 var i = s.push(pop(s) + "scale(", null, ",", null, ")");
29985 q.push({i: i - 4, x: number$1(xa, xb)}, {i: i - 2, x: number$1(ya, yb)});
29986 } else if (xb !== 1 || yb !== 1) {
29987 s.push(pop(s) + "scale(" + xb + "," + yb + ")");
29991 return function(a, b) {
29992 var s = [], // string constants and placeholders
29993 q = []; // number interpolators
29994 a = parse(a), b = parse(b);
29995 translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
29996 rotate(a.rotate, b.rotate, s, q);
29997 skewX(a.skewX, b.skewX, s, q);
29998 scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
29999 a = b = null; // gc
30000 return function(t) {
30001 var i = -1, n = q.length, o;
30002 while (++i < n) s[(o = q[i]).i] = o.x(t);
30008 var interpolateTransformCss$1 = interpolateTransform$1(parseCss$1, "px, ", "px)", "deg)");
30009 var interpolateTransformSvg$1 = interpolateTransform$1(parseSvg$1, ", ", ")", ")");
30011 var rho$1 = Math.SQRT2;
30014 var epsilon2$2 = 1e-12;
30016 function cosh$1(x) {
30017 return ((x = Math.exp(x)) + 1 / x) / 2;
30020 function sinh$1(x) {
30021 return ((x = Math.exp(x)) - 1 / x) / 2;
30024 function tanh$1(x) {
30025 return ((x = Math.exp(2 * x)) - 1) / (x + 1);
30028 // p0 = [ux0, uy0, w0]
30029 // p1 = [ux1, uy1, w1]
30030 var interpolateZoom = function(p0, p1) {
30031 var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
30032 ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
30035 d2 = dx * dx + dy * dy,
30039 // Special case for u0 ≅ u1.
30040 if (d2 < epsilon2$2) {
30041 S = Math.log(w1 / w0) / rho$1;
30046 w0 * Math.exp(rho$1 * t * S)
30053 var d1 = Math.sqrt(d2),
30054 b0 = (w1 * w1 - w0 * w0 + rho4$1 * d2) / (2 * w0 * rho2$1 * d1),
30055 b1 = (w1 * w1 - w0 * w0 - rho4$1 * d2) / (2 * w1 * rho2$1 * d1),
30056 r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
30057 r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
30058 S = (r1 - r0) / rho$1;
30061 coshr0 = cosh$1(r0),
30062 u = w0 / (rho2$1 * d1) * (coshr0 * tanh$1(rho$1 * s + r0) - sinh$1(r0));
30066 w0 * coshr0 / cosh$1(rho$1 * s + r0)
30071 i.duration = S * 1000;
30076 function hsl$3(hue$$1) {
30077 return function(start, end) {
30078 var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
30079 s = nogamma$1(start.s, end.s),
30080 l = nogamma$1(start.l, end.l),
30081 opacity = nogamma$1(start.opacity, end.opacity);
30082 return function(t) {
30086 start.opacity = opacity(t);
30092 var hsl$4 = hsl$3(hue$1);
30093 var hslLong$1 = hsl$3(nogamma$1);
30095 function lab$2(start, end) {
30096 var l = nogamma$1((start = lab(start)).l, (end = lab(end)).l),
30097 a = nogamma$1(start.a, end.a),
30098 b = nogamma$1(start.b, end.b),
30099 opacity = nogamma$1(start.opacity, end.opacity);
30100 return function(t) {
30104 start.opacity = opacity(t);
30109 function hcl$3(hue$$1) {
30110 return function(start, end) {
30111 var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
30112 c = nogamma$1(start.c, end.c),
30113 l = nogamma$1(start.l, end.l),
30114 opacity = nogamma$1(start.opacity, end.opacity);
30115 return function(t) {
30119 start.opacity = opacity(t);
30125 var hcl$4 = hcl$3(hue$1);
30126 var hclLong$1 = hcl$3(nogamma$1);
30128 function cubehelix$3(hue$$1) {
30129 return (function cubehelixGamma(y) {
30132 function cubehelix$$1(start, end) {
30133 var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
30134 s = nogamma$1(start.s, end.s),
30135 l = nogamma$1(start.l, end.l),
30136 opacity = nogamma$1(start.opacity, end.opacity);
30137 return function(t) {
30140 start.l = l(Math.pow(t, y));
30141 start.opacity = opacity(t);
30146 cubehelix$$1.gamma = cubehelixGamma;
30148 return cubehelix$$1;
30152 var cubehelix$4 = cubehelix$3(hue$1);
30153 var cubehelixLong$1 = cubehelix$3(nogamma$1);
30155 var quantize$1 = function(interpolator, n) {
30156 var samples = new Array(n);
30157 for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
30161 var d3polygonArea = function(polygon) {
30163 n = polygon.length,
30165 b = polygon[n - 1],
30171 area += a[1] * b[0] - a[0] * b[1];
30177 var d3polygonCentroid = function(polygon) {
30179 n = polygon.length,
30183 b = polygon[n - 1],
30190 k += c = a[0] * b[1] - b[0] * a[1];
30191 x += (a[0] + b[0]) * c;
30192 y += (a[1] + b[1]) * c;
30195 return k *= 3, [x / k, y / k];
30198 // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
30199 // the 3D cross product in a quadrant I Cartesian coordinate system (+x is
30200 // right, +y is up). Returns a positive value if ABC is counter-clockwise,
30201 // negative if clockwise, and zero if the points are collinear.
30202 var cross = function(a, b, c) {
30203 return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
30206 function lexicographicOrder(a, b) {
30207 return a[0] - b[0] || a[1] - b[1];
30210 // Computes the upper convex hull per the monotone chain algorithm.
30211 // Assumes points.length >= 3, is sorted by x, unique in y.
30212 // Returns an array of indices into points in left-to-right order.
30213 function computeUpperHullIndexes(points) {
30214 var n = points.length,
30218 for (var i = 2; i < n; ++i) {
30219 while (size > 1 && cross(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
30220 indexes[size++] = i;
30223 return indexes.slice(0, size); // remove popped points
30226 var d3polygonHull = function(points) {
30227 if ((n = points.length) < 3) return null;
30231 sortedPoints = new Array(n),
30232 flippedPoints = new Array(n);
30234 for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
30235 sortedPoints.sort(lexicographicOrder);
30236 for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
30238 var upperIndexes = computeUpperHullIndexes(sortedPoints),
30239 lowerIndexes = computeUpperHullIndexes(flippedPoints);
30241 // Construct the hull polygon, removing possible duplicate endpoints.
30242 var skipLeft = lowerIndexes[0] === upperIndexes[0],
30243 skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
30246 // Add upper hull in right-to-l order.
30247 // Then add lower hull in left-to-right order.
30248 for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
30249 for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
30254 var contains = function(polygon, point) {
30255 var n = polygon.length,
30256 p = polygon[n - 1],
30257 x = point[0], y = point[1],
30258 x0 = p[0], y0 = p[1],
30262 for (var i = 0; i < n; ++i) {
30263 p = polygon[i], x1 = p[0], y1 = p[1];
30264 if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
30271 var length$1 = function(polygon) {
30273 n = polygon.length,
30274 b = polygon[n - 1],
30289 perimeter += Math.sqrt(xa * xa + ya * ya);
30295 var slice$3 = [].slice;
30299 function Queue(size) {
30300 if (!(size >= 1)) throw new Error;
30303 this._error = null;
30309 this._start = 0; // inside a synchronous task callback?
30312 Queue.prototype = queue.prototype = {
30313 constructor: Queue,
30314 defer: function(callback) {
30315 if (typeof callback !== "function" || this._call) throw new Error;
30316 if (this._error != null) return this;
30317 var t = slice$3.call(arguments, 1);
30319 ++this._waiting, this._tasks.push(t);
30323 abort: function() {
30324 if (this._error == null) abort(this, new Error("abort"));
30327 await: function(callback) {
30328 if (typeof callback !== "function" || this._call) throw new Error;
30329 this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
30333 awaitAll: function(callback) {
30334 if (typeof callback !== "function" || this._call) throw new Error;
30335 this._call = callback;
30341 function poke$1(q) {
30343 try { start$1(q); } // let the current task complete
30345 if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
30346 else if (!q._data) throw e; // await callback errored synchronously
30351 function start$1(q) {
30352 while (q._start = q._waiting && q._active < q._size) {
30353 var i = q._ended + q._active,
30358 --q._waiting, ++q._active;
30359 t = c.apply(null, t);
30360 if (!q._tasks[i]) continue; // task finished synchronously
30361 q._tasks[i] = t || noabort;
30365 function end(q, i) {
30366 return function(e, r) {
30367 if (!q._tasks[i]) return; // ignore multiple callbacks
30368 --q._active, ++q._ended;
30369 q._tasks[i] = null;
30370 if (q._error != null) return; // ignore secondary errors
30375 if (q._waiting) poke$1(q);
30376 else maybeNotify(q);
30381 function abort(q, e) {
30382 var i = q._tasks.length, t;
30383 q._error = e; // ignore active callbacks
30384 q._data = undefined; // allow gc
30385 q._waiting = NaN; // prevent starting
30388 if (t = q._tasks[i]) {
30389 q._tasks[i] = null;
30392 catch (e) { /* ignore */ }
30397 q._active = NaN; // allow notification
30401 function maybeNotify(q) {
30402 if (!q._active && q._call) {
30404 q._data = undefined; // allow gc
30405 q._call(q._error, d);
30409 function queue(concurrency) {
30410 return new Queue(arguments.length ? +concurrency : Infinity);
30413 var uniform = function(min, max) {
30414 min = min == null ? 0 : +min;
30415 max = max == null ? 1 : +max;
30416 if (arguments.length === 1) max = min, min = 0;
30418 return function() {
30419 return Math.random() * max + min;
30423 var normal = function(mu, sigma) {
30425 mu = mu == null ? 0 : +mu;
30426 sigma = sigma == null ? 1 : +sigma;
30427 return function() {
30430 // If available, use the second previously-generated uniform random.
30431 if (x != null) y = x, x = null;
30433 // Otherwise, generate a new x and y.
30435 x = Math.random() * 2 - 1;
30436 y = Math.random() * 2 - 1;
30438 } while (!r || r > 1);
30440 return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
30444 var logNormal = function() {
30445 var randomNormal = normal.apply(this, arguments);
30446 return function() {
30447 return Math.exp(randomNormal());
30451 var irwinHall = function(n) {
30452 return function() {
30453 for (var sum = 0, i = 0; i < n; ++i) sum += Math.random();
30458 var bates = function(n) {
30459 var randomIrwinHall = irwinHall(n);
30460 return function() {
30461 return randomIrwinHall() / n;
30465 var exponential$2 = function(lambda) {
30466 return function() {
30467 return -Math.log(1 - Math.random()) / lambda;
30471 var request = function(url, callback) {
30473 event = dispatch("beforesend", "progress", "load", "error"),
30476 xhr = new XMLHttpRequest,
30483 // If IE does not support CORS, use XDomainRequest.
30484 if (typeof XDomainRequest !== "undefined"
30485 && !("withCredentials" in xhr)
30486 && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
30489 ? xhr.onload = xhr.onerror = xhr.ontimeout = respond
30490 : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
30492 function respond(o) {
30493 var status = xhr.status, result;
30494 if (!status && hasResponse(xhr)
30495 || status >= 200 && status < 300
30496 || status === 304) {
30499 result = response.call(request, xhr);
30501 event.call("error", request, e);
30507 event.call("load", request, result);
30509 event.call("error", request, o);
30513 xhr.onprogress = function(e) {
30514 event.call("progress", request, e);
30518 header: function(name, value) {
30519 name = (name + "").toLowerCase();
30520 if (arguments.length < 2) return headers.get(name);
30521 if (value == null) headers.remove(name);
30522 else headers.set(name, value + "");
30526 // If mimeType is non-null and no Accept header is set, a default is used.
30527 mimeType: function(value) {
30528 if (!arguments.length) return mimeType;
30529 mimeType = value == null ? null : value + "";
30533 // Specifies what type the response value should take;
30534 // for instance, arraybuffer, blob, document, or text.
30535 responseType: function(value) {
30536 if (!arguments.length) return responseType;
30537 responseType = value;
30541 timeout: function(value) {
30542 if (!arguments.length) return timeout;
30547 user: function(value) {
30548 return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
30551 password: function(value) {
30552 return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
30555 // Specify how to convert the response content to a specific type;
30556 // changes the callback value on "load" events.
30557 response: function(value) {
30562 // Alias for send("GET", …).
30563 get: function(data, callback) {
30564 return request.send("GET", data, callback);
30567 // Alias for send("POST", …).
30568 post: function(data, callback) {
30569 return request.send("POST", data, callback);
30572 // If callback is non-null, it will be used for error and load events.
30573 send: function(method, data, callback) {
30574 xhr.open(method, url, true, user, password);
30575 if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
30576 if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
30577 if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
30578 if (responseType != null) xhr.responseType = responseType;
30579 if (timeout > 0) xhr.timeout = timeout;
30580 if (callback == null && typeof data === "function") callback = data, data = null;
30581 if (callback != null && callback.length === 1) callback = fixCallback(callback);
30582 if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
30583 event.call("beforesend", request, xhr);
30584 xhr.send(data == null ? null : data);
30588 abort: function() {
30594 var value = event.on.apply(event, arguments);
30595 return value === event ? request : value;
30599 if (callback != null) {
30600 if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
30601 return request.get(callback);
30607 function fixCallback(callback) {
30608 return function(error, xhr) {
30609 callback(error == null ? xhr : null);
30613 function hasResponse(xhr) {
30614 var type = xhr.responseType;
30615 return type && type !== "text"
30616 ? xhr.response // null on error
30617 : xhr.responseText; // "" on error
30620 var type$3 = function(defaultMimeType, response) {
30621 return function(url, callback) {
30622 var r = request(url).mimeType(defaultMimeType).response(response);
30623 if (callback != null) {
30624 if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
30625 return r.get(callback);
30631 var html = type$3("text/html", function(xhr) {
30632 return document.createRange().createContextualFragment(xhr.responseText);
30635 var json = type$3("application/json", function(xhr) {
30636 return JSON.parse(xhr.responseText);
30639 var text = type$3("text/plain", function(xhr) {
30640 return xhr.responseText;
30643 var xml = type$3("application/xml", function(xhr) {
30644 var xml = xhr.responseXML;
30645 if (!xml) throw new Error("parse error");
30649 var dsv$1 = function(defaultMimeType, parse) {
30650 return function(url, row, callback) {
30651 if (arguments.length < 3) callback = row, row = null;
30652 var r = request(url).mimeType(defaultMimeType);
30653 r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
30655 return callback ? r.get(callback) : r;
30659 function responseOf(parse, row) {
30660 return function(request$$1) {
30661 return parse(request$$1.responseText, row);
30665 var csv$1 = dsv$1("text/csv", csvParse);
30667 var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
30669 var array$3 = Array.prototype;
30671 var map$3 = array$3.map;
30672 var slice$4 = array$3.slice;
30674 var implicit = {name: "implicit"};
30676 function ordinal(range) {
30677 var index = map$1(),
30679 unknown = implicit;
30681 range = range == null ? [] : slice$4.call(range);
30683 function scale(d) {
30684 var key = d + "", i = index.get(key);
30686 if (unknown !== implicit) return unknown;
30687 index.set(key, i = domain.push(d));
30689 return range[(i - 1) % range.length];
30692 scale.domain = function(_) {
30693 if (!arguments.length) return domain.slice();
30694 domain = [], index = map$1();
30695 var i = -1, n = _.length, d, key;
30696 while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
30700 scale.range = function(_) {
30701 return arguments.length ? (range = slice$4.call(_), scale) : range.slice();
30704 scale.unknown = function(_) {
30705 return arguments.length ? (unknown = _, scale) : unknown;
30708 scale.copy = function() {
30719 var scale = ordinal().unknown(undefined),
30720 domain = scale.domain,
30721 ordinalRange = scale.range,
30730 delete scale.unknown;
30732 function rescale() {
30733 var n = domain().length,
30734 reverse = range$$1[1] < range$$1[0],
30735 start = range$$1[reverse - 0],
30736 stop = range$$1[1 - reverse];
30737 step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
30738 if (round) step = Math.floor(step);
30739 start += (stop - start - step * (n - paddingInner)) * align;
30740 bandwidth = step * (1 - paddingInner);
30741 if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
30742 var values = sequence(n).map(function(i) { return start + step * i; });
30743 return ordinalRange(reverse ? values.reverse() : values);
30746 scale.domain = function(_) {
30747 return arguments.length ? (domain(_), rescale()) : domain();
30750 scale.range = function(_) {
30751 return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
30754 scale.rangeRound = function(_) {
30755 return range$$1 = [+_[0], +_[1]], round = true, rescale();
30758 scale.bandwidth = function() {
30762 scale.step = function() {
30766 scale.round = function(_) {
30767 return arguments.length ? (round = !!_, rescale()) : round;
30770 scale.padding = function(_) {
30771 return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
30774 scale.paddingInner = function(_) {
30775 return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
30778 scale.paddingOuter = function(_) {
30779 return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
30782 scale.align = function(_) {
30783 return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
30786 scale.copy = function() {
30791 .paddingInner(paddingInner)
30792 .paddingOuter(paddingOuter)
30799 function pointish(scale) {
30800 var copy = scale.copy;
30802 scale.padding = scale.paddingOuter;
30803 delete scale.paddingInner;
30804 delete scale.paddingOuter;
30806 scale.copy = function() {
30807 return pointish(copy());
30813 function point$1() {
30814 return pointish(band().paddingInner(1));
30817 var constant$10 = function(x) {
30818 return function() {
30823 var number$2 = function(x) {
30829 function deinterpolateLinear(a, b) {
30830 return (b -= (a = +a))
30831 ? function(x) { return (x - a) / b; }
30835 function deinterpolateClamp(deinterpolate) {
30836 return function(a, b) {
30837 var d = deinterpolate(a = +a, b = +b);
30838 return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
30842 function reinterpolateClamp(reinterpolate) {
30843 return function(a, b) {
30844 var r = reinterpolate(a = +a, b = +b);
30845 return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
30849 function bimap(domain, range$$1, deinterpolate, reinterpolate) {
30850 var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1];
30851 if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
30852 else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
30853 return function(x) { return r0(d0(x)); };
30856 function polymap(domain, range$$1, deinterpolate, reinterpolate) {
30857 var j = Math.min(domain.length, range$$1.length) - 1,
30862 // Reverse descending domains.
30863 if (domain[j] < domain[0]) {
30864 domain = domain.slice().reverse();
30865 range$$1 = range$$1.slice().reverse();
30869 d[i] = deinterpolate(domain[i], domain[i + 1]);
30870 r[i] = reinterpolate(range$$1[i], range$$1[i + 1]);
30873 return function(x) {
30874 var i = bisectRight(domain, x, 1, j) - 1;
30875 return r[i](d[i](x));
30879 function copy(source, target) {
30881 .domain(source.domain())
30882 .range(source.range())
30883 .interpolate(source.interpolate())
30884 .clamp(source.clamp());
30887 // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
30888 // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
30889 function continuous(deinterpolate, reinterpolate) {
30892 interpolate$$1 = interpolateValue,
30898 function rescale() {
30899 piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap;
30900 output = input = null;
30904 function scale(x) {
30905 return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);
30908 scale.invert = function(y) {
30909 return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
30912 scale.domain = function(_) {
30913 return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();
30916 scale.range = function(_) {
30917 return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice();
30920 scale.rangeRound = function(_) {
30921 return range$$1 = slice$4.call(_), interpolate$$1 = interpolateRound, rescale();
30924 scale.clamp = function(_) {
30925 return arguments.length ? (clamp = !!_, rescale()) : clamp;
30928 scale.interpolate = function(_) {
30929 return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;
30935 var tickFormat = function(domain, count, specifier) {
30936 var start = domain[0],
30937 stop = domain[domain.length - 1],
30938 step = tickStep(start, stop, count == null ? 10 : count),
30940 specifier = formatSpecifier(specifier == null ? ",f" : specifier);
30941 switch (specifier.type) {
30943 var value = Math.max(Math.abs(start), Math.abs(stop));
30944 if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
30945 return formatPrefix(specifier, value);
30952 if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
30957 if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
30961 return format(specifier);
30964 function linearish(scale) {
30965 var domain = scale.domain;
30967 scale.ticks = function(count) {
30969 return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
30972 scale.tickFormat = function(count, specifier) {
30973 return tickFormat(domain(), count, specifier);
30976 scale.nice = function(count) {
30979 n = count == null ? 10 : count,
30982 step = tickStep(start, stop, n);
30985 step = tickStep(Math.floor(start / step) * step, Math.ceil(stop / step) * step, n);
30986 d[0] = Math.floor(start / step) * step;
30987 d[i] = Math.ceil(stop / step) * step;
30997 function linear$3() {
30998 var scale = continuous(deinterpolateLinear, reinterpolate);
31000 scale.copy = function() {
31001 return copy(scale, linear$3());
31004 return linearish(scale);
31007 function identity$7() {
31008 var domain = [0, 1];
31010 function scale(x) {
31014 scale.invert = scale;
31016 scale.domain = scale.range = function(_) {
31017 return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();
31020 scale.copy = function() {
31021 return identity$7().domain(domain);
31024 return linearish(scale);
31027 var nice = function(domain, interval) {
31028 domain = domain.slice();
31031 i1 = domain.length - 1,
31037 t = i0, i0 = i1, i1 = t;
31038 t = x0, x0 = x1, x1 = t;
31041 domain[i0] = interval.floor(x0);
31042 domain[i1] = interval.ceil(x1);
31046 function deinterpolate(a, b) {
31047 return (b = Math.log(b / a))
31048 ? function(x) { return Math.log(x / a) / b; }
31052 function reinterpolate$1(a, b) {
31054 ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
31055 : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
31058 function pow10(x) {
31059 return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
31062 function powp(base) {
31063 return base === 10 ? pow10
31064 : base === Math.E ? Math.exp
31065 : function(x) { return Math.pow(base, x); };
31068 function logp(base) {
31069 return base === Math.E ? Math.log
31070 : base === 10 && Math.log10
31071 || base === 2 && Math.log2
31072 || (base = Math.log(base), function(x) { return Math.log(x) / base; });
31075 function reflect(f) {
31076 return function(x) {
31082 var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]),
31083 domain = scale.domain,
31088 function rescale() {
31089 logs = logp(base), pows = powp(base);
31090 if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
31094 scale.base = function(_) {
31095 return arguments.length ? (base = +_, rescale()) : base;
31098 scale.domain = function(_) {
31099 return arguments.length ? (domain(_), rescale()) : domain();
31102 scale.ticks = function(count) {
31105 v = d[d.length - 1],
31108 if (r = v < u) i = u, u = v, v = i;
31115 n = count == null ? 10 : +count,
31118 if (!(base % 1) && j - i < n) {
31119 i = Math.round(i) - 1, j = Math.round(j) + 1;
31120 if (u > 0) for (; i < j; ++i) {
31121 for (k = 1, p = pows(i); k < base; ++k) {
31123 if (t < u) continue;
31127 } else for (; i < j; ++i) {
31128 for (k = base - 1, p = pows(i); k >= 1; --k) {
31130 if (t < u) continue;
31136 z = ticks(i, j, Math.min(j - i, n)).map(pows);
31139 return r ? z.reverse() : z;
31142 scale.tickFormat = function(count, specifier) {
31143 if (specifier == null) specifier = base === 10 ? ".0e" : ",";
31144 if (typeof specifier !== "function") specifier = format(specifier);
31145 if (count === Infinity) return specifier;
31146 if (count == null) count = 10;
31147 var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
31148 return function(d) {
31149 var i = d / pows(Math.round(logs(d)));
31150 if (i * base < base - 0.5) i *= base;
31151 return i <= k ? specifier(d) : "";
31155 scale.nice = function() {
31156 return domain(nice(domain(), {
31157 floor: function(x) { return pows(Math.floor(logs(x))); },
31158 ceil: function(x) { return pows(Math.ceil(logs(x))); }
31162 scale.copy = function() {
31163 return copy(scale, log$1().base(base));
31169 function raise$1(x, exponent) {
31170 return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
31175 scale = continuous(deinterpolate, reinterpolate),
31176 domain = scale.domain;
31178 function deinterpolate(a, b) {
31179 return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))
31180 ? function(x) { return (raise$1(x, exponent) - a) / b; }
31184 function reinterpolate(a, b) {
31185 b = raise$1(b, exponent) - (a = raise$1(a, exponent));
31186 return function(t) { return raise$1(a + b * t, 1 / exponent); };
31189 scale.exponent = function(_) {
31190 return arguments.length ? (exponent = +_, domain(domain())) : exponent;
31193 scale.copy = function() {
31194 return copy(scale, pow$1().exponent(exponent));
31197 return linearish(scale);
31200 function sqrt$1() {
31201 return pow$1().exponent(0.5);
31204 function quantile$$1() {
31209 function rescale() {
31210 var i = 0, n = Math.max(1, range$$1.length);
31211 thresholds = new Array(n - 1);
31212 while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
31216 function scale(x) {
31217 if (!isNaN(x = +x)) return range$$1[bisectRight(thresholds, x)];
31220 scale.invertExtent = function(y) {
31221 var i = range$$1.indexOf(y);
31222 return i < 0 ? [NaN, NaN] : [
31223 i > 0 ? thresholds[i - 1] : domain[0],
31224 i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
31228 scale.domain = function(_) {
31229 if (!arguments.length) return domain.slice();
31231 for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
31232 domain.sort(ascending);
31236 scale.range = function(_) {
31237 return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice();
31240 scale.quantiles = function() {
31241 return thresholds.slice();
31244 scale.copy = function() {
31245 return quantile$$1()
31253 function quantize$2() {
31260 function scale(x) {
31261 if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
31264 function rescale() {
31266 domain = new Array(n);
31267 while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
31271 scale.domain = function(_) {
31272 return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
31275 scale.range = function(_) {
31276 return arguments.length ? (n = (range$$1 = slice$4.call(_)).length - 1, rescale()) : range$$1.slice();
31279 scale.invertExtent = function(y) {
31280 var i = range$$1.indexOf(y);
31281 return i < 0 ? [NaN, NaN]
31282 : i < 1 ? [x0, domain[0]]
31283 : i >= n ? [domain[n - 1], x1]
31284 : [domain[i - 1], domain[i]];
31287 scale.copy = function() {
31288 return quantize$2()
31293 return linearish(scale);
31296 function threshold$1() {
31297 var domain = [0.5],
31301 function scale(x) {
31302 if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
31305 scale.domain = function(_) {
31306 return arguments.length ? (domain = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice();
31309 scale.range = function(_) {
31310 return arguments.length ? (range$$1 = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice();
31313 scale.invertExtent = function(y) {
31314 var i = range$$1.indexOf(y);
31315 return [domain[i - 1], domain[i]];
31318 scale.copy = function() {
31319 return threshold$1()
31327 var t0$1 = new Date;
31328 var t1$1 = new Date;
31330 function newInterval(floori, offseti, count, field) {
31332 function interval(date) {
31333 return floori(date = new Date(+date)), date;
31336 interval.floor = interval;
31338 interval.ceil = function(date) {
31339 return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
31342 interval.round = function(date) {
31343 var d0 = interval(date),
31344 d1 = interval.ceil(date);
31345 return date - d0 < d1 - date ? d0 : d1;
31348 interval.offset = function(date, step) {
31349 return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
31352 interval.range = function(start, stop, step) {
31354 start = interval.ceil(start);
31355 step = step == null ? 1 : Math.floor(step);
31356 if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
31357 do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop)
31361 interval.filter = function(test) {
31362 return newInterval(function(date) {
31363 if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
31364 }, function(date, step) {
31365 if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty
31370 interval.count = function(start, end) {
31371 t0$1.setTime(+start), t1$1.setTime(+end);
31372 floori(t0$1), floori(t1$1);
31373 return Math.floor(count(t0$1, t1$1));
31376 interval.every = function(step) {
31377 step = Math.floor(step);
31378 return !isFinite(step) || !(step > 0) ? null
31379 : !(step > 1) ? interval
31380 : interval.filter(field
31381 ? function(d) { return field(d) % step === 0; }
31382 : function(d) { return interval.count(0, d) % step === 0; });
31389 var millisecond = newInterval(function() {
31391 }, function(date, step) {
31392 date.setTime(+date + step);
31393 }, function(start, end) {
31394 return end - start;
31397 // An optimized implementation for this simple case.
31398 millisecond.every = function(k) {
31400 if (!isFinite(k) || !(k > 0)) return null;
31401 if (!(k > 1)) return millisecond;
31402 return newInterval(function(date) {
31403 date.setTime(Math.floor(date / k) * k);
31404 }, function(date, step) {
31405 date.setTime(+date + step * k);
31406 }, function(start, end) {
31407 return (end - start) / k;
31411 var milliseconds = millisecond.range;
31413 var durationSecond$1 = 1e3;
31414 var durationMinute$1 = 6e4;
31415 var durationHour$1 = 36e5;
31416 var durationDay$1 = 864e5;
31417 var durationWeek$1 = 6048e5;
31419 var second = newInterval(function(date) {
31420 date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1);
31421 }, function(date, step) {
31422 date.setTime(+date + step * durationSecond$1);
31423 }, function(start, end) {
31424 return (end - start) / durationSecond$1;
31425 }, function(date) {
31426 return date.getUTCSeconds();
31429 var seconds = second.range;
31431 var minute = newInterval(function(date) {
31432 date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1);
31433 }, function(date, step) {
31434 date.setTime(+date + step * durationMinute$1);
31435 }, function(start, end) {
31436 return (end - start) / durationMinute$1;
31437 }, function(date) {
31438 return date.getMinutes();
31441 var minutes = minute.range;
31443 var hour = newInterval(function(date) {
31444 var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1;
31445 if (offset < 0) offset += durationHour$1;
31446 date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset);
31447 }, function(date, step) {
31448 date.setTime(+date + step * durationHour$1);
31449 }, function(start, end) {
31450 return (end - start) / durationHour$1;
31451 }, function(date) {
31452 return date.getHours();
31455 var hours = hour.range;
31457 var day = newInterval(function(date) {
31458 date.setHours(0, 0, 0, 0);
31459 }, function(date, step) {
31460 date.setDate(date.getDate() + step);
31461 }, function(start, end) {
31462 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1;
31463 }, function(date) {
31464 return date.getDate() - 1;
31467 var days = day.range;
31469 function weekday(i) {
31470 return newInterval(function(date) {
31471 date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
31472 date.setHours(0, 0, 0, 0);
31473 }, function(date, step) {
31474 date.setDate(date.getDate() + step * 7);
31475 }, function(start, end) {
31476 return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1;
31480 var sunday = weekday(0);
31481 var monday = weekday(1);
31482 var tuesday = weekday(2);
31483 var wednesday = weekday(3);
31484 var thursday = weekday(4);
31485 var friday = weekday(5);
31486 var saturday = weekday(6);
31488 var sundays = sunday.range;
31489 var mondays = monday.range;
31490 var tuesdays = tuesday.range;
31491 var wednesdays = wednesday.range;
31492 var thursdays = thursday.range;
31493 var fridays = friday.range;
31494 var saturdays = saturday.range;
31496 var month = newInterval(function(date) {
31498 date.setHours(0, 0, 0, 0);
31499 }, function(date, step) {
31500 date.setMonth(date.getMonth() + step);
31501 }, function(start, end) {
31502 return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
31503 }, function(date) {
31504 return date.getMonth();
31507 var months = month.range;
31509 var year = newInterval(function(date) {
31510 date.setMonth(0, 1);
31511 date.setHours(0, 0, 0, 0);
31512 }, function(date, step) {
31513 date.setFullYear(date.getFullYear() + step);
31514 }, function(start, end) {
31515 return end.getFullYear() - start.getFullYear();
31516 }, function(date) {
31517 return date.getFullYear();
31520 // An optimized implementation for this simple case.
31521 year.every = function(k) {
31522 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
31523 date.setFullYear(Math.floor(date.getFullYear() / k) * k);
31524 date.setMonth(0, 1);
31525 date.setHours(0, 0, 0, 0);
31526 }, function(date, step) {
31527 date.setFullYear(date.getFullYear() + step * k);
31531 var years = year.range;
31533 var utcMinute = newInterval(function(date) {
31534 date.setUTCSeconds(0, 0);
31535 }, function(date, step) {
31536 date.setTime(+date + step * durationMinute$1);
31537 }, function(start, end) {
31538 return (end - start) / durationMinute$1;
31539 }, function(date) {
31540 return date.getUTCMinutes();
31543 var utcMinutes = utcMinute.range;
31545 var utcHour = newInterval(function(date) {
31546 date.setUTCMinutes(0, 0, 0);
31547 }, function(date, step) {
31548 date.setTime(+date + step * durationHour$1);
31549 }, function(start, end) {
31550 return (end - start) / durationHour$1;
31551 }, function(date) {
31552 return date.getUTCHours();
31555 var utcHours = utcHour.range;
31557 var utcDay = newInterval(function(date) {
31558 date.setUTCHours(0, 0, 0, 0);
31559 }, function(date, step) {
31560 date.setUTCDate(date.getUTCDate() + step);
31561 }, function(start, end) {
31562 return (end - start) / durationDay$1;
31563 }, function(date) {
31564 return date.getUTCDate() - 1;
31567 var utcDays = utcDay.range;
31569 function utcWeekday(i) {
31570 return newInterval(function(date) {
31571 date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
31572 date.setUTCHours(0, 0, 0, 0);
31573 }, function(date, step) {
31574 date.setUTCDate(date.getUTCDate() + step * 7);
31575 }, function(start, end) {
31576 return (end - start) / durationWeek$1;
31580 var utcSunday = utcWeekday(0);
31581 var utcMonday = utcWeekday(1);
31582 var utcTuesday = utcWeekday(2);
31583 var utcWednesday = utcWeekday(3);
31584 var utcThursday = utcWeekday(4);
31585 var utcFriday = utcWeekday(5);
31586 var utcSaturday = utcWeekday(6);
31588 var utcSundays = utcSunday.range;
31589 var utcMondays = utcMonday.range;
31590 var utcTuesdays = utcTuesday.range;
31591 var utcWednesdays = utcWednesday.range;
31592 var utcThursdays = utcThursday.range;
31593 var utcFridays = utcFriday.range;
31594 var utcSaturdays = utcSaturday.range;
31596 var utcMonth = newInterval(function(date) {
31597 date.setUTCDate(1);
31598 date.setUTCHours(0, 0, 0, 0);
31599 }, function(date, step) {
31600 date.setUTCMonth(date.getUTCMonth() + step);
31601 }, function(start, end) {
31602 return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
31603 }, function(date) {
31604 return date.getUTCMonth();
31607 var utcMonths = utcMonth.range;
31609 var utcYear = newInterval(function(date) {
31610 date.setUTCMonth(0, 1);
31611 date.setUTCHours(0, 0, 0, 0);
31612 }, function(date, step) {
31613 date.setUTCFullYear(date.getUTCFullYear() + step);
31614 }, function(start, end) {
31615 return end.getUTCFullYear() - start.getUTCFullYear();
31616 }, function(date) {
31617 return date.getUTCFullYear();
31620 // An optimized implementation for this simple case.
31621 utcYear.every = function(k) {
31622 return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
31623 date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
31624 date.setUTCMonth(0, 1);
31625 date.setUTCHours(0, 0, 0, 0);
31626 }, function(date, step) {
31627 date.setUTCFullYear(date.getUTCFullYear() + step * k);
31631 var utcYears = utcYear.range;
31633 function localDate(d) {
31634 if (0 <= d.y && d.y < 100) {
31635 var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
31636 date.setFullYear(d.y);
31639 return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
31642 function utcDate(d) {
31643 if (0 <= d.y && d.y < 100) {
31644 var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
31645 date.setUTCFullYear(d.y);
31648 return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
31651 function newYear(y) {
31652 return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
31655 function formatLocale$1(locale) {
31656 var locale_dateTime = locale.dateTime,
31657 locale_date = locale.date,
31658 locale_time = locale.time,
31659 locale_periods = locale.periods,
31660 locale_weekdays = locale.days,
31661 locale_shortWeekdays = locale.shortDays,
31662 locale_months = locale.months,
31663 locale_shortMonths = locale.shortMonths;
31665 var periodRe = formatRe(locale_periods),
31666 periodLookup = formatLookup(locale_periods),
31667 weekdayRe = formatRe(locale_weekdays),
31668 weekdayLookup = formatLookup(locale_weekdays),
31669 shortWeekdayRe = formatRe(locale_shortWeekdays),
31670 shortWeekdayLookup = formatLookup(locale_shortWeekdays),
31671 monthRe = formatRe(locale_months),
31672 monthLookup = formatLookup(locale_months),
31673 shortMonthRe = formatRe(locale_shortMonths),
31674 shortMonthLookup = formatLookup(locale_shortMonths);
31677 "a": formatShortWeekday,
31678 "A": formatWeekday,
31679 "b": formatShortMonth,
31682 "d": formatDayOfMonth,
31683 "e": formatDayOfMonth,
31686 "j": formatDayOfYear,
31687 "L": formatMilliseconds,
31688 "m": formatMonthNumber,
31689 "M": formatMinutes,
31691 "S": formatSeconds,
31692 "U": formatWeekNumberSunday,
31693 "w": formatWeekdayNumber,
31694 "W": formatWeekNumberMonday,
31698 "Y": formatFullYear,
31700 "%": formatLiteralPercent
31704 "a": formatUTCShortWeekday,
31705 "A": formatUTCWeekday,
31706 "b": formatUTCShortMonth,
31707 "B": formatUTCMonth,
31709 "d": formatUTCDayOfMonth,
31710 "e": formatUTCDayOfMonth,
31711 "H": formatUTCHour24,
31712 "I": formatUTCHour12,
31713 "j": formatUTCDayOfYear,
31714 "L": formatUTCMilliseconds,
31715 "m": formatUTCMonthNumber,
31716 "M": formatUTCMinutes,
31717 "p": formatUTCPeriod,
31718 "S": formatUTCSeconds,
31719 "U": formatUTCWeekNumberSunday,
31720 "w": formatUTCWeekdayNumber,
31721 "W": formatUTCWeekNumberMonday,
31724 "y": formatUTCYear,
31725 "Y": formatUTCFullYear,
31726 "Z": formatUTCZone,
31727 "%": formatLiteralPercent
31731 "a": parseShortWeekday,
31733 "b": parseShortMonth,
31735 "c": parseLocaleDateTime,
31736 "d": parseDayOfMonth,
31737 "e": parseDayOfMonth,
31740 "j": parseDayOfYear,
31741 "L": parseMilliseconds,
31742 "m": parseMonthNumber,
31746 "U": parseWeekNumberSunday,
31747 "w": parseWeekdayNumber,
31748 "W": parseWeekNumberMonday,
31749 "x": parseLocaleDate,
31750 "X": parseLocaleTime,
31752 "Y": parseFullYear,
31754 "%": parseLiteralPercent
31757 // These recursive directive definitions must be deferred.
31758 formats.x = newFormat(locale_date, formats);
31759 formats.X = newFormat(locale_time, formats);
31760 formats.c = newFormat(locale_dateTime, formats);
31761 utcFormats.x = newFormat(locale_date, utcFormats);
31762 utcFormats.X = newFormat(locale_time, utcFormats);
31763 utcFormats.c = newFormat(locale_dateTime, utcFormats);
31765 function newFormat(specifier, formats) {
31766 return function(date) {
31770 n = specifier.length,
31775 if (!(date instanceof Date)) date = new Date(+date);
31778 if (specifier.charCodeAt(i) === 37) {
31779 string.push(specifier.slice(j, i));
31780 if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
31781 else pad = c === "e" ? " " : "0";
31782 if (format = formats[c]) c = format(date, pad);
31788 string.push(specifier.slice(j, i));
31789 return string.join("");
31793 function newParse(specifier, newDate) {
31794 return function(string) {
31795 var d = newYear(1900),
31796 i = parseSpecifier(d, specifier, string += "", 0);
31797 if (i != string.length) return null;
31799 // The am-pm flag is 0 for AM, and 1 for PM.
31800 if ("p" in d) d.H = d.H % 12 + d.p * 12;
31802 // Convert day-of-week and week-of-year to day-of-year.
31803 if ("W" in d || "U" in d) {
31804 if (!("w" in d)) d.w = "W" in d ? 1 : 0;
31805 var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
31807 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;
31810 // If a time zone is specified, all fields are interpreted as UTC and then
31811 // offset according to the specified time zone.
31813 d.H += d.Z / 100 | 0;
31818 // Otherwise, all fields are in local time.
31823 function parseSpecifier(d, specifier, string, j) {
31825 n = specifier.length,
31831 if (j >= m) return -1;
31832 c = specifier.charCodeAt(i++);
31834 c = specifier.charAt(i++);
31835 parse = parses[c in pads ? specifier.charAt(i++) : c];
31836 if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
31837 } else if (c != string.charCodeAt(j++)) {
31845 function parsePeriod(d, string, i) {
31846 var n = periodRe.exec(string.slice(i));
31847 return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31850 function parseShortWeekday(d, string, i) {
31851 var n = shortWeekdayRe.exec(string.slice(i));
31852 return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31855 function parseWeekday(d, string, i) {
31856 var n = weekdayRe.exec(string.slice(i));
31857 return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31860 function parseShortMonth(d, string, i) {
31861 var n = shortMonthRe.exec(string.slice(i));
31862 return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31865 function parseMonth(d, string, i) {
31866 var n = monthRe.exec(string.slice(i));
31867 return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
31870 function parseLocaleDateTime(d, string, i) {
31871 return parseSpecifier(d, locale_dateTime, string, i);
31874 function parseLocaleDate(d, string, i) {
31875 return parseSpecifier(d, locale_date, string, i);
31878 function parseLocaleTime(d, string, i) {
31879 return parseSpecifier(d, locale_time, string, i);
31882 function formatShortWeekday(d) {
31883 return locale_shortWeekdays[d.getDay()];
31886 function formatWeekday(d) {
31887 return locale_weekdays[d.getDay()];
31890 function formatShortMonth(d) {
31891 return locale_shortMonths[d.getMonth()];
31894 function formatMonth(d) {
31895 return locale_months[d.getMonth()];
31898 function formatPeriod(d) {
31899 return locale_periods[+(d.getHours() >= 12)];
31902 function formatUTCShortWeekday(d) {
31903 return locale_shortWeekdays[d.getUTCDay()];
31906 function formatUTCWeekday(d) {
31907 return locale_weekdays[d.getUTCDay()];
31910 function formatUTCShortMonth(d) {
31911 return locale_shortMonths[d.getUTCMonth()];
31914 function formatUTCMonth(d) {
31915 return locale_months[d.getUTCMonth()];
31918 function formatUTCPeriod(d) {
31919 return locale_periods[+(d.getUTCHours() >= 12)];
31923 format: function(specifier) {
31924 var f = newFormat(specifier += "", formats);
31925 f.toString = function() { return specifier; };
31928 parse: function(specifier) {
31929 var p = newParse(specifier += "", localDate);
31930 p.toString = function() { return specifier; };
31933 utcFormat: function(specifier) {
31934 var f = newFormat(specifier += "", utcFormats);
31935 f.toString = function() { return specifier; };
31938 utcParse: function(specifier) {
31939 var p = newParse(specifier, utcDate);
31940 p.toString = function() { return specifier; };
31946 var pads = {"-": "", "_": " ", "0": "0"};
31947 var numberRe = /^\s*\d+/;
31948 var percentRe = /^%/;
31949 var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
31951 function pad(value, fill, width) {
31952 var sign = value < 0 ? "-" : "",
31953 string = (sign ? -value : value) + "",
31954 length = string.length;
31955 return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
31958 function requote(s) {
31959 return s.replace(requoteRe, "\\$&");
31962 function formatRe(names) {
31963 return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
31966 function formatLookup(names) {
31967 var map = {}, i = -1, n = names.length;
31968 while (++i < n) map[names[i].toLowerCase()] = i;
31972 function parseWeekdayNumber(d, string, i) {
31973 var n = numberRe.exec(string.slice(i, i + 1));
31974 return n ? (d.w = +n[0], i + n[0].length) : -1;
31977 function parseWeekNumberSunday(d, string, i) {
31978 var n = numberRe.exec(string.slice(i));
31979 return n ? (d.U = +n[0], i + n[0].length) : -1;
31982 function parseWeekNumberMonday(d, string, i) {
31983 var n = numberRe.exec(string.slice(i));
31984 return n ? (d.W = +n[0], i + n[0].length) : -1;
31987 function parseFullYear(d, string, i) {
31988 var n = numberRe.exec(string.slice(i, i + 4));
31989 return n ? (d.y = +n[0], i + n[0].length) : -1;
31992 function parseYear(d, string, i) {
31993 var n = numberRe.exec(string.slice(i, i + 2));
31994 return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
31997 function parseZone(d, string, i) {
31998 var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6));
31999 return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
32002 function parseMonthNumber(d, string, i) {
32003 var n = numberRe.exec(string.slice(i, i + 2));
32004 return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
32007 function parseDayOfMonth(d, string, i) {
32008 var n = numberRe.exec(string.slice(i, i + 2));
32009 return n ? (d.d = +n[0], i + n[0].length) : -1;
32012 function parseDayOfYear(d, string, i) {
32013 var n = numberRe.exec(string.slice(i, i + 3));
32014 return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
32017 function parseHour24(d, string, i) {
32018 var n = numberRe.exec(string.slice(i, i + 2));
32019 return n ? (d.H = +n[0], i + n[0].length) : -1;
32022 function parseMinutes(d, string, i) {
32023 var n = numberRe.exec(string.slice(i, i + 2));
32024 return n ? (d.M = +n[0], i + n[0].length) : -1;
32027 function parseSeconds(d, string, i) {
32028 var n = numberRe.exec(string.slice(i, i + 2));
32029 return n ? (d.S = +n[0], i + n[0].length) : -1;
32032 function parseMilliseconds(d, string, i) {
32033 var n = numberRe.exec(string.slice(i, i + 3));
32034 return n ? (d.L = +n[0], i + n[0].length) : -1;
32037 function parseLiteralPercent(d, string, i) {
32038 var n = percentRe.exec(string.slice(i, i + 1));
32039 return n ? i + n[0].length : -1;
32042 function formatDayOfMonth(d, p) {
32043 return pad(d.getDate(), p, 2);
32046 function formatHour24(d, p) {
32047 return pad(d.getHours(), p, 2);
32050 function formatHour12(d, p) {
32051 return pad(d.getHours() % 12 || 12, p, 2);
32054 function formatDayOfYear(d, p) {
32055 return pad(1 + day.count(year(d), d), p, 3);
32058 function formatMilliseconds(d, p) {
32059 return pad(d.getMilliseconds(), p, 3);
32062 function formatMonthNumber(d, p) {
32063 return pad(d.getMonth() + 1, p, 2);
32066 function formatMinutes(d, p) {
32067 return pad(d.getMinutes(), p, 2);
32070 function formatSeconds(d, p) {
32071 return pad(d.getSeconds(), p, 2);
32074 function formatWeekNumberSunday(d, p) {
32075 return pad(sunday.count(year(d), d), p, 2);
32078 function formatWeekdayNumber(d) {
32082 function formatWeekNumberMonday(d, p) {
32083 return pad(monday.count(year(d), d), p, 2);
32086 function formatYear(d, p) {
32087 return pad(d.getFullYear() % 100, p, 2);
32090 function formatFullYear(d, p) {
32091 return pad(d.getFullYear() % 10000, p, 4);
32094 function formatZone(d) {
32095 var z = d.getTimezoneOffset();
32096 return (z > 0 ? "-" : (z *= -1, "+"))
32097 + pad(z / 60 | 0, "0", 2)
32098 + pad(z % 60, "0", 2);
32101 function formatUTCDayOfMonth(d, p) {
32102 return pad(d.getUTCDate(), p, 2);
32105 function formatUTCHour24(d, p) {
32106 return pad(d.getUTCHours(), p, 2);
32109 function formatUTCHour12(d, p) {
32110 return pad(d.getUTCHours() % 12 || 12, p, 2);
32113 function formatUTCDayOfYear(d, p) {
32114 return pad(1 + utcDay.count(utcYear(d), d), p, 3);
32117 function formatUTCMilliseconds(d, p) {
32118 return pad(d.getUTCMilliseconds(), p, 3);
32121 function formatUTCMonthNumber(d, p) {
32122 return pad(d.getUTCMonth() + 1, p, 2);
32125 function formatUTCMinutes(d, p) {
32126 return pad(d.getUTCMinutes(), p, 2);
32129 function formatUTCSeconds(d, p) {
32130 return pad(d.getUTCSeconds(), p, 2);
32133 function formatUTCWeekNumberSunday(d, p) {
32134 return pad(utcSunday.count(utcYear(d), d), p, 2);
32137 function formatUTCWeekdayNumber(d) {
32138 return d.getUTCDay();
32141 function formatUTCWeekNumberMonday(d, p) {
32142 return pad(utcMonday.count(utcYear(d), d), p, 2);
32145 function formatUTCYear(d, p) {
32146 return pad(d.getUTCFullYear() % 100, p, 2);
32149 function formatUTCFullYear(d, p) {
32150 return pad(d.getUTCFullYear() % 10000, p, 4);
32153 function formatUTCZone() {
32157 function formatLiteralPercent() {
32168 dateTime: "%x, %X",
32169 date: "%-m/%-d/%Y",
32170 time: "%-I:%M:%S %p",
32171 periods: ["AM", "PM"],
32172 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
32173 shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
32174 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
32175 shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
32178 function defaultLocale$1(definition) {
32179 locale$2 = formatLocale$1(definition);
32180 timeFormat = locale$2.format;
32181 timeParse = locale$2.parse;
32182 utcFormat = locale$2.utcFormat;
32183 utcParse = locale$2.utcParse;
32187 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
32189 function formatIsoNative(date) {
32190 return date.toISOString();
32193 var formatIso = Date.prototype.toISOString
32195 : utcFormat(isoSpecifier);
32197 function parseIsoNative(string) {
32198 var date = new Date(string);
32199 return isNaN(date) ? null : date;
32202 var parseIso = +new Date("2000-01-01T00:00:00.000Z")
32204 : utcParse(isoSpecifier);
32206 var durationSecond = 1000;
32207 var durationMinute = durationSecond * 60;
32208 var durationHour = durationMinute * 60;
32209 var durationDay = durationHour * 24;
32210 var durationWeek = durationDay * 7;
32211 var durationMonth = durationDay * 30;
32212 var durationYear = durationDay * 365;
32214 function date$2(t) {
32215 return new Date(t);
32218 function number$3(t) {
32219 return t instanceof Date ? +t : +new Date(+t);
32222 function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
32223 var scale = continuous(deinterpolateLinear, reinterpolate),
32224 invert = scale.invert,
32225 domain = scale.domain;
32227 var formatMillisecond = format(".%L"),
32228 formatSecond = format(":%S"),
32229 formatMinute = format("%I:%M"),
32230 formatHour = format("%I %p"),
32231 formatDay = format("%a %d"),
32232 formatWeek = format("%b %d"),
32233 formatMonth = format("%B"),
32234 formatYear = format("%Y");
32236 var tickIntervals = [
32237 [second$$1, 1, durationSecond],
32238 [second$$1, 5, 5 * durationSecond],
32239 [second$$1, 15, 15 * durationSecond],
32240 [second$$1, 30, 30 * durationSecond],
32241 [minute$$1, 1, durationMinute],
32242 [minute$$1, 5, 5 * durationMinute],
32243 [minute$$1, 15, 15 * durationMinute],
32244 [minute$$1, 30, 30 * durationMinute],
32245 [ hour$$1, 1, durationHour ],
32246 [ hour$$1, 3, 3 * durationHour ],
32247 [ hour$$1, 6, 6 * durationHour ],
32248 [ hour$$1, 12, 12 * durationHour ],
32249 [ day$$1, 1, durationDay ],
32250 [ day$$1, 2, 2 * durationDay ],
32251 [ week, 1, durationWeek ],
32252 [ month$$1, 1, durationMonth ],
32253 [ month$$1, 3, 3 * durationMonth ],
32254 [ year$$1, 1, durationYear ]
32257 function tickFormat(date) {
32258 return (second$$1(date) < date ? formatMillisecond
32259 : minute$$1(date) < date ? formatSecond
32260 : hour$$1(date) < date ? formatMinute
32261 : day$$1(date) < date ? formatHour
32262 : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)
32263 : year$$1(date) < date ? formatMonth
32264 : formatYear)(date);
32267 function tickInterval(interval, start, stop, step) {
32268 if (interval == null) interval = 10;
32270 // If a desired tick count is specified, pick a reasonable tick interval
32271 // based on the extent of the domain and a rough estimate of tick size.
32272 // Otherwise, assume interval is already a time interval and use it.
32273 if (typeof interval === "number") {
32274 var target = Math.abs(stop - start) / interval,
32275 i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);
32276 if (i === tickIntervals.length) {
32277 step = tickStep(start / durationYear, stop / durationYear, interval);
32278 interval = year$$1;
32280 i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
32284 step = tickStep(start, stop, interval);
32285 interval = millisecond$$1;
32289 return step == null ? interval : interval.every(step);
32292 scale.invert = function(y) {
32293 return new Date(invert(y));
32296 scale.domain = function(_) {
32297 return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$2);
32300 scale.ticks = function(interval, step) {
32303 t1 = d[d.length - 1],
32306 if (r) t = t0, t0 = t1, t1 = t;
32307 t = tickInterval(interval, t0, t1, step);
32308 t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
32309 return r ? t.reverse() : t;
32312 scale.tickFormat = function(count, specifier) {
32313 return specifier == null ? tickFormat : format(specifier);
32316 scale.nice = function(interval, step) {
32318 return (interval = tickInterval(interval, d[0], d[d.length - 1], step))
32319 ? domain(nice(d, interval))
32323 scale.copy = function() {
32324 return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
32330 var time = function() {
32331 return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
32334 var utcTime = function() {
32335 return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
32338 var colors = function(s) {
32339 return s.match(/.{6}/g).map(function(x) {
32344 var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
32346 var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
32348 var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
32350 var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
32352 var cubehelix$5 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
32354 var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
32356 var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
32358 var rainbow = cubehelix();
32360 var rainbow$1 = function(t) {
32361 if (t < 0 || t > 1) t -= Math.floor(t);
32362 var ts = Math.abs(t - 0.5);
32363 rainbow.h = 360 * t - 100;
32364 rainbow.s = 1.5 - 1.5 * ts;
32365 rainbow.l = 0.8 - 0.9 * ts;
32366 return rainbow + "";
32369 function ramp(range) {
32370 var n = range.length;
32371 return function(t) {
32372 return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
32376 var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
32378 var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
32380 var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
32382 var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
32384 function sequential(interpolator) {
32389 function scale(x) {
32390 var t = (x - x0) / (x1 - x0);
32391 return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
32394 scale.domain = function(_) {
32395 return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
32398 scale.clamp = function(_) {
32399 return arguments.length ? (clamp = !!_, scale) : clamp;
32402 scale.interpolator = function(_) {
32403 return arguments.length ? (interpolator = _, scale) : interpolator;
32406 scale.copy = function() {
32407 return sequential(interpolator).domain([x0, x1]).clamp(clamp);
32410 return linearish(scale);
32413 var constant$11 = function(x) {
32414 return function constant() {
32419 var epsilon$3 = 1e-12;
32420 var pi$4 = Math.PI;
32421 var halfPi$3 = pi$4 / 2;
32422 var tau$4 = 2 * pi$4;
32424 function arcInnerRadius(d) {
32425 return d.innerRadius;
32428 function arcOuterRadius(d) {
32429 return d.outerRadius;
32432 function arcStartAngle(d) {
32433 return d.startAngle;
32436 function arcEndAngle(d) {
32440 function arcPadAngle(d) {
32441 return d && d.padAngle; // Note: optional!
32444 function asin$1(x) {
32445 return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);
32448 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
32449 var x10 = x1 - x0, y10 = y1 - y0,
32450 x32 = x3 - x2, y32 = y3 - y2,
32451 t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
32452 return [x0 + t * x10, y0 + t * y10];
32455 // Compute perpendicular offset line of length rc.
32456 // http://mathworld.wolfram.com/Circle-LineIntersection.html
32457 function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
32460 lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01),
32467 x00 = (x11 + x10) / 2,
32468 y00 = (y11 + y10) / 2,
32471 d2 = dx * dx + dy * dy,
32473 D = x11 * y10 - x10 * y11,
32474 d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)),
32475 cx0 = (D * dy - dx * d) / d2,
32476 cy0 = (-D * dx - dy * d) / d2,
32477 cx1 = (D * dy + dx * d) / d2,
32478 cy1 = (-D * dx + dy * d) / d2,
32484 // Pick the closer of the two intersection points.
32485 // TODO Is there a faster way to determine which intersection to use?
32486 if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
32493 x11: cx0 * (r1 / r - 1),
32494 y11: cy0 * (r1 / r - 1)
32498 var arc = function() {
32499 var innerRadius = arcInnerRadius,
32500 outerRadius = arcOuterRadius,
32501 cornerRadius = constant$11(0),
32503 startAngle = arcStartAngle,
32504 endAngle = arcEndAngle,
32505 padAngle = arcPadAngle,
32511 r0 = +innerRadius.apply(this, arguments),
32512 r1 = +outerRadius.apply(this, arguments),
32513 a0 = startAngle.apply(this, arguments) - halfPi$3,
32514 a1 = endAngle.apply(this, arguments) - halfPi$3,
32515 da = Math.abs(a1 - a0),
32518 if (!context) context = buffer = path();
32520 // Ensure that the outer radius is always larger than the inner radius.
32521 if (r1 < r0) r = r1, r1 = r0, r0 = r;
32524 if (!(r1 > epsilon$3)) context.moveTo(0, 0);
32526 // Or is it a circle or annulus?
32527 else if (da > tau$4 - epsilon$3) {
32528 context.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0));
32529 context.arc(0, 0, r1, a0, a1, !cw);
32530 if (r0 > epsilon$3) {
32531 context.moveTo(r0 * Math.cos(a1), r0 * Math.sin(a1));
32532 context.arc(0, 0, r0, a1, a0, cw);
32536 // Or is it a circular or annular sector?
32544 ap = padAngle.apply(this, arguments) / 2,
32545 rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)),
32546 rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
32552 // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
32553 if (rp > epsilon$3) {
32554 var p0 = asin$1(rp / r0 * Math.sin(ap)),
32555 p1 = asin$1(rp / r1 * Math.sin(ap));
32556 if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
32557 else da0 = 0, a00 = a10 = (a0 + a1) / 2;
32558 if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
32559 else da1 = 0, a01 = a11 = (a0 + a1) / 2;
32562 var x01 = r1 * Math.cos(a01),
32563 y01 = r1 * Math.sin(a01),
32564 x10 = r0 * Math.cos(a10),
32565 y10 = r0 * Math.sin(a10);
32567 // Apply rounded corners?
32568 if (rc > epsilon$3) {
32569 var x11 = r1 * Math.cos(a11),
32570 y11 = r1 * Math.sin(a11),
32571 x00 = r0 * Math.cos(a00),
32572 y00 = r0 * Math.sin(a00);
32574 // Restrict the corner radius according to the sector angle.
32576 var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
32581 kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2),
32582 lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
32583 rc0 = Math.min(rc, (r0 - lc) / (kc - 1));
32584 rc1 = Math.min(rc, (r1 - lc) / (kc + 1));
32588 // Is the sector collapsed to a line?
32589 if (!(da1 > epsilon$3)) context.moveTo(x01, y01);
32591 // Does the sector’s outer ring have rounded corners?
32592 else if (rc1 > epsilon$3) {
32593 t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
32594 t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
32596 context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
32598 // Have the corners merged?
32599 if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
32601 // Otherwise, draw the two corners and the ring.
32603 context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
32604 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);
32605 context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
32609 // Or is the outer ring just a circular arc?
32610 else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
32612 // Is there no inner ring, and it’s a circular sector?
32613 // Or perhaps it’s an annular sector collapsed due to padding?
32614 if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);
32616 // Does the sector’s inner ring (or point) have rounded corners?
32617 else if (rc0 > epsilon$3) {
32618 t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
32619 t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
32621 context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
32623 // Have the corners merged?
32624 if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw);
32626 // Otherwise, draw the two corners and the ring.
32628 context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
32629 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);
32630 context.arc(t1.cx, t1.cy, rc0, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
32634 // Or is the inner ring just a circular arc?
32635 else context.arc(0, 0, r0, a10, a00, cw);
32638 context.closePath();
32640 if (buffer) return context = null, buffer + "" || null;
32643 arc.centroid = function() {
32644 var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
32645 a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;
32646 return [Math.cos(a) * r, Math.sin(a) * r];
32649 arc.innerRadius = function(_) {
32650 return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$11(+_), arc) : innerRadius;
32653 arc.outerRadius = function(_) {
32654 return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$11(+_), arc) : outerRadius;
32657 arc.cornerRadius = function(_) {
32658 return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$11(+_), arc) : cornerRadius;
32661 arc.padRadius = function(_) {
32662 return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$11(+_), arc) : padRadius;
32665 arc.startAngle = function(_) {
32666 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$11(+_), arc) : startAngle;
32669 arc.endAngle = function(_) {
32670 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$11(+_), arc) : endAngle;
32673 arc.padAngle = function(_) {
32674 return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$11(+_), arc) : padAngle;
32677 arc.context = function(_) {
32678 return arguments.length ? ((context = _ == null ? null : _), arc) : context;
32684 function Linear(context) {
32685 this._context = context;
32688 Linear.prototype = {
32689 areaStart: function() {
32692 areaEnd: function() {
32695 lineStart: function() {
32698 lineEnd: function() {
32699 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
32700 this._line = 1 - this._line;
32702 point: function(x, y) {
32704 switch (this._point) {
32705 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
32706 case 1: this._point = 2; // proceed
32707 default: this._context.lineTo(x, y); break;
32712 var curveLinear = function(context) {
32713 return new Linear(context);
32724 var line = function() {
32727 defined = constant$11(true),
32729 curve = curveLinear,
32732 function line(data) {
32739 if (context == null) output = curve(buffer = path());
32741 for (i = 0; i <= n; ++i) {
32742 if (!(i < n && defined(d = data[i], i, data)) === defined0) {
32743 if (defined0 = !defined0) output.lineStart();
32744 else output.lineEnd();
32746 if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
32749 if (buffer) return output = null, buffer + "" || null;
32752 line.x = function(_) {
32753 return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), line) : x$$1;
32756 line.y = function(_) {
32757 return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), line) : y$$1;
32760 line.defined = function(_) {
32761 return arguments.length ? (defined = typeof _ === "function" ? _ : constant$11(!!_), line) : defined;
32764 line.curve = function(_) {
32765 return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
32768 line.context = function(_) {
32769 return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
32775 var area$1 = function() {
32778 y0 = constant$11(0),
32780 defined = constant$11(true),
32782 curve = curveLinear,
32785 function area(data) {
32793 x0z = new Array(n),
32794 y0z = new Array(n);
32796 if (context == null) output = curve(buffer = path());
32798 for (i = 0; i <= n; ++i) {
32799 if (!(i < n && defined(d = data[i], i, data)) === defined0) {
32800 if (defined0 = !defined0) {
32802 output.areaStart();
32803 output.lineStart();
32806 output.lineStart();
32807 for (k = i - 1; k >= j; --k) {
32808 output.point(x0z[k], y0z[k]);
32815 x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
32816 output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
32820 if (buffer) return output = null, buffer + "" || null;
32823 function arealine() {
32824 return line().defined(defined).curve(curve).context(context);
32827 area.x = function(_) {
32828 return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$11(+_), x1 = null, area) : x0;
32831 area.x0 = function(_) {
32832 return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$11(+_), area) : x0;
32835 area.x1 = function(_) {
32836 return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$11(+_), area) : x1;
32839 area.y = function(_) {
32840 return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$11(+_), y1 = null, area) : y0;
32843 area.y0 = function(_) {
32844 return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$11(+_), area) : y0;
32847 area.y1 = function(_) {
32848 return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$11(+_), area) : y1;
32852 area.lineY0 = function() {
32853 return arealine().x(x0).y(y0);
32856 area.lineY1 = function() {
32857 return arealine().x(x0).y(y1);
32860 area.lineX1 = function() {
32861 return arealine().x(x1).y(y0);
32864 area.defined = function(_) {
32865 return arguments.length ? (defined = typeof _ === "function" ? _ : constant$11(!!_), area) : defined;
32868 area.curve = function(_) {
32869 return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
32872 area.context = function(_) {
32873 return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
32879 var descending$1 = function(a, b) {
32880 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
32883 var identity$8 = function(d) {
32887 var pie = function() {
32888 var value = identity$8,
32889 sortValues = descending$1,
32891 startAngle = constant$11(0),
32892 endAngle = constant$11(tau$4),
32893 padAngle = constant$11(0);
32895 function pie(data) {
32901 index = new Array(n),
32902 arcs = new Array(n),
32903 a0 = +startAngle.apply(this, arguments),
32904 da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),
32906 p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
32907 pa = p * (da < 0 ? -1 : 1),
32910 for (i = 0; i < n; ++i) {
32911 if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
32916 // Optionally sort the arcs by previously-computed values or by data.
32917 if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
32918 else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
32920 // Compute the arcs! They are stored in the original data's order.
32921 for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
32922 j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
32935 pie.value = function(_) {
32936 return arguments.length ? (value = typeof _ === "function" ? _ : constant$11(+_), pie) : value;
32939 pie.sortValues = function(_) {
32940 return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
32943 pie.sort = function(_) {
32944 return arguments.length ? (sort = _, sortValues = null, pie) : sort;
32947 pie.startAngle = function(_) {
32948 return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$11(+_), pie) : startAngle;
32951 pie.endAngle = function(_) {
32952 return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$11(+_), pie) : endAngle;
32955 pie.padAngle = function(_) {
32956 return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$11(+_), pie) : padAngle;
32962 var curveRadialLinear = curveRadial(curveLinear);
32964 function Radial(curve) {
32965 this._curve = curve;
32968 Radial.prototype = {
32969 areaStart: function() {
32970 this._curve.areaStart();
32972 areaEnd: function() {
32973 this._curve.areaEnd();
32975 lineStart: function() {
32976 this._curve.lineStart();
32978 lineEnd: function() {
32979 this._curve.lineEnd();
32981 point: function(a, r) {
32982 this._curve.point(r * Math.sin(a), r * -Math.cos(a));
32986 function curveRadial(curve) {
32988 function radial(context) {
32989 return new Radial(curve(context));
32992 radial._curve = curve;
32997 function radialLine(l) {
33000 l.angle = l.x, delete l.x;
33001 l.radius = l.y, delete l.y;
33003 l.curve = function(_) {
33004 return arguments.length ? c(curveRadial(_)) : c()._curve;
33010 var radialLine$1 = function() {
33011 return radialLine(line().curve(curveRadialLinear));
33014 var radialArea = function() {
33015 var a = area$1().curve(curveRadialLinear),
33022 a.angle = a.x, delete a.x;
33023 a.startAngle = a.x0, delete a.x0;
33024 a.endAngle = a.x1, delete a.x1;
33025 a.radius = a.y, delete a.y;
33026 a.innerRadius = a.y0, delete a.y0;
33027 a.outerRadius = a.y1, delete a.y1;
33028 a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0;
33029 a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1;
33030 a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0;
33031 a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1;
33033 a.curve = function(_) {
33034 return arguments.length ? c(curveRadial(_)) : c()._curve;
33041 draw: function(context, size) {
33042 var r = Math.sqrt(size / pi$4);
33043 context.moveTo(r, 0);
33044 context.arc(0, 0, r, 0, tau$4);
33049 draw: function(context, size) {
33050 var r = Math.sqrt(size / 5) / 2;
33051 context.moveTo(-3 * r, -r);
33052 context.lineTo(-r, -r);
33053 context.lineTo(-r, -3 * r);
33054 context.lineTo(r, -3 * r);
33055 context.lineTo(r, -r);
33056 context.lineTo(3 * r, -r);
33057 context.lineTo(3 * r, r);
33058 context.lineTo(r, r);
33059 context.lineTo(r, 3 * r);
33060 context.lineTo(-r, 3 * r);
33061 context.lineTo(-r, r);
33062 context.lineTo(-3 * r, r);
33063 context.closePath();
33067 var tan30 = Math.sqrt(1 / 3);
33068 var tan30_2 = tan30 * 2;
33071 draw: function(context, size) {
33072 var y = Math.sqrt(size / tan30_2),
33074 context.moveTo(0, -y);
33075 context.lineTo(x, 0);
33076 context.lineTo(0, y);
33077 context.lineTo(-x, 0);
33078 context.closePath();
33082 var ka = 0.89081309152928522810;
33083 var kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);
33084 var kx = Math.sin(tau$4 / 10) * kr;
33085 var ky = -Math.cos(tau$4 / 10) * kr;
33088 draw: function(context, size) {
33089 var r = Math.sqrt(size * ka),
33092 context.moveTo(0, -r);
33093 context.lineTo(x, y);
33094 for (var i = 1; i < 5; ++i) {
33095 var a = tau$4 * i / 5,
33098 context.lineTo(s * r, -c * r);
33099 context.lineTo(c * x - s * y, s * x + c * y);
33101 context.closePath();
33106 draw: function(context, size) {
33107 var w = Math.sqrt(size),
33109 context.rect(x, x, w, w);
33113 var sqrt3 = Math.sqrt(3);
33116 draw: function(context, size) {
33117 var y = -Math.sqrt(size / (sqrt3 * 3));
33118 context.moveTo(0, y * 2);
33119 context.lineTo(-sqrt3 * y, -y);
33120 context.lineTo(sqrt3 * y, -y);
33121 context.closePath();
33126 var s = Math.sqrt(3) / 2;
33127 var k = 1 / Math.sqrt(12);
33128 var a = (k / 2 + 1) * 3;
33131 draw: function(context, size) {
33132 var r = Math.sqrt(size / a),
33139 context.moveTo(x0, y0);
33140 context.lineTo(x1, y1);
33141 context.lineTo(x2, y2);
33142 context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
33143 context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
33144 context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
33145 context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
33146 context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
33147 context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
33148 context.closePath();
33162 var symbol = function() {
33163 var type = constant$11(circle$2),
33164 size = constant$11(64),
33167 function symbol() {
33169 if (!context) context = buffer = path();
33170 type.apply(this, arguments).draw(context, +size.apply(this, arguments));
33171 if (buffer) return context = null, buffer + "" || null;
33174 symbol.type = function(_) {
33175 return arguments.length ? (type = typeof _ === "function" ? _ : constant$11(_), symbol) : type;
33178 symbol.size = function(_) {
33179 return arguments.length ? (size = typeof _ === "function" ? _ : constant$11(+_), symbol) : size;
33182 symbol.context = function(_) {
33183 return arguments.length ? (context = _ == null ? null : _, symbol) : context;
33189 var noop$2 = function() {};
33191 function point$2(that, x, y) {
33192 that._context.bezierCurveTo(
33193 (2 * that._x0 + that._x1) / 3,
33194 (2 * that._y0 + that._y1) / 3,
33195 (that._x0 + 2 * that._x1) / 3,
33196 (that._y0 + 2 * that._y1) / 3,
33197 (that._x0 + 4 * that._x1 + x) / 6,
33198 (that._y0 + 4 * that._y1 + y) / 6
33202 function Basis(context) {
33203 this._context = context;
33206 Basis.prototype = {
33207 areaStart: function() {
33210 areaEnd: function() {
33213 lineStart: function() {
33214 this._x0 = this._x1 =
33215 this._y0 = this._y1 = NaN;
33218 lineEnd: function() {
33219 switch (this._point) {
33220 case 3: point$2(this, this._x1, this._y1); // proceed
33221 case 2: this._context.lineTo(this._x1, this._y1); break;
33223 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33224 this._line = 1 - this._line;
33226 point: function(x, y) {
33228 switch (this._point) {
33229 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33230 case 1: this._point = 2; break;
33231 case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
33232 default: point$2(this, x, y); break;
33234 this._x0 = this._x1, this._x1 = x;
33235 this._y0 = this._y1, this._y1 = y;
33239 var basis$4 = function(context) {
33240 return new Basis(context);
33243 function BasisClosed(context) {
33244 this._context = context;
33247 BasisClosed.prototype = {
33250 lineStart: function() {
33251 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
33252 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
33255 lineEnd: function() {
33256 switch (this._point) {
33258 this._context.moveTo(this._x2, this._y2);
33259 this._context.closePath();
33263 this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
33264 this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
33265 this._context.closePath();
33269 this.point(this._x2, this._y2);
33270 this.point(this._x3, this._y3);
33271 this.point(this._x4, this._y4);
33276 point: function(x, y) {
33278 switch (this._point) {
33279 case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
33280 case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
33281 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;
33282 default: point$2(this, x, y); break;
33284 this._x0 = this._x1, this._x1 = x;
33285 this._y0 = this._y1, this._y1 = y;
33289 var basisClosed$2 = function(context) {
33290 return new BasisClosed(context);
33293 function BasisOpen(context) {
33294 this._context = context;
33297 BasisOpen.prototype = {
33298 areaStart: function() {
33301 areaEnd: function() {
33304 lineStart: function() {
33305 this._x0 = this._x1 =
33306 this._y0 = this._y1 = NaN;
33309 lineEnd: function() {
33310 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
33311 this._line = 1 - this._line;
33313 point: function(x, y) {
33315 switch (this._point) {
33316 case 0: this._point = 1; break;
33317 case 1: this._point = 2; break;
33318 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;
33319 case 3: this._point = 4; // proceed
33320 default: point$2(this, x, y); break;
33322 this._x0 = this._x1, this._x1 = x;
33323 this._y0 = this._y1, this._y1 = y;
33327 var basisOpen = function(context) {
33328 return new BasisOpen(context);
33331 function Bundle(context, beta) {
33332 this._basis = new Basis(context);
33336 Bundle.prototype = {
33337 lineStart: function() {
33340 this._basis.lineStart();
33342 lineEnd: function() {
33358 this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
33359 this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
33364 this._x = this._y = null;
33365 this._basis.lineEnd();
33367 point: function(x, y) {
33373 var bundle = ((function custom(beta) {
33375 function bundle(context) {
33376 return beta === 1 ? new Basis(context) : new Bundle(context, beta);
33379 bundle.beta = function(beta) {
33380 return custom(+beta);
33386 function point$3(that, x, y) {
33387 that._context.bezierCurveTo(
33388 that._x1 + that._k * (that._x2 - that._x0),
33389 that._y1 + that._k * (that._y2 - that._y0),
33390 that._x2 + that._k * (that._x1 - x),
33391 that._y2 + that._k * (that._y1 - y),
33397 function Cardinal(context, tension) {
33398 this._context = context;
33399 this._k = (1 - tension) / 6;
33402 Cardinal.prototype = {
33403 areaStart: function() {
33406 areaEnd: function() {
33409 lineStart: function() {
33410 this._x0 = this._x1 = this._x2 =
33411 this._y0 = this._y1 = this._y2 = NaN;
33414 lineEnd: function() {
33415 switch (this._point) {
33416 case 2: this._context.lineTo(this._x2, this._y2); break;
33417 case 3: point$3(this, this._x1, this._y1); break;
33419 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33420 this._line = 1 - this._line;
33422 point: function(x, y) {
33424 switch (this._point) {
33425 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33426 case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
33427 case 2: this._point = 3; // proceed
33428 default: point$3(this, x, y); break;
33430 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33431 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33435 var cardinal = ((function custom(tension) {
33437 function cardinal(context) {
33438 return new Cardinal(context, tension);
33441 cardinal.tension = function(tension) {
33442 return custom(+tension);
33448 function CardinalClosed(context, tension) {
33449 this._context = context;
33450 this._k = (1 - tension) / 6;
33453 CardinalClosed.prototype = {
33456 lineStart: function() {
33457 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
33458 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
33461 lineEnd: function() {
33462 switch (this._point) {
33464 this._context.moveTo(this._x3, this._y3);
33465 this._context.closePath();
33469 this._context.lineTo(this._x3, this._y3);
33470 this._context.closePath();
33474 this.point(this._x3, this._y3);
33475 this.point(this._x4, this._y4);
33476 this.point(this._x5, this._y5);
33481 point: function(x, y) {
33483 switch (this._point) {
33484 case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
33485 case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
33486 case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
33487 default: point$3(this, x, y); break;
33489 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33490 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33494 var cardinalClosed = ((function custom(tension) {
33496 function cardinal(context) {
33497 return new CardinalClosed(context, tension);
33500 cardinal.tension = function(tension) {
33501 return custom(+tension);
33507 function CardinalOpen(context, tension) {
33508 this._context = context;
33509 this._k = (1 - tension) / 6;
33512 CardinalOpen.prototype = {
33513 areaStart: function() {
33516 areaEnd: function() {
33519 lineStart: function() {
33520 this._x0 = this._x1 = this._x2 =
33521 this._y0 = this._y1 = this._y2 = NaN;
33524 lineEnd: function() {
33525 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
33526 this._line = 1 - this._line;
33528 point: function(x, y) {
33530 switch (this._point) {
33531 case 0: this._point = 1; break;
33532 case 1: this._point = 2; break;
33533 case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
33534 case 3: this._point = 4; // proceed
33535 default: point$3(this, x, y); break;
33537 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33538 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33542 var cardinalOpen = ((function custom(tension) {
33544 function cardinal(context) {
33545 return new CardinalOpen(context, tension);
33548 cardinal.tension = function(tension) {
33549 return custom(+tension);
33555 function point$4(that, x, y) {
33561 if (that._l01_a > epsilon$3) {
33562 var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
33563 n = 3 * that._l01_a * (that._l01_a + that._l12_a);
33564 x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
33565 y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
33568 if (that._l23_a > epsilon$3) {
33569 var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
33570 m = 3 * that._l23_a * (that._l23_a + that._l12_a);
33571 x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
33572 y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
33575 that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
33578 function CatmullRom(context, alpha) {
33579 this._context = context;
33580 this._alpha = alpha;
33583 CatmullRom.prototype = {
33584 areaStart: function() {
33587 areaEnd: function() {
33590 lineStart: function() {
33591 this._x0 = this._x1 = this._x2 =
33592 this._y0 = this._y1 = this._y2 = NaN;
33593 this._l01_a = this._l12_a = this._l23_a =
33594 this._l01_2a = this._l12_2a = this._l23_2a =
33597 lineEnd: function() {
33598 switch (this._point) {
33599 case 2: this._context.lineTo(this._x2, this._y2); break;
33600 case 3: this.point(this._x2, this._y2); break;
33602 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33603 this._line = 1 - this._line;
33605 point: function(x, y) {
33609 var x23 = this._x2 - x,
33610 y23 = this._y2 - y;
33611 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
33614 switch (this._point) {
33615 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33616 case 1: this._point = 2; break;
33617 case 2: this._point = 3; // proceed
33618 default: point$4(this, x, y); break;
33621 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
33622 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
33623 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33624 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33628 var catmullRom = ((function custom(alpha) {
33630 function catmullRom(context) {
33631 return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
33634 catmullRom.alpha = function(alpha) {
33635 return custom(+alpha);
33641 function CatmullRomClosed(context, alpha) {
33642 this._context = context;
33643 this._alpha = alpha;
33646 CatmullRomClosed.prototype = {
33649 lineStart: function() {
33650 this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
33651 this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
33652 this._l01_a = this._l12_a = this._l23_a =
33653 this._l01_2a = this._l12_2a = this._l23_2a =
33656 lineEnd: function() {
33657 switch (this._point) {
33659 this._context.moveTo(this._x3, this._y3);
33660 this._context.closePath();
33664 this._context.lineTo(this._x3, this._y3);
33665 this._context.closePath();
33669 this.point(this._x3, this._y3);
33670 this.point(this._x4, this._y4);
33671 this.point(this._x5, this._y5);
33676 point: function(x, y) {
33680 var x23 = this._x2 - x,
33681 y23 = this._y2 - y;
33682 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
33685 switch (this._point) {
33686 case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
33687 case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
33688 case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
33689 default: point$4(this, x, y); break;
33692 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
33693 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
33694 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33695 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33699 var catmullRomClosed = ((function custom(alpha) {
33701 function catmullRom(context) {
33702 return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
33705 catmullRom.alpha = function(alpha) {
33706 return custom(+alpha);
33712 function CatmullRomOpen(context, alpha) {
33713 this._context = context;
33714 this._alpha = alpha;
33717 CatmullRomOpen.prototype = {
33718 areaStart: function() {
33721 areaEnd: function() {
33724 lineStart: function() {
33725 this._x0 = this._x1 = this._x2 =
33726 this._y0 = this._y1 = this._y2 = NaN;
33727 this._l01_a = this._l12_a = this._l23_a =
33728 this._l01_2a = this._l12_2a = this._l23_2a =
33731 lineEnd: function() {
33732 if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
33733 this._line = 1 - this._line;
33735 point: function(x, y) {
33739 var x23 = this._x2 - x,
33740 y23 = this._y2 - y;
33741 this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
33744 switch (this._point) {
33745 case 0: this._point = 1; break;
33746 case 1: this._point = 2; break;
33747 case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
33748 case 3: this._point = 4; // proceed
33749 default: point$4(this, x, y); break;
33752 this._l01_a = this._l12_a, this._l12_a = this._l23_a;
33753 this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
33754 this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
33755 this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
33759 var catmullRomOpen = ((function custom(alpha) {
33761 function catmullRom(context) {
33762 return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
33765 catmullRom.alpha = function(alpha) {
33766 return custom(+alpha);
33772 function LinearClosed(context) {
33773 this._context = context;
33776 LinearClosed.prototype = {
33779 lineStart: function() {
33782 lineEnd: function() {
33783 if (this._point) this._context.closePath();
33785 point: function(x, y) {
33787 if (this._point) this._context.lineTo(x, y);
33788 else this._point = 1, this._context.moveTo(x, y);
33792 var linearClosed = function(context) {
33793 return new LinearClosed(context);
33796 function sign$1(x) {
33797 return x < 0 ? -1 : 1;
33800 // Calculate the slopes of the tangents (Hermite-type interpolation) based on
33801 // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
33802 // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
33803 // NOV(II), P. 443, 1990.
33804 function slope3(that, x2, y2) {
33805 var h0 = that._x1 - that._x0,
33806 h1 = x2 - that._x1,
33807 s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
33808 s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
33809 p = (s0 * h1 + s1 * h0) / (h0 + h1);
33810 return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
33813 // Calculate a one-sided slope.
33814 function slope2(that, t) {
33815 var h = that._x1 - that._x0;
33816 return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
33819 // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
33820 // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
33821 // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
33822 function point$5(that, t0, t1) {
33827 dx = (x1 - x0) / 3;
33828 that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
33831 function MonotoneX(context) {
33832 this._context = context;
33835 MonotoneX.prototype = {
33836 areaStart: function() {
33839 areaEnd: function() {
33842 lineStart: function() {
33843 this._x0 = this._x1 =
33844 this._y0 = this._y1 =
33848 lineEnd: function() {
33849 switch (this._point) {
33850 case 2: this._context.lineTo(this._x1, this._y1); break;
33851 case 3: point$5(this, this._t0, slope2(this, this._t0)); break;
33853 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33854 this._line = 1 - this._line;
33856 point: function(x, y) {
33860 if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
33861 switch (this._point) {
33862 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33863 case 1: this._point = 2; break;
33864 case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
33865 default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;
33868 this._x0 = this._x1, this._x1 = x;
33869 this._y0 = this._y1, this._y1 = y;
33874 function MonotoneY(context) {
33875 this._context = new ReflectContext(context);
33878 (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
33879 MonotoneX.prototype.point.call(this, y, x);
33882 function ReflectContext(context) {
33883 this._context = context;
33886 ReflectContext.prototype = {
33887 moveTo: function(x, y) { this._context.moveTo(y, x); },
33888 closePath: function() { this._context.closePath(); },
33889 lineTo: function(x, y) { this._context.lineTo(y, x); },
33890 bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
33893 function monotoneX(context) {
33894 return new MonotoneX(context);
33897 function monotoneY(context) {
33898 return new MonotoneY(context);
33901 function Natural(context) {
33902 this._context = context;
33905 Natural.prototype = {
33906 areaStart: function() {
33909 areaEnd: function() {
33912 lineStart: function() {
33916 lineEnd: function() {
33922 this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
33924 this._context.lineTo(x[1], y[1]);
33926 var px = controlPoints(x),
33927 py = controlPoints(y);
33928 for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
33929 this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
33934 if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
33935 this._line = 1 - this._line;
33936 this._x = this._y = null;
33938 point: function(x, y) {
33944 // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
33945 function controlPoints(x) {
33952 a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
33953 for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
33954 a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
33955 for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
33956 a[n - 1] = r[n - 1] / b[n - 1];
33957 for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
33958 b[n - 1] = (x[n] + a[n - 1]) / 2;
33959 for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
33963 var natural = function(context) {
33964 return new Natural(context);
33967 function Step(context, t) {
33968 this._context = context;
33973 areaStart: function() {
33976 areaEnd: function() {
33979 lineStart: function() {
33980 this._x = this._y = NaN;
33983 lineEnd: function() {
33984 if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
33985 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
33986 if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
33988 point: function(x, y) {
33990 switch (this._point) {
33991 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
33992 case 1: this._point = 2; // proceed
33994 if (this._t <= 0) {
33995 this._context.lineTo(this._x, y);
33996 this._context.lineTo(x, y);
33998 var x1 = this._x * (1 - this._t) + x * this._t;
33999 this._context.lineTo(x1, this._y);
34000 this._context.lineTo(x1, y);
34005 this._x = x, this._y = y;
34009 var step = function(context) {
34010 return new Step(context, 0.5);
34013 function stepBefore(context) {
34014 return new Step(context, 0);
34017 function stepAfter(context) {
34018 return new Step(context, 1);
34021 var slice$5 = Array.prototype.slice;
34023 var none$1 = function(series, order) {
34024 if (!((n = series.length) > 1)) return;
34025 for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
34026 s0 = s1, s1 = series[order[i]];
34027 for (var j = 0; j < m; ++j) {
34028 s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
34033 var none$2 = function(series) {
34034 var n = series.length, o = new Array(n);
34035 while (--n >= 0) o[n] = n;
34039 function stackValue(d, key) {
34043 var stack = function() {
34044 var keys = constant$11([]),
34047 value = stackValue;
34049 function stack(data) {
34050 var kz = keys.apply(this, arguments),
34057 for (i = 0; i < n; ++i) {
34058 for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
34059 si[j] = sij = [0, +value(data[j], ki, j, data)];
34060 sij.data = data[j];
34065 for (i = 0, oz = order(sz); i < n; ++i) {
34066 sz[oz[i]].index = i;
34073 stack.keys = function(_) {
34074 return arguments.length ? (keys = typeof _ === "function" ? _ : constant$11(slice$5.call(_)), stack) : keys;
34077 stack.value = function(_) {
34078 return arguments.length ? (value = typeof _ === "function" ? _ : constant$11(+_), stack) : value;
34081 stack.order = function(_) {
34082 return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$11(slice$5.call(_)), stack) : order;
34085 stack.offset = function(_) {
34086 return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
34092 var expand = function(series, order) {
34093 if (!((n = series.length) > 0)) return;
34094 for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
34095 for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
34096 if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
34098 none$1(series, order);
34101 var silhouette = function(series, order) {
34102 if (!((n = series.length) > 0)) return;
34103 for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
34104 for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
34105 s0[j][1] += s0[j][0] = -y / 2;
34107 none$1(series, order);
34110 var wiggle = function(series, order) {
34111 if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
34112 for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
34113 for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
34114 var si = series[order[i]],
34115 sij0 = si[j][1] || 0,
34116 sij1 = si[j - 1][1] || 0,
34117 s3 = (sij0 - sij1) / 2;
34118 for (var k = 0; k < i; ++k) {
34119 var sk = series[order[k]],
34120 skj0 = sk[j][1] || 0,
34121 skj1 = sk[j - 1][1] || 0;
34124 s1 += sij0, s2 += s3 * sij0;
34126 s0[j - 1][1] += s0[j - 1][0] = y;
34127 if (s1) y -= s2 / s1;
34129 s0[j - 1][1] += s0[j - 1][0] = y;
34130 none$1(series, order);
34133 var ascending$2 = function(series) {
34134 var sums = series.map(sum$2);
34135 return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });
34138 function sum$2(series) {
34139 var s = 0, i = -1, n = series.length, v;
34140 while (++i < n) if (v = +series[i][1]) s += v;
34144 var descending$2 = function(series) {
34145 return ascending$2(series).reverse();
34148 var insideOut = function(series) {
34149 var n = series.length,
34152 sums = series.map(sum$2),
34153 order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),
34159 for (i = 0; i < n; ++i) {
34161 if (top < bottom) {
34170 return bottoms.reverse().concat(tops);
34173 var reverse = function(series) {
34174 return none$2(series).reverse();
34179 var interval$2 = 0;
34180 var pokeDelay$1 = 1000;
34183 var clockLast$1 = 0;
34184 var clockNow$1 = 0;
34185 var clockSkew$1 = 0;
34186 var clock$1 = typeof performance === "object" && performance.now ? performance : Date;
34187 var setFrame$1 = typeof requestAnimationFrame === "function" ? requestAnimationFrame : function(f) { setTimeout(f, 17); };
34190 return clockNow$1 || (setFrame$1(clearNow$1), clockNow$1 = clock$1.now() + clockSkew$1);
34193 function clearNow$1() {
34197 function Timer$1() {
34203 Timer$1.prototype = timer$1.prototype = {
34204 constructor: Timer$1,
34205 restart: function(callback, delay, time) {
34206 if (typeof callback !== "function") throw new TypeError("callback is not a function");
34207 time = (time == null ? now$1() : +time) + (delay == null ? 0 : +delay);
34208 if (!this._next && taskTail$1 !== this) {
34209 if (taskTail$1) taskTail$1._next = this;
34210 else taskHead$1 = this;
34213 this._call = callback;
34220 this._time = Infinity;
34226 function timer$1(callback, delay, time) {
34227 var t = new Timer$1;
34228 t.restart(callback, delay, time);
34232 function timerFlush$1() {
34233 now$1(); // Get the current time, if not already set.
34234 ++frame$1; // Pretend we’ve set an alarm, if we haven’t already.
34235 var t = taskHead$1, e;
34237 if ((e = clockNow$1 - t._time) >= 0) t._call.call(null, e);
34243 function wake$1() {
34244 clockNow$1 = (clockLast$1 = clock$1.now()) + clockSkew$1;
34245 frame$1 = timeout$2 = 0;
34255 function poke$2() {
34256 var now = clock$1.now(), delay = now - clockLast$1;
34257 if (delay > pokeDelay$1) clockSkew$1 -= delay, clockLast$1 = now;
34261 var t0, t1 = taskHead$1, t2, time = Infinity;
34264 if (time > t1._time) time = t1._time;
34265 t0 = t1, t1 = t1._next;
34267 t2 = t1._next, t1._next = null;
34268 t1 = t0 ? t0._next = t2 : taskHead$1 = t2;
34275 function sleep$1(time) {
34276 if (frame$1) return; // Soonest alarm already set, or will be.
34277 if (timeout$2) timeout$2 = clearTimeout(timeout$2);
34278 var delay = time - clockNow$1;
34280 if (time < Infinity) timeout$2 = setTimeout(wake$1, delay);
34281 if (interval$2) interval$2 = clearInterval(interval$2);
34283 if (!interval$2) clockLast$1 = clockNow$1, interval$2 = setInterval(poke$2, pokeDelay$1);
34284 frame$1 = 1, setFrame$1(wake$1);
34288 var timeout$3 = function(callback, delay, time) {
34289 var t = new Timer$1;
34290 delay = delay == null ? 0 : +delay;
34291 t.restart(function(elapsed) {
34293 callback(elapsed + delay);
34298 var interval$3 = function(callback, delay, time) {
34299 var t = new Timer$1, total = delay;
34300 if (delay == null) return t.restart(callback, delay, time), t;
34301 delay = +delay, time = time == null ? now$1() : +time;
34302 t.restart(function tick(elapsed) {
34304 t.restart(tick, total += delay, time);
34310 var constant$12 = function(x) {
34311 return function() {
34324 function RedBlackTree() {
34325 this._ = null; // root node
34328 function RedBlackNode(node) {
34329 node.U = // parent node
34330 node.C = // color - true for red, false for black
34331 node.L = // left node
34332 node.R = // right node
34333 node.P = // previous node
34334 node.N = null; // next node
34337 RedBlackTree.prototype = {
34338 constructor: RedBlackTree,
34340 insert: function(after, node) {
34341 var parent, grandpa, uncle;
34346 if (after.N) after.N.P = node;
34350 while (after.L) after = after.L;
34356 } else if (this._) {
34357 after = RedBlackFirst(this._);
34360 after.P = after.L = node;
34363 node.P = node.N = null;
34367 node.L = node.R = null;
34372 while (parent && parent.C) {
34373 grandpa = parent.U;
34374 if (parent === grandpa.L) {
34376 if (uncle && uncle.C) {
34377 parent.C = uncle.C = false;
34381 if (after === parent.R) {
34382 RedBlackRotateLeft(this, parent);
34388 RedBlackRotateRight(this, grandpa);
34392 if (uncle && uncle.C) {
34393 parent.C = uncle.C = false;
34397 if (after === parent.L) {
34398 RedBlackRotateRight(this, parent);
34404 RedBlackRotateLeft(this, grandpa);
34412 remove: function(node) {
34413 if (node.N) node.N.P = node.P;
34414 if (node.P) node.P.N = node.N;
34415 node.N = node.P = null;
34417 var parent = node.U,
34424 if (!left) next = right;
34425 else if (!right) next = left;
34426 else next = RedBlackFirst(right);
34429 if (parent.L === node) parent.L = next;
34430 else parent.R = next;
34435 if (left && right) {
34440 if (next !== right) {
34457 if (node) node.U = parent;
34459 if (node && node.C) { node.C = false; return; }
34462 if (node === this._) break;
34463 if (node === parent.L) {
34464 sibling = parent.R;
34468 RedBlackRotateLeft(this, parent);
34469 sibling = parent.R;
34471 if ((sibling.L && sibling.L.C)
34472 || (sibling.R && sibling.R.C)) {
34473 if (!sibling.R || !sibling.R.C) {
34474 sibling.L.C = false;
34476 RedBlackRotateRight(this, sibling);
34477 sibling = parent.R;
34479 sibling.C = parent.C;
34480 parent.C = sibling.R.C = false;
34481 RedBlackRotateLeft(this, parent);
34486 sibling = parent.L;
34490 RedBlackRotateRight(this, parent);
34491 sibling = parent.L;
34493 if ((sibling.L && sibling.L.C)
34494 || (sibling.R && sibling.R.C)) {
34495 if (!sibling.L || !sibling.L.C) {
34496 sibling.R.C = false;
34498 RedBlackRotateLeft(this, sibling);
34499 sibling = parent.L;
34501 sibling.C = parent.C;
34502 parent.C = sibling.L.C = false;
34503 RedBlackRotateRight(this, parent);
34513 if (node) node.C = false;
34517 function RedBlackRotateLeft(tree, node) {
34523 if (parent.L === p) parent.L = q;
34532 if (p.R) p.R.U = p;
34536 function RedBlackRotateRight(tree, node) {
34542 if (parent.L === p) parent.L = q;
34551 if (p.L) p.L.U = p;
34555 function RedBlackFirst(node) {
34556 while (node.L) node = node.L;
34560 function createEdge(left, right, v0, v1) {
34561 var edge = [null, null],
34562 index = edges.push(edge) - 1;
34564 edge.right = right;
34565 if (v0) setEdgeEnd(edge, left, right, v0);
34566 if (v1) setEdgeEnd(edge, right, left, v1);
34567 cells[left.index].halfedges.push(index);
34568 cells[right.index].halfedges.push(index);
34572 function createBorderEdge(left, v0, v1) {
34573 var edge = [v0, v1];
34578 function setEdgeEnd(edge, left, right, vertex) {
34579 if (!edge[0] && !edge[1]) {
34582 edge.right = right;
34583 } else if (edge.left === right) {
34590 // Liang–Barsky line clipping.
34591 function clipEdge(edge, x0, y0, x1, y1) {
34605 if (!dx && r > 0) return;
34608 if (r < t0) return;
34609 if (r < t1) t1 = r;
34610 } else if (dx > 0) {
34611 if (r > t1) return;
34612 if (r > t0) t0 = r;
34616 if (!dx && r < 0) return;
34619 if (r > t1) return;
34620 if (r > t0) t0 = r;
34621 } else if (dx > 0) {
34622 if (r < t0) return;
34623 if (r < t1) t1 = r;
34627 if (!dy && r > 0) return;
34630 if (r < t0) return;
34631 if (r < t1) t1 = r;
34632 } else if (dy > 0) {
34633 if (r > t1) return;
34634 if (r > t0) t0 = r;
34638 if (!dy && r < 0) return;
34641 if (r > t1) return;
34642 if (r > t0) t0 = r;
34643 } else if (dy > 0) {
34644 if (r < t0) return;
34645 if (r < t1) t1 = r;
34648 if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?
34650 if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
34651 if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
34655 function connectEdge(edge, x0, y0, x1, y1) {
34657 if (v1) return true;
34661 right = edge.right,
34666 fx = (lx + rx) / 2,
34667 fy = (ly + ry) / 2,
34672 if (fx < x0 || fx >= x1) return;
34674 if (!v0) v0 = [fx, y0];
34675 else if (v0[1] >= y1) return;
34678 if (!v0) v0 = [fx, y1];
34679 else if (v0[1] < y0) return;
34683 fm = (lx - rx) / (ry - ly);
34685 if (fm < -1 || fm > 1) {
34687 if (!v0) v0 = [(y0 - fb) / fm, y0];
34688 else if (v0[1] >= y1) return;
34689 v1 = [(y1 - fb) / fm, y1];
34691 if (!v0) v0 = [(y1 - fb) / fm, y1];
34692 else if (v0[1] < y0) return;
34693 v1 = [(y0 - fb) / fm, y0];
34697 if (!v0) v0 = [x0, fm * x0 + fb];
34698 else if (v0[0] >= x1) return;
34699 v1 = [x1, fm * x1 + fb];
34701 if (!v0) v0 = [x1, fm * x1 + fb];
34702 else if (v0[0] < x0) return;
34703 v1 = [x0, fm * x0 + fb];
34713 function clipEdges(x0, y0, x1, y1) {
34714 var i = edges.length,
34718 if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
34719 || !clipEdge(edge, x0, y0, x1, y1)
34720 || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4
34721 || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {
34727 function createCell(site) {
34728 return cells[site.index] = {
34734 function cellHalfedgeAngle(cell, edge) {
34735 var site = cell.site,
34738 if (site === vb) vb = va, va = site;
34739 if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
34740 if (site === va) va = edge[1], vb = edge[0];
34741 else va = edge[0], vb = edge[1];
34742 return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
34745 function cellHalfedgeStart(cell, edge) {
34746 return edge[+(edge.left !== cell.site)];
34749 function cellHalfedgeEnd(cell, edge) {
34750 return edge[+(edge.left === cell.site)];
34753 function sortCellHalfedges() {
34754 for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
34755 if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
34756 var index = new Array(m),
34757 array = new Array(m);
34758 for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
34759 index.sort(function(i, j) { return array[j] - array[i]; });
34760 for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
34761 for (j = 0; j < m; ++j) halfedges[j] = array[j];
34766 function clipCells(x0, y0, x1, y1) {
34767 var nCells = cells.length,
34782 for (iCell = 0; iCell < nCells; ++iCell) {
34783 if (cell = cells[iCell]) {
34785 halfedges = cell.halfedges;
34786 iHalfedge = halfedges.length;
34788 // Remove any dangling clipped edges.
34789 while (iHalfedge--) {
34790 if (!edges[halfedges[iHalfedge]]) {
34791 halfedges.splice(iHalfedge, 1);
34795 // Insert any border edges as necessary.
34796 iHalfedge = 0, nHalfedges = halfedges.length;
34797 while (iHalfedge < nHalfedges) {
34798 end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
34799 start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
34800 if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {
34801 halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
34802 Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]
34803 : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]
34804 : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]
34805 : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]
34811 if (nHalfedges) cover = false;
34815 // If there weren’t any edges, have the closest site cover the extent.
34816 // It doesn’t matter which corner of the extent we measure!
34818 var dx, dy, d2, dc = Infinity;
34820 for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
34821 if (cell = cells[iCell]) {
34825 d2 = dx * dx + dy * dy;
34826 if (d2 < dc) dc = d2, cover = cell;
34831 var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
34832 cover.halfedges.push(
34833 edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
34834 edges.push(createBorderEdge(site, v01, v11)) - 1,
34835 edges.push(createBorderEdge(site, v11, v10)) - 1,
34836 edges.push(createBorderEdge(site, v10, v00)) - 1
34841 // Lastly delete any cells with no edges; these were entirely clipped.
34842 for (iCell = 0; iCell < nCells; ++iCell) {
34843 if (cell = cells[iCell]) {
34844 if (!cell.halfedges.length) {
34845 delete cells[iCell];
34851 var circlePool = [];
34855 function Circle() {
34856 RedBlackNode(this);
34864 function attachCircle(arc) {
34868 if (!lArc || !rArc) return;
34870 var lSite = lArc.site,
34874 if (lSite === rSite) return;
34878 ax = lSite[0] - bx,
34879 ay = lSite[1] - by,
34880 cx = rSite[0] - bx,
34881 cy = rSite[1] - by;
34883 var d = 2 * (ax * cy - ay * cx);
34884 if (d >= -epsilon2$3) return;
34886 var ha = ax * ax + ay * ay,
34887 hc = cx * cx + cy * cy,
34888 x = (cy * ha - ay * hc) / d,
34889 y = (ax * hc - cx * ha) / d;
34891 var circle = circlePool.pop() || new Circle;
34893 circle.site = cSite;
34895 circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
34897 arc.circle = circle;
34903 if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
34904 if (node.L) node = node.L;
34905 else { before = node.P; break; }
34907 if (node.R) node = node.R;
34908 else { before = node; break; }
34912 circles.insert(before, circle);
34913 if (!before) firstCircle = circle;
34916 function detachCircle(arc) {
34917 var circle = arc.circle;
34919 if (!circle.P) firstCircle = circle.N;
34920 circles.remove(circle);
34921 circlePool.push(circle);
34922 RedBlackNode(circle);
34927 var beachPool = [];
34930 RedBlackNode(this);
34933 this.circle = null;
34936 function createBeach(site) {
34937 var beach = beachPool.pop() || new Beach;
34942 function detachBeach(beach) {
34943 detachCircle(beach);
34944 beaches.remove(beach);
34945 beachPool.push(beach);
34946 RedBlackNode(beach);
34949 function removeBeach(beach) {
34950 var circle = beach.circle,
34954 previous = beach.P,
34956 disappearing = [beach];
34958 detachBeach(beach);
34960 var lArc = previous;
34962 && Math.abs(x - lArc.circle.x) < epsilon$4
34963 && Math.abs(y - lArc.circle.cy) < epsilon$4) {
34965 disappearing.unshift(lArc);
34970 disappearing.unshift(lArc);
34971 detachCircle(lArc);
34975 && Math.abs(x - rArc.circle.x) < epsilon$4
34976 && Math.abs(y - rArc.circle.cy) < epsilon$4) {
34978 disappearing.push(rArc);
34983 disappearing.push(rArc);
34984 detachCircle(rArc);
34986 var nArcs = disappearing.length,
34988 for (iArc = 1; iArc < nArcs; ++iArc) {
34989 rArc = disappearing[iArc];
34990 lArc = disappearing[iArc - 1];
34991 setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
34994 lArc = disappearing[0];
34995 rArc = disappearing[nArcs - 1];
34996 rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
34998 attachCircle(lArc);
34999 attachCircle(rArc);
35002 function addBeach(site) {
35004 directrix = site[1],
35012 dxl = leftBreakPoint(node, directrix) - x;
35013 if (dxl > epsilon$4) node = node.L; else {
35014 dxr = x - rightBreakPoint(node, directrix);
35015 if (dxr > epsilon$4) {
35022 if (dxl > -epsilon$4) {
35025 } else if (dxr > -epsilon$4) {
35029 lArc = rArc = node;
35037 var newArc = createBeach(site);
35038 beaches.insert(lArc, newArc);
35040 if (!lArc && !rArc) return;
35042 if (lArc === rArc) {
35043 detachCircle(lArc);
35044 rArc = createBeach(lArc.site);
35045 beaches.insert(newArc, rArc);
35046 newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
35047 attachCircle(lArc);
35048 attachCircle(rArc);
35052 if (!rArc) { // && lArc
35053 newArc.edge = createEdge(lArc.site, newArc.site);
35057 // else lArc !== rArc
35058 detachCircle(lArc);
35059 detachCircle(rArc);
35061 var lSite = lArc.site,
35067 cx = rSite[0] - ax,
35068 cy = rSite[1] - ay,
35069 d = 2 * (bx * cy - by * cx),
35070 hb = bx * bx + by * by,
35071 hc = cx * cx + cy * cy,
35072 vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
35074 setEdgeEnd(rArc.edge, lSite, rSite, vertex);
35075 newArc.edge = createEdge(lSite, site, null, vertex);
35076 rArc.edge = createEdge(site, rSite, null, vertex);
35077 attachCircle(lArc);
35078 attachCircle(rArc);
35081 function leftBreakPoint(arc, directrix) {
35082 var site = arc.site,
35085 pby2 = rfocy - directrix;
35087 if (!pby2) return rfocx;
35090 if (!lArc) return -Infinity;
35093 var lfocx = site[0],
35095 plby2 = lfocy - directrix;
35097 if (!plby2) return lfocx;
35099 var hl = lfocx - rfocx,
35100 aby2 = 1 / pby2 - 1 / plby2,
35103 if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
35105 return (rfocx + lfocx) / 2;
35108 function rightBreakPoint(arc, directrix) {
35110 if (rArc) return leftBreakPoint(rArc, directrix);
35111 var site = arc.site;
35112 return site[1] === directrix ? site[0] : Infinity;
35115 var epsilon$4 = 1e-6;
35116 var epsilon2$3 = 1e-12;
35122 function triangleArea(a, b, c) {
35123 return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
35126 function lexicographic(a, b) {
35131 function Diagram(sites, extent) {
35132 var site = sites.sort(lexicographic).pop(),
35138 cells = new Array(sites.length);
35139 beaches = new RedBlackTree;
35140 circles = new RedBlackTree;
35143 circle = firstCircle;
35144 if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
35145 if (site[0] !== x || site[1] !== y) {
35147 x = site[0], y = site[1];
35149 site = sites.pop();
35150 } else if (circle) {
35151 removeBeach(circle.arc);
35157 sortCellHalfedges();
35160 var x0 = +extent[0][0],
35161 y0 = +extent[0][1],
35162 x1 = +extent[1][0],
35163 y1 = +extent[1][1];
35164 clipEdges(x0, y0, x1, y1);
35165 clipCells(x0, y0, x1, y1);
35168 this.edges = edges;
35169 this.cells = cells;
35177 Diagram.prototype = {
35178 constructor: Diagram,
35180 polygons: function() {
35181 var edges = this.edges;
35183 return this.cells.map(function(cell) {
35184 var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
35185 polygon.data = cell.site.data;
35190 triangles: function() {
35191 var triangles = [],
35192 edges = this.edges;
35194 this.cells.forEach(function(cell, i) {
35195 if (!(m = (halfedges = cell.halfedges).length)) return;
35196 var site = cell.site,
35201 e1 = edges[halfedges[m - 1]],
35202 s1 = e1.left === site ? e1.right : e1.left;
35206 e1 = edges[halfedges[j]];
35207 s1 = e1.left === site ? e1.right : e1.left;
35208 if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
35209 triangles.push([site.data, s0.data, s1.data]);
35217 links: function() {
35218 return this.edges.filter(function(edge) {
35220 }).map(function(edge) {
35222 source: edge.left.data,
35223 target: edge.right.data
35228 find: function(x, y, radius) {
35229 var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;
35231 // Use the previously-found cell, or start with an arbitrary one.
35232 while (!(cell = that.cells[i1])) if (++i1 >= n) return null;
35233 var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;
35235 // Traverse the half-edges to find a closer cell, if any.
35237 cell = that.cells[i0 = i1], i1 = null;
35238 cell.halfedges.forEach(function(e) {
35239 var edge = that.edges[e], v = edge.left;
35240 if ((v === cell.site || !v) && !(v = edge.right)) return;
35241 var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;
35242 if (v2 < d2) d2 = v2, i1 = v.index;
35244 } while (i1 !== null);
35248 return radius == null || d2 <= radius * radius ? cell.site : null;
35252 var voronoi = function() {
35257 function voronoi(data) {
35258 return new Diagram(data.map(function(d, i) {
35259 var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];
35266 voronoi.polygons = function(data) {
35267 return voronoi(data).polygons();
35270 voronoi.links = function(data) {
35271 return voronoi(data).links();
35274 voronoi.triangles = function(data) {
35275 return voronoi(data).triangles();
35278 voronoi.x = function(_) {
35279 return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$12(+_), voronoi) : x$$1;
35282 voronoi.y = function(_) {
35283 return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$12(+_), voronoi) : y$$1;
35286 voronoi.extent = function(_) {
35287 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]]];
35290 voronoi.size = function(_) {
35291 return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
35297 var constant$13 = function(x) {
35298 return function() {
35303 function ZoomEvent(target, type, transform) {
35304 this.target = target;
35306 this.transform = transform;
35309 function Transform(k, x, y) {
35315 Transform.prototype = {
35316 constructor: Transform,
35317 scale: function(k) {
35318 return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
35320 translate: function(x, y) {
35321 return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
35323 apply: function(point) {
35324 return [point[0] * this.k + this.x, point[1] * this.k + this.y];
35326 applyX: function(x) {
35327 return x * this.k + this.x;
35329 applyY: function(y) {
35330 return y * this.k + this.y;
35332 invert: function(location) {
35333 return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
35335 invertX: function(x) {
35336 return (x - this.x) / this.k;
35338 invertY: function(y) {
35339 return (y - this.y) / this.k;
35341 rescaleX: function(x) {
35342 return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
35344 rescaleY: function(y) {
35345 return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
35347 toString: function() {
35348 return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
35352 var identity$9 = new Transform(1, 0, 0);
35354 transform$1.prototype = Transform.prototype;
35356 function transform$1(node) {
35357 return node.__zoom || identity$9;
35360 function nopropagation$2() {
35361 event.stopImmediatePropagation();
35364 var noevent$2 = function() {
35365 event.preventDefault();
35366 event.stopImmediatePropagation();
35369 // Ignore right-click, since that should open the context menu.
35370 function defaultFilter$2() {
35371 return !event.button;
35374 function defaultExtent$1() {
35375 var e = this, w, h;
35376 if (e instanceof SVGElement) {
35377 e = e.ownerSVGElement || e;
35378 w = e.width.baseVal.value;
35379 h = e.height.baseVal.value;
35382 h = e.clientHeight;
35384 return [[0, 0], [w, h]];
35387 function defaultTransform() {
35388 return this.__zoom || identity$9;
35391 var zoom$1 = function() {
35392 var filter = defaultFilter$2,
35393 extent = defaultExtent$1,
35401 interpolate$$1 = interpolateZoom,
35403 listeners = dispatch("start", "zoom", "end"),
35409 function zoom(selection$$1) {
35411 .on("wheel.zoom", wheeled)
35412 .on("mousedown.zoom", mousedowned)
35413 .on("dblclick.zoom", dblclicked)
35414 .on("touchstart.zoom", touchstarted)
35415 .on("touchmove.zoom", touchmoved)
35416 .on("touchend.zoom touchcancel.zoom", touchended)
35417 .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
35418 .property("__zoom", defaultTransform);
35421 zoom.transform = function(collection, transform) {
35422 var selection$$1 = collection.selection ? collection.selection() : collection;
35423 selection$$1.property("__zoom", defaultTransform);
35424 if (collection !== selection$$1) {
35425 schedule(collection, transform);
35427 selection$$1.interrupt().each(function() {
35428 gesture(this, arguments)
35430 .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform)
35436 zoom.scaleBy = function(selection$$1, k) {
35437 zoom.scaleTo(selection$$1, function() {
35438 var k0 = this.__zoom.k,
35439 k1 = typeof k === "function" ? k.apply(this, arguments) : k;
35444 zoom.scaleTo = function(selection$$1, k) {
35445 zoom.transform(selection$$1, function() {
35446 var e = extent.apply(this, arguments),
35449 p1 = t0.invert(p0),
35450 k1 = typeof k === "function" ? k.apply(this, arguments) : k;
35451 return constrain(translate(scale(t0, k1), p0, p1), e);
35455 zoom.translateBy = function(selection$$1, x, y) {
35456 zoom.transform(selection$$1, function() {
35457 return constrain(this.__zoom.translate(
35458 typeof x === "function" ? x.apply(this, arguments) : x,
35459 typeof y === "function" ? y.apply(this, arguments) : y
35460 ), extent.apply(this, arguments));
35464 function scale(transform, k) {
35465 k = Math.max(k0, Math.min(k1, k));
35466 return k === transform.k ? transform : new Transform(k, transform.x, transform.y);
35469 function translate(transform, p0, p1) {
35470 var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k;
35471 return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y);
35474 function constrain(transform, extent) {
35475 var dx0 = transform.invertX(extent[0][0]) - x0,
35476 dx1 = transform.invertX(extent[1][0]) - x1,
35477 dy0 = transform.invertY(extent[0][1]) - y0,
35478 dy1 = transform.invertY(extent[1][1]) - y1;
35479 return transform.translate(
35480 dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
35481 dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
35485 function centroid(extent) {
35486 return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
35489 function schedule(transition$$1, transform, center) {
35491 .on("start.zoom", function() { gesture(this, arguments).start(); })
35492 .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
35493 .tween("zoom", function() {
35496 g = gesture(that, args),
35497 e = extent.apply(that, args),
35498 p = center || centroid(e),
35499 w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
35501 b = typeof transform === "function" ? transform.apply(that, args) : transform,
35502 i = interpolate$$1(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
35503 return function(t) {
35504 if (t === 1) t = b; // Avoid rounding error on end.
35505 else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
35511 function gesture(that, args) {
35512 for (var i = 0, n = gestures.length, g; i < n; ++i) {
35513 if ((g = gestures[i]).that === that) {
35517 return new Gesture(that, args);
35520 function Gesture(that, args) {
35525 this.extent = extent.apply(that, args);
35528 Gesture.prototype = {
35529 start: function() {
35530 if (++this.active === 1) {
35531 this.index = gestures.push(this) - 1;
35532 this.emit("start");
35536 zoom: function(key, transform) {
35537 if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]);
35538 if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]);
35539 if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]);
35540 this.that.__zoom = transform;
35545 if (--this.active === 0) {
35546 gestures.splice(this.index, 1);
35552 emit: function(type) {
35553 customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
35557 function wheeled() {
35558 if (!filter.apply(this, arguments)) return;
35559 var g = gesture(this, arguments),
35561 k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -event.deltaY * (event.deltaMode ? 120 : 1) / 500))),
35564 // If the mouse is in the same location as before, reuse it.
35565 // If there were recent wheel events, reset the wheel idle timeout.
35567 if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
35568 g.mouse[1] = t.invert(g.mouse[0] = p);
35570 clearTimeout(g.wheel);
35573 // If this wheel event won’t trigger a transform change, ignore it.
35574 else if (t.k === k) return;
35576 // Otherwise, capture the mouse point and location at the start.
35578 g.mouse = [p, t.invert(p)];
35584 g.wheel = setTimeout(wheelidled, wheelDelay);
35585 g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent));
35587 function wheelidled() {
35593 function mousedowned() {
35594 if (touchending || !filter.apply(this, arguments)) return;
35595 var g = gesture(this, arguments),
35596 v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
35599 dragDisable(event.view);
35601 g.mouse = [p, this.__zoom.invert(p)];
35605 function mousemoved() {
35608 g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent));
35611 function mouseupped() {
35612 v.on("mousemove.zoom mouseup.zoom", null);
35613 yesdrag(event.view, g.moved);
35619 function dblclicked() {
35620 if (!filter.apply(this, arguments)) return;
35621 var t0 = this.__zoom,
35623 p1 = t0.invert(p0),
35624 k1 = t0.k * (event.shiftKey ? 0.5 : 2),
35625 t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments));
35628 if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);
35629 else select(this).call(zoom.transform, t1);
35632 function touchstarted() {
35633 if (!filter.apply(this, arguments)) return;
35634 var g = gesture(this, arguments),
35635 touches$$1 = event.changedTouches,
35637 n = touches$$1.length, i, t, p;
35640 for (i = 0; i < n; ++i) {
35641 t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
35642 p = [p, this.__zoom.invert(p), t.identifier];
35643 if (!g.touch0) g.touch0 = p, started = true;
35644 else if (!g.touch1) g.touch1 = p;
35647 // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
35648 if (touchstarting) {
35649 touchstarting = clearTimeout(touchstarting);
35652 p = select(this).on("dblclick.zoom");
35653 if (p) p.apply(this, arguments);
35659 touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
35665 function touchmoved() {
35666 var g = gesture(this, arguments),
35667 touches$$1 = event.changedTouches,
35668 n = touches$$1.length, i, t, p, l;
35671 if (touchstarting) touchstarting = clearTimeout(touchstarting);
35672 for (i = 0; i < n; ++i) {
35673 t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
35674 if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
35675 else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
35679 var p0 = g.touch0[0], l0 = g.touch0[1],
35680 p1 = g.touch1[0], l1 = g.touch1[1],
35681 dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
35682 dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
35683 t = scale(t, Math.sqrt(dp / dl));
35684 p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
35685 l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
35687 else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
35689 g.zoom("touch", constrain(translate(t, p, l), g.extent));
35692 function touchended() {
35693 var g = gesture(this, arguments),
35694 touches$$1 = event.changedTouches,
35695 n = touches$$1.length, i, t;
35698 if (touchending) clearTimeout(touchending);
35699 touchending = setTimeout(function() { touchending = null; }, touchDelay);
35700 for (i = 0; i < n; ++i) {
35702 if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
35703 else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
35705 if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
35706 if (!g.touch0) g.end();
35709 zoom.filter = function(_) {
35710 return arguments.length ? (filter = typeof _ === "function" ? _ : constant$13(!!_), zoom) : filter;
35713 zoom.extent = function(_) {
35714 return arguments.length ? (extent = typeof _ === "function" ? _ : constant$13([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
35717 zoom.scaleExtent = function(_) {
35718 return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1];
35721 zoom.translateExtent = function(_) {
35722 return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]];
35725 zoom.duration = function(_) {
35726 return arguments.length ? (duration = +_, zoom) : duration;
35729 zoom.interpolate = function(_) {
35730 return arguments.length ? (interpolate$$1 = _, zoom) : interpolate$$1;
35733 zoom.on = function() {
35734 var value = listeners.on.apply(listeners, arguments);
35735 return value === listeners ? zoom : value;
35743 var index$2 = Object.freeze({
35745 bisect: bisectRight,
35746 bisectRight: bisectRight,
35747 bisectLeft: bisectLeft,
35748 ascending: ascending,
35749 bisector: bisector,
35750 descending: descending,
35751 deviation: deviation,
35753 histogram: histogram,
35754 thresholdFreedmanDiaconis: freedmanDiaconis,
35755 thresholdScott: scott,
35756 thresholdSturges: sturges,
35764 quantile: threshold,
35770 tickStep: tickStep,
35771 transpose: transpose,
35772 variance: variance,
35775 axisRight: axisRight,
35776 axisBottom: axisBottom,
35777 axisLeft: axisLeft,
35781 brushSelection: brushSelection,
35795 cubehelix: cubehelix,
35796 dispatch: dispatch,
35798 dragDisable: dragDisable,
35799 dragEnable: yesdrag,
35801 csvParse: csvParse,
35802 csvParseRows: csvParseRows,
35803 csvFormat: csvFormat,
35804 csvFormatRows: csvFormatRows,
35805 tsvParse: tsvParse,
35806 tsvParseRows: tsvParseRows,
35807 tsvFormat: tsvFormat,
35808 tsvFormatRows: tsvFormatRows,
35809 easeLinear: linear$1,
35810 easeQuad: quadInOut,
35811 easeQuadIn: quadIn,
35812 easeQuadOut: quadOut,
35813 easeQuadInOut: quadInOut,
35814 easeCubic: cubicInOut,
35815 easeCubicIn: cubicIn,
35816 easeCubicOut: cubicOut,
35817 easeCubicInOut: cubicInOut,
35818 easePoly: polyInOut,
35819 easePolyIn: polyIn,
35820 easePolyOut: polyOut,
35821 easePolyInOut: polyInOut,
35824 easeSinOut: sinOut,
35825 easeSinInOut: sinInOut,
35828 easeExpOut: expOut,
35829 easeExpInOut: expInOut,
35830 easeCircle: circleInOut,
35831 easeCircleIn: circleIn,
35832 easeCircleOut: circleOut,
35833 easeCircleInOut: circleInOut,
35834 easeBounce: bounceOut,
35835 easeBounceIn: bounceIn,
35836 easeBounceOut: bounceOut,
35837 easeBounceInOut: bounceInOut,
35838 easeBack: backInOut,
35839 easeBackIn: backIn,
35840 easeBackOut: backOut,
35841 easeBackInOut: backInOut,
35842 easeElastic: elasticOut,
35843 easeElasticIn: elasticIn,
35844 easeElasticOut: elasticOut,
35845 easeElasticInOut: elasticInOut,
35846 forceCenter: center$1,
35847 forceCollide: collide,
35849 forceManyBody: manyBody,
35850 forceSimulation: simulation,
35853 formatDefaultLocale: defaultLocale,
35854 get format () { return format; },
35855 get formatPrefix () { return formatPrefix; },
35856 formatLocale: formatLocale,
35857 formatSpecifier: formatSpecifier,
35858 precisionFixed: precisionFixed,
35859 precisionPrefix: precisionPrefix,
35860 precisionRound: precisionRound,
35863 geoCentroid: d3GeoCentroid,
35865 geoClipExtent: extent$1,
35866 geoDistance: distance,
35867 geoGraticule: graticule,
35868 geoGraticule10: graticule10,
35869 geoInterpolate: interpolate$1,
35870 geoLength: d3GeoLength,
35873 geoAlbersUsa: albersUsa,
35874 geoAzimuthalEqualArea: azimuthalEqualArea,
35875 geoAzimuthalEqualAreaRaw: azimuthalEqualAreaRaw,
35876 geoAzimuthalEquidistant: azimuthalEquidistant,
35877 geoAzimuthalEquidistantRaw: azimuthalEquidistantRaw,
35878 geoConicConformal: conicConformal,
35879 geoConicConformalRaw: conicConformalRaw,
35880 geoConicEqualArea: conicEqualArea,
35881 geoConicEqualAreaRaw: conicEqualAreaRaw,
35882 geoConicEquidistant: conicEquidistant,
35883 geoConicEquidistantRaw: conicEquidistantRaw,
35884 geoEquirectangular: equirectangular,
35885 geoEquirectangularRaw: equirectangularRaw,
35886 geoGnomonic: gnomonic,
35887 geoGnomonicRaw: gnomonicRaw,
35888 geoIdentity: identity$5,
35889 geoProjection: projection,
35890 geoProjectionMutator: projectionMutator,
35891 geoMercator: mercator,
35892 geoMercatorRaw: mercatorRaw,
35893 geoOrthographic: orthographic,
35894 geoOrthographicRaw: orthographicRaw,
35895 geoStereographic: stereographic,
35896 geoStereographicRaw: stereographicRaw,
35897 geoTransverseMercator: transverseMercator,
35898 geoTransverseMercatorRaw: transverseMercatorRaw,
35899 geoRotation: rotation,
35900 geoStream: geoStream,
35901 geoTransform: transform,
35903 hierarchy: hierarchy,
35905 packSiblings: siblings,
35906 packEnclose: enclose,
35907 partition: partition,
35908 stratify: stratify,
35911 treemapBinary: binary,
35912 treemapDice: treemapDice,
35913 treemapSlice: treemapSlice,
35914 treemapSliceDice: sliceDice,
35915 treemapSquarify: squarify,
35916 treemapResquarify: resquarify,
35917 interpolate: value$1,
35918 interpolateArray: array$2,
35919 interpolateBasis: basis$3,
35920 interpolateBasisClosed: basisClosed$1,
35921 interpolateDate: date$1,
35922 interpolateNumber: number$1,
35923 interpolateObject: object$2,
35924 interpolateRound: round,
35925 interpolateString: string,
35926 interpolateTransformCss: interpolateTransformCss$1,
35927 interpolateTransformSvg: interpolateTransformSvg$1,
35928 interpolateZoom: interpolateZoom,
35929 interpolateRgb: rgb$1,
35930 interpolateRgbBasis: rgbBasis$1,
35931 interpolateRgbBasisClosed: rgbBasisClosed$1,
35932 interpolateHsl: hsl$4,
35933 interpolateHslLong: hslLong$1,
35934 interpolateLab: lab$2,
35935 interpolateHcl: hcl$4,
35936 interpolateHclLong: hclLong$1,
35937 interpolateCubehelix: cubehelix$4,
35938 interpolateCubehelixLong: cubehelixLong$1,
35939 quantize: quantize$1,
35941 polygonArea: d3polygonArea,
35942 polygonCentroid: d3polygonCentroid,
35943 polygonHull: d3polygonHull,
35944 polygonContains: contains,
35945 polygonLength: length$1,
35946 quadtree: quadtree,
35948 randomUniform: uniform,
35949 randomNormal: normal,
35950 randomLogNormal: logNormal,
35951 randomBates: bates,
35952 randomIrwinHall: irwinHall,
35953 randomExponential: exponential$2,
35962 scalePoint: point$1,
35963 scaleIdentity: identity$7,
35964 scaleLinear: linear$3,
35966 scaleOrdinal: ordinal,
35967 scaleImplicit: implicit,
35970 scaleQuantile: quantile$$1,
35971 scaleQuantize: quantize$2,
35972 scaleThreshold: threshold$1,
35975 schemeCategory10: category10,
35976 schemeCategory20b: category20b,
35977 schemeCategory20c: category20c,
35978 schemeCategory20: category20,
35979 interpolateCubehelixDefault: cubehelix$5,
35980 interpolateRainbow: rainbow$1,
35981 interpolateWarm: warm,
35982 interpolateCool: cool,
35983 interpolateViridis: viridis,
35984 interpolateMagma: magma,
35985 interpolateInferno: inferno,
35986 interpolatePlasma: plasma,
35987 scaleSequential: sequential,
35990 matcher: matcher$1,
35992 namespace: namespace,
35993 namespaces: namespaces,
35995 selectAll: selectAll,
35996 selection: selection,
35997 selector: selector,
35998 selectorAll: selectorAll,
36002 get event () { return event; },
36003 customEvent: customEvent,
36008 radialArea: radialArea,
36009 radialLine: radialLine$1,
36012 symbolCircle: circle$2,
36013 symbolCross: cross$1,
36014 symbolDiamond: diamond,
36015 symbolSquare: square,
36017 symbolTriangle: triangle,
36019 curveBasisClosed: basisClosed$2,
36020 curveBasisOpen: basisOpen,
36021 curveBasis: basis$4,
36022 curveBundle: bundle,
36023 curveCardinalClosed: cardinalClosed,
36024 curveCardinalOpen: cardinalOpen,
36025 curveCardinal: cardinal,
36026 curveCatmullRomClosed: catmullRomClosed,
36027 curveCatmullRomOpen: catmullRomOpen,
36028 curveCatmullRom: catmullRom,
36029 curveLinearClosed: linearClosed,
36030 curveLinear: curveLinear,
36031 curveMonotoneX: monotoneX,
36032 curveMonotoneY: monotoneY,
36033 curveNatural: natural,
36035 curveStepAfter: stepAfter,
36036 curveStepBefore: stepBefore,
36038 stackOffsetExpand: expand,
36039 stackOffsetNone: none$1,
36040 stackOffsetSilhouette: silhouette,
36041 stackOffsetWiggle: wiggle,
36042 stackOrderAscending: ascending$2,
36043 stackOrderDescending: descending$2,
36044 stackOrderInsideOut: insideOut,
36045 stackOrderNone: none$2,
36046 stackOrderReverse: reverse,
36047 timeInterval: newInterval,
36048 timeMillisecond: millisecond,
36049 timeMilliseconds: milliseconds,
36050 utcMillisecond: millisecond,
36051 utcMilliseconds: milliseconds,
36052 timeSecond: second,
36053 timeSeconds: seconds,
36055 utcSeconds: seconds,
36056 timeMinute: minute,
36057 timeMinutes: minutes,
36063 timeWeeks: sundays,
36064 timeSunday: sunday,
36065 timeSundays: sundays,
36066 timeMonday: monday,
36067 timeMondays: mondays,
36068 timeTuesday: tuesday,
36069 timeTuesdays: tuesdays,
36070 timeWednesday: wednesday,
36071 timeWednesdays: wednesdays,
36072 timeThursday: thursday,
36073 timeThursdays: thursdays,
36074 timeFriday: friday,
36075 timeFridays: fridays,
36076 timeSaturday: saturday,
36077 timeSaturdays: saturdays,
36079 timeMonths: months,
36082 utcMinute: utcMinute,
36083 utcMinutes: utcMinutes,
36085 utcHours: utcHours,
36088 utcWeek: utcSunday,
36089 utcWeeks: utcSundays,
36090 utcSunday: utcSunday,
36091 utcSundays: utcSundays,
36092 utcMonday: utcMonday,
36093 utcMondays: utcMondays,
36094 utcTuesday: utcTuesday,
36095 utcTuesdays: utcTuesdays,
36096 utcWednesday: utcWednesday,
36097 utcWednesdays: utcWednesdays,
36098 utcThursday: utcThursday,
36099 utcThursdays: utcThursdays,
36100 utcFriday: utcFriday,
36101 utcFridays: utcFridays,
36102 utcSaturday: utcSaturday,
36103 utcSaturdays: utcSaturdays,
36104 utcMonth: utcMonth,
36105 utcMonths: utcMonths,
36107 utcYears: utcYears,
36108 timeFormatDefaultLocale: defaultLocale$1,
36109 get timeFormat () { return timeFormat; },
36110 get timeParse () { return timeParse; },
36111 get utcFormat () { return utcFormat; },
36112 get utcParse () { return utcParse; },
36113 timeFormatLocale: formatLocale$1,
36114 isoFormat: formatIso,
36115 isoParse: parseIso,
36118 timerFlush: timerFlush$1,
36119 timeout: timeout$3,
36120 interval: interval$3,
36121 transition: transition,
36123 interrupt: interrupt,
36126 zoomTransform: transform$1,
36127 zoomIdentity: identity$9
36131 Bypasses features of D3's default projection stream pipeline that are unnecessary:
36132 * Antimeridian clipping
36133 * Spherical rotation
36136 function geoRawMercator() {
36137 var project = mercatorRaw,
36138 k = 512 / Math.PI, // scale
36139 x = 0, y = 0, // translate
36140 clipExtent = [[0, 0], [0, 0]];
36143 function projection(point) {
36144 point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
36145 return [point[0] * k + x, y - point[1] * k];
36149 projection.invert = function(point) {
36150 point = project.invert((point[0] - x) / k, (y - point[1]) / k);
36151 return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
36155 projection.scale = function(_) {
36156 if (!arguments.length) return k;
36162 projection.translate = function(_) {
36163 if (!arguments.length) return [x, y];
36170 projection.clipExtent = function(_) {
36171 if (!arguments.length) return clipExtent;
36177 projection.transform = function(_) {
36178 if (!arguments.length) return identity$9.translate(x, y).scale(k);
36186 projection.stream = transform({
36187 point: function(x, y) {
36188 x = projection([x, y]);
36189 this.stream.point(x[0], x[1]);
36197 function osmNode() {
36198 if (!(this instanceof osmNode)) {
36199 return (new osmNode()).initialize(arguments);
36200 } else if (arguments.length) {
36201 this.initialize(arguments);
36205 osmEntity$$1.node = osmNode;
36207 osmNode.prototype = Object.create(osmEntity$$1.prototype);
36209 lodash.extend(osmNode.prototype, {
36214 extent: function() {
36215 return new geoExtent$$1(this.loc);
36219 geometry: function(graph) {
36220 return graph.transient(this, 'geometry', function() {
36221 return graph.isPoi(this) ? 'point' : 'vertex';
36226 move: function(loc) {
36227 return this.update({loc: loc});
36231 isDegenerate: function() {
36233 Array.isArray(this.loc) && this.loc.length === 2 &&
36234 this.loc[0] >= -180 && this.loc[0] <= 180 &&
36235 this.loc[1] >= -90 && this.loc[1] <= 90
36240 isEndpoint: function(resolver) {
36241 return resolver.transient(this, 'isEndpoint', function() {
36243 return resolver.parentWays(this).filter(function(parent) {
36244 return !parent.isClosed() && !!parent.affix(id);
36250 isConnected: function(resolver) {
36251 return resolver.transient(this, 'isConnected', function() {
36252 var parents = resolver.parentWays(this);
36254 // vertex is connected to multiple parent ways
36255 if (parents.length > 1) {
36258 } else if (parents.length === 1) {
36259 var way = parents[0],
36260 nodes = way.nodes.slice();
36261 if (way.isClosed()) { nodes.pop(); } // ignore connecting node if closed
36263 // return true if vertex appears multiple times (way is self intersecting)
36264 return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id);
36272 isIntersection: function(resolver) {
36273 return resolver.transient(this, 'isIntersection', function() {
36274 return resolver.parentWays(this).filter(function(parent) {
36275 return (parent.tags.highway ||
36276 parent.tags.waterway ||
36277 parent.tags.railway ||
36278 parent.tags.aeroway) &&
36279 parent.geometry(resolver) === 'line';
36285 isHighwayIntersection: function(resolver) {
36286 return resolver.transient(this, 'isHighwayIntersection', function() {
36287 return resolver.parentWays(this).filter(function(parent) {
36288 return parent.tags.highway && parent.geometry(resolver) === 'line';
36294 isOnAddressLine: function(resolver) {
36295 return resolver.transient(this, 'isOnAddressLine', function() {
36296 return resolver.parentWays(this).filter(function(parent) {
36297 return parent.tags.hasOwnProperty('addr:interpolation') &&
36298 parent.geometry(resolver) === 'line';
36304 asJXON: function(changeset_id) {
36307 '@id': this.osmId(),
36308 '@lon': this.loc[0],
36309 '@lat': this.loc[1],
36310 '@version': (this.version || 0),
36311 tag: lodash.map(this.tags, function(v, k) {
36312 return { keyAttributes: { k: k, v: v } };
36316 if (changeset_id) r.node['@changeset'] = changeset_id;
36321 asGeoJSON: function() {
36324 coordinates: this.loc
36330 Order the nodes of a way in reverse order and reverse any direction dependent tags
36331 other than `oneway`. (We assume that correcting a backwards oneway is the primary
36332 reason for reversing a way.)
36334 The following transforms are performed:
36337 *:right=* ⟺ *:left=*
36338 *:forward=* ⟺ *:backward=*
36339 direction=up ⟺ direction=down
36340 incline=up ⟺ incline=down
36344 role=forward ⟺ role=backward
36345 role=north ⟺ role=south
36346 role=east ⟺ role=west
36348 In addition, numeric-valued `incline` tags are negated.
36350 The JOSM implementation was used as a guide, but transformations that were of unclear benefit
36351 or adjusted tags that don't seem to be used in practice were omitted.
36353 Also, each node on the way is examined for its own tags and the following transformations are performed
36354 in order to ensure associated nodes (eg a Stop Sign) is also reversed
36357 direction=forward ⟺ direction=backward
36358 direction=left ⟺ direction=right
36359 *:forward=* ⟺ *:backward=*
36360 *:left=* ⟺ *:right=*
36363 http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
36364 http://wiki.openstreetmap.org/wiki/Key:direction#Steps
36365 http://wiki.openstreetmap.org/wiki/Key:incline
36366 http://wiki.openstreetmap.org/wiki/Route#Members
36367 http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
36368 http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
36369 http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
36371 function actionReverse(wayId, options) {
36372 var replacements = [
36373 [/:right$/, ':left'], [/:left$/, ':right'],
36374 [/:forward$/, ':backward'], [/:backward$/, ':forward']
36376 numeric = /^([+\-]?)(?=[\d.])/,
36378 forward: 'backward',
36379 backward: 'forward',
36387 function reverseKey(key) {
36388 for (var i = 0; i < replacements.length; ++i) {
36389 var replacement = replacements[i];
36390 if (replacement[0].test(key)) {
36391 return key.replace(replacement[0], replacement[1]);
36398 function reverseValue(key, value) {
36399 if (key === 'incline' && numeric.test(value)) {
36400 return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
36401 } else if (key === 'incline' || key === 'direction') {
36402 return {up: 'down', down: 'up'}[value] || value;
36403 } else if (options && options.reverseOneway && key === 'oneway') {
36404 return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
36406 return {left: 'right', right: 'left'}[value] || value;
36411 function reverseDirectionTags(node) {
36412 // Update the direction based tags as appropriate then return an updated node
36413 return node.update({tags: lodash.transform(node.tags, function(acc, tagValue, tagKey) {
36414 // See if this is a direction tag and reverse (or use existing value if not recognised)
36415 if (tagKey === 'direction') {
36416 acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
36418 // Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
36419 // This will pass through other tags unchanged
36420 acc[reverseKey(tagKey)] = tagValue;
36427 function reverseTagsOnNodes(graph, nodeIds) {
36428 // Reverse the direction of appropriate tags attached to the nodes (#3076)
36429 return lodash(nodeIds)
36430 // Get each node from the graph
36431 .map(function(nodeId) { return graph.entity(nodeId);})
36432 // Check tags on the node, if there aren't any, we can skip
36433 .filter(function(existingNode) { return existingNode.tags !== undefined;})
36434 // Get a new version of each node with the appropriate tags reversed
36435 .map(function(existingNode) { return reverseDirectionTags(existingNode);})
36436 // Chain together consecutive updates to the graph for each updated node and return
36437 .reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
36441 return function(graph) {
36442 var way = graph.entity(wayId),
36443 nodes = way.nodes.slice().reverse(),
36444 tags = {}, key, role;
36446 for (key in way.tags) {
36447 tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
36450 graph.parentRelations(way).forEach(function(relation) {
36451 relation.members.forEach(function(member, index) {
36452 if (member.id === way.id && (role = roleReversals[member.role])) {
36453 relation = relation.updateMember({role: role}, index);
36454 graph = graph.replace(relation);
36459 // Reverse any associated directions on nodes on the way and then replace
36460 // the way itself with the reversed node ids and updated way tags
36461 return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
36465 // For fixing up rendering of multipolygons with tags on the outer member.
36466 // https://github.com/openstreetmap/iD/issues/613
36467 function osmIsSimpleMultipolygonOuterMember(entity, graph) {
36468 if (entity.type !== 'way')
36471 var parents = graph.parentRelations(entity);
36472 if (parents.length !== 1)
36475 var parent = parents[0];
36476 if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
36479 var members = parent.members, member;
36480 for (var i = 0; i < members.length; i++) {
36481 member = members[i];
36482 if (member.id === entity.id && member.role && member.role !== 'outer')
36483 return false; // Not outer member
36484 if (member.id !== entity.id && (!member.role || member.role === 'outer'))
36485 return false; // Not a simple multipolygon
36492 function osmSimpleMultipolygonOuterMember(entity, graph) {
36493 if (entity.type !== 'way')
36496 var parents = graph.parentRelations(entity);
36497 if (parents.length !== 1)
36500 var parent = parents[0];
36501 if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
36504 var members = parent.members, member, outerMember;
36505 for (var i = 0; i < members.length; i++) {
36506 member = members[i];
36507 if (!member.role || member.role === 'outer') {
36509 return false; // Not a simple multipolygon
36510 outerMember = member;
36514 return outerMember && graph.hasEntity(outerMember.id);
36518 // Join `array` into sequences of connecting ways.
36520 // Segments which share identical start/end nodes will, as much as possible,
36521 // be connected with each other.
36523 // The return value is a nested array. Each constituent array contains elements
36524 // of `array` which have been determined to connect. Each consitituent array
36525 // also has a `nodes` property whose value is an ordered array of member nodes,
36526 // with appropriate order reversal and start/end coordinate de-duplication.
36528 // Members of `array` must have, at minimum, `type` and `id` properties.
36529 // Thus either an array of `osmWay`s or a relation member array may be
36532 // If an member has a `tags` property, its tags will be reversed via
36533 // `actionReverse` in the output.
36535 // Incomplete members (those for which `graph.hasEntity(element.id)` returns
36536 // false) and non-way members are ignored.
36538 function osmJoinWays(array, graph) {
36539 var joined = [], member, current, nodes, first, last, i, how, what;
36541 array = array.filter(function(member) {
36542 return member.type === 'way' && graph.hasEntity(member.id);
36545 function resolve(member) {
36546 return graph.childNodes(graph.entity(member.id));
36549 function reverse(member) {
36550 return member.tags ? actionReverse(member.id, { reverseOneway: true })(graph).entity(member.id) : member;
36553 while (array.length) {
36554 member = array.shift();
36555 current = [member];
36556 current.nodes = nodes = resolve(member).slice();
36557 joined.push(current);
36559 while (array.length && lodash.first(nodes) !== lodash.last(nodes)) {
36560 first = lodash.first(nodes);
36561 last = lodash.last(nodes);
36563 for (i = 0; i < array.length; i++) {
36565 what = resolve(member);
36567 if (last === lodash.first(what)) {
36569 what = what.slice(1);
36571 } else if (last === lodash.last(what)) {
36573 what = what.slice(0, -1).reverse();
36574 member = reverse(member);
36576 } else if (first === lodash.last(what)) {
36577 how = nodes.unshift;
36578 what = what.slice(0, -1);
36580 } else if (first === lodash.first(what)) {
36581 how = nodes.unshift;
36582 what = what.slice(1).reverse();
36583 member = reverse(member);
36591 break; // No more joinable ways.
36593 how.apply(current, [member]);
36594 how.apply(nodes, what);
36596 array.splice(i, 1);
36603 function osmRelation() {
36604 if (!(this instanceof osmRelation)) {
36605 return (new osmRelation()).initialize(arguments);
36606 } else if (arguments.length) {
36607 this.initialize(arguments);
36612 osmEntity$$1.relation = osmRelation;
36614 osmRelation.prototype = Object.create(osmEntity$$1.prototype);
36617 osmRelation.creationOrder = function(a, b) {
36618 var aId = parseInt(osmEntity$$1.id.toOSM(a.id), 10);
36619 var bId = parseInt(osmEntity$$1.id.toOSM(b.id), 10);
36621 if (aId < 0 || bId < 0) return aId - bId;
36626 lodash.extend(osmRelation.prototype, {
36631 copy: function(resolver, copies) {
36632 if (copies[this.id])
36633 return copies[this.id];
36635 var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
36637 var members = this.members.map(function(member) {
36638 return lodash.extend({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
36641 copy = copy.update({members: members});
36642 copies[this.id] = copy;
36648 extent: function(resolver, memo) {
36649 return resolver.transient(this, 'extent', function() {
36650 if (memo && memo[this.id]) return geoExtent$$1();
36652 memo[this.id] = true;
36654 var extent$$1 = geoExtent$$1();
36655 for (var i = 0; i < this.members.length; i++) {
36656 var member = resolver.hasEntity(this.members[i].id);
36658 extent$$1._extend(member.extent(resolver, memo));
36666 geometry: function(graph) {
36667 return graph.transient(this, 'geometry', function() {
36668 return this.isMultipolygon() ? 'area' : 'relation';
36673 isDegenerate: function() {
36674 return this.members.length === 0;
36678 // Return an array of members, each extended with an 'index' property whose value
36679 // is the member index.
36680 indexedMembers: function() {
36681 var result = new Array(this.members.length);
36682 for (var i = 0; i < this.members.length; i++) {
36683 result[i] = lodash.extend({}, this.members[i], {index: i});
36689 // Return the first member with the given role. A copy of the member object
36690 // is returned, extended with an 'index' property whose value is the member index.
36691 memberByRole: function(role) {
36692 for (var i = 0; i < this.members.length; i++) {
36693 if (this.members[i].role === role) {
36694 return lodash.extend({}, this.members[i], {index: i});
36700 // Return the first member with the given id. A copy of the member object
36701 // is returned, extended with an 'index' property whose value is the member index.
36702 memberById: function(id) {
36703 for (var i = 0; i < this.members.length; i++) {
36704 if (this.members[i].id === id) {
36705 return lodash.extend({}, this.members[i], {index: i});
36711 // Return the first member with the given id and role. A copy of the member object
36712 // is returned, extended with an 'index' property whose value is the member index.
36713 memberByIdAndRole: function(id, role) {
36714 for (var i = 0; i < this.members.length; i++) {
36715 if (this.members[i].id === id && this.members[i].role === role) {
36716 return lodash.extend({}, this.members[i], {index: i});
36722 addMember: function(member, index) {
36723 var members = this.members.slice();
36724 members.splice(index === undefined ? members.length : index, 0, member);
36725 return this.update({members: members});
36729 updateMember: function(member, index) {
36730 var members = this.members.slice();
36731 members.splice(index, 1, lodash.extend({}, members[index], member));
36732 return this.update({members: members});
36736 removeMember: function(index) {
36737 var members = this.members.slice();
36738 members.splice(index, 1);
36739 return this.update({members: members});
36743 removeMembersWithID: function(id) {
36744 var members = lodash.reject(this.members, function(m) { return m.id === id; });
36745 return this.update({members: members});
36749 // Wherever a member appears with id `needle.id`, replace it with a member
36750 // with id `replacement.id`, type `replacement.type`, and the original role,
36751 // unless a member already exists with that id and role. Return an updated
36753 replaceMember: function(needle, replacement) {
36754 if (!this.memberById(needle.id))
36759 for (var i = 0; i < this.members.length; i++) {
36760 var member = this.members[i];
36761 if (member.id !== needle.id) {
36762 members.push(member);
36763 } else if (!this.memberByIdAndRole(replacement.id, member.role)) {
36764 members.push({id: replacement.id, type: replacement.type, role: member.role});
36768 return this.update({members: members});
36772 asJXON: function(changeset_id) {
36775 '@id': this.osmId(),
36776 '@version': this.version || 0,
36777 member: lodash.map(this.members, function(member) {
36782 ref: osmEntity$$1.id.toOSM(member.id)
36786 tag: lodash.map(this.tags, function(v, k) {
36787 return { keyAttributes: { k: k, v: v } };
36791 if (changeset_id) r.relation['@changeset'] = changeset_id;
36796 asGeoJSON: function(resolver) {
36797 return resolver.transient(this, 'GeoJSON', function () {
36798 if (this.isMultipolygon()) {
36800 type: 'MultiPolygon',
36801 coordinates: this.multipolygon(resolver)
36805 type: 'FeatureCollection',
36806 properties: this.tags,
36807 features: this.members.map(function (member) {
36808 return lodash.extend({role: member.role}, resolver.entity(member.id).asGeoJSON(resolver));
36816 area: function(resolver) {
36817 return resolver.transient(this, 'area', function() {
36818 return area(this.asGeoJSON(resolver));
36823 isMultipolygon: function() {
36824 return this.tags.type === 'multipolygon';
36828 isComplete: function(resolver) {
36829 for (var i = 0; i < this.members.length; i++) {
36830 if (!resolver.hasEntity(this.members[i].id)) {
36838 isRestriction: function() {
36839 return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
36843 // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
36844 // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
36846 // This corresponds to the structure needed for rendering a multipolygon path using a
36847 // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
36849 // In the case of invalid geometries, this function will still return a result which
36850 // includes the nodes of all way members, but some Nds may be unclosed and some inner
36851 // rings not matched with the intended outer ring.
36853 multipolygon: function(resolver) {
36854 var outers = this.members.filter(function(m) { return 'outer' === (m.role || 'outer'); }),
36855 inners = this.members.filter(function(m) { return 'inner' === m.role; });
36857 outers = osmJoinWays(outers, resolver);
36858 inners = osmJoinWays(inners, resolver);
36860 outers = outers.map(function(outer) { return lodash.map(outer.nodes, 'loc'); });
36861 inners = inners.map(function(inner) { return lodash.map(inner.nodes, 'loc'); });
36863 var result = outers.map(function(o) {
36864 // Heuristic for detecting counterclockwise winding order. Assumes
36865 // that OpenStreetMap polygons are not hemisphere-spanning.
36866 return [area({ type: 'Polygon', coordinates: [o] }) > 2 * Math.PI ? o.reverse() : o];
36869 function findOuter(inner) {
36872 for (o = 0; o < outers.length; o++) {
36874 if (geoPolygonContainsPolygon(outer, inner))
36878 for (o = 0; o < outers.length; o++) {
36880 if (geoPolygonIntersectsPolygon(outer, inner, false))
36885 for (var i = 0; i < inners.length; i++) {
36886 var inner = inners[i];
36888 if (area({ type: 'Polygon', coordinates: [inner] }) < 2 * Math.PI) {
36889 inner = inner.reverse();
36892 var o = findOuter(inners[i]);
36893 if (o !== undefined)
36894 result[o].push(inners[i]);
36896 result.push([inners[i]]); // Invalid geometry
36903 function osmLanes(entity) {
36904 if (entity.type !== 'way') return null;
36905 if (!entity.tags.highway) return null;
36907 var tags = entity.tags;
36908 var isOneWay = entity.isOneWay();
36909 var laneCount = getLaneCount(tags, isOneWay);
36910 var maxspeed = parseMaxspeed(tags);
36912 var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
36913 var forward = laneDirections.forward;
36914 var backward = laneDirections.backward;
36915 var bothways = laneDirections.bothways;
36917 // parse the piped string 'x|y|z' format
36918 var turnLanes = {};
36919 turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
36920 turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
36921 turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
36923 var maxspeedLanes = {};
36924 maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
36925 maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
36926 maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
36929 psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
36930 psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
36931 psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
36934 busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
36935 busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
36936 busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
36938 var taxiLanes = {};
36939 taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
36940 taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
36941 taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
36944 hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
36945 hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
36946 hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
36949 hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
36950 hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
36951 hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
36953 var bicyclewayLanes = {};
36954 bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
36955 bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
36956 bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
36964 // map forward/backward/unspecified of each lane type to lanesObj
36965 mapToLanesObj(lanesObj, turnLanes, 'turnLane');
36966 mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
36967 mapToLanesObj(lanesObj, psvLanes, 'psv');
36968 mapToLanesObj(lanesObj, busLanes, 'bus');
36969 mapToLanesObj(lanesObj, taxiLanes, 'taxi');
36970 mapToLanesObj(lanesObj, hovLanes, 'hov');
36971 mapToLanesObj(lanesObj, hgvLanes, 'hgv');
36972 mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
36979 backward: backward,
36980 bothways: bothways,
36981 turnLanes: turnLanes,
36982 maxspeed: maxspeed,
36983 maxspeedLanes: maxspeedLanes,
36984 psvLanes: psvLanes,
36985 busLanes: busLanes,
36986 taxiLanes: taxiLanes,
36987 hovLanes: hovLanes,
36988 hgvLanes: hgvLanes,
36989 bicyclewayLanes: bicyclewayLanes
36996 function getLaneCount(tags, isOneWay) {
36999 count = parseInt(tags.lanes, 10);
37006 switch (tags.highway) {
37009 count = isOneWay ? 2 : 4;
37012 count = isOneWay ? 1 : 2;
37020 function parseMaxspeed(tags) {
37021 var maxspeed = tags.maxspeed;
37022 if (lodash.isNumber(maxspeed)) return maxspeed;
37023 if (lodash.isString(maxspeed)) {
37024 maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g);
37025 if (!maxspeed) return;
37026 return parseInt(maxspeed, 10);
37031 function parseLaneDirections(tags, isOneWay, laneCount) {
37032 var forward = parseInt(tags['lanes:forward'], 10);
37033 var backward = parseInt(tags['lanes:backward'], 10);
37034 var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
37036 if (parseInt(tags.oneway, 10) === -1) {
37039 backward = laneCount;
37041 else if (isOneWay) {
37042 forward = laneCount;
37046 else if (lodash.isNaN(forward) && lodash.isNaN(backward)) {
37047 backward = Math.floor((laneCount - bothways) / 2);
37048 forward = laneCount - bothways - backward;
37050 else if (lodash.isNaN(forward)) {
37051 if (backward > laneCount - bothways) {
37052 backward = laneCount - bothways;
37054 forward = laneCount - bothways - backward;
37056 else if (lodash.isNaN(backward)) {
37057 if (forward > laneCount - bothways) {
37058 forward = laneCount - bothways;
37060 backward = laneCount - bothways - forward;
37064 backward: backward,
37070 function parseTurnLanes(tag){
37073 var validValues = [
37074 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
37075 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
37078 return tag.split('|')
37079 .map(function (s) {
37080 if (s === '') s = 'none';
37081 return s.split(';')
37082 .map(function (d) {
37083 return validValues.indexOf(d) === -1 ? 'unknown': d;
37089 function parseMaxspeedLanes(tag, maxspeed) {
37092 return tag.split('|')
37093 .map(function (s) {
37094 if (s === 'none') return s;
37095 var m = parseInt(s, 10);
37096 if (s === '' || m === maxspeed) return null;
37097 return lodash.isNaN(m) ? 'unknown': m;
37102 function parseMiscLanes(tag) {
37105 var validValues = [
37106 'yes', 'no', 'designated'
37109 return tag.split('|')
37110 .map(function (s) {
37111 if (s === '') s = 'no';
37112 return validValues.indexOf(s) === -1 ? 'unknown': s;
37117 function parseBicycleWay(tag) {
37120 var validValues = [
37121 'yes', 'no', 'designated', 'lane'
37124 return tag.split('|')
37125 .map(function (s) {
37126 if (s === '') s = 'no';
37127 return validValues.indexOf(s) === -1 ? 'unknown': s;
37132 function mapToLanesObj(lanesObj, data, key) {
37133 if (data.forward) data.forward.forEach(function(l, i) {
37134 if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
37135 lanesObj.forward[i][key] = l;
37137 if (data.backward) data.backward.forEach(function(l, i) {
37138 if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
37139 lanesObj.backward[i][key] = l;
37141 if (data.unspecified) data.unspecified.forEach(function(l, i) {
37142 if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
37143 lanesObj.unspecified[i][key] = l;
37147 var translations = Object.create(null);
37149 var currentLocale = 'en';
37150 var textDirection = 'ltr';
37152 function setLocale(_) {
37153 if (translations[_] !== undefined) {
37155 } else if (translations[_.split('-')[0]]) {
37156 currentLocale = _.split('-')[0];
37160 function addTranslation(id, value) {
37161 translations[id] = value;
37165 * Given a string identifier, try to find that string in the current
37166 * language, and return it.
37168 * @param {string} s string identifier
37169 * @returns {string?} locale string
37171 function t(s, o, loc) {
37172 loc = loc || currentLocale;
37174 var path = s.split('.').reverse();
37175 var rep = translations[loc];
37177 while (rep !== undefined && path.length) rep = rep[path.pop()];
37179 if (rep !== undefined) {
37180 if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
37184 if (loc !== 'en') {
37185 return t(s, o, 'en');
37188 if (o && 'default' in o) {
37192 var missing = 'Missing ' + loc + ' translation: ' + s;
37193 if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
37199 * Given string 'ltr' or 'rtl', save that setting
37201 * @param {string} s ltr or rtl
37204 function setTextDirection(dir) {
37205 textDirection = dir;
37210 function utilDetect(force) {
37211 if (detected && !force) return detected;
37214 var ua = navigator.userAgent,
37217 m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); // Edge
37219 detected.browser = m[1];
37220 detected.version = m[2];
37222 if (!detected.browser) {
37223 m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); // IE11
37225 detected.browser = 'msie';
37226 detected.version = m[1];
37229 if (!detected.browser) {
37230 m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); // Opera 15+
37232 detected.browser = 'Opera';
37233 detected.version = m[2];
37236 if (!detected.browser) {
37237 m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
37239 detected.browser = m[1];
37240 detected.version = m[2];
37241 m = ua.match(/version\/([\.\d]+)/i);
37242 if (m !== null) detected.version = m[1];
37245 if (!detected.browser) {
37246 detected.browser = navigator.appName;
37247 detected.version = navigator.appVersion;
37250 // keep major.minor version only..
37251 detected.version = detected.version.split(/\W/).slice(0,2).join('.');
37253 if (detected.browser.toLowerCase() === 'msie') {
37254 detected.ie = true;
37255 detected.browser = 'Internet Explorer';
37256 detected.support = parseFloat(detected.version) >= 11;
37258 detected.ie = false;
37259 detected.support = true;
37262 // Added due to incomplete svg style support. See #715
37263 detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
37265 detected.locale = (navigator.languages && navigator.languages.length)
37266 ? navigator.languages[0] : (navigator.language || navigator.userLanguage || 'en-US');
37268 // Loaded locale is stored in currentLocale
37269 // return that instead (except in the situation where 'en' might override 'en-US')
37270 var loadedLocale = currentLocale || 'en';
37271 if (loadedLocale !== 'en') {
37272 detected.locale = loadedLocale;
37275 // detect text direction
37276 var q = utilStringQs(window.location.hash.substring(1));
37277 var lang = dataLocales[detected.locale];
37278 if ((lang && lang.rtl) || q.hasOwnProperty('rtl')) {
37279 detected.textDirection = 'rtl';
37281 detected.textDirection = 'ltr';
37283 setTextDirection(detected.textDirection);
37285 detected.host = window.location && (window.location.origin + window.location.pathname);
37287 detected.filedrop = (window.FileReader && 'ondrop' in window);
37290 return navigator.userAgent.indexOf(x) !== -1;
37294 detected.os = 'win';
37295 detected.platform = 'Windows';
37297 else if (nav('Mac')) {
37298 detected.os = 'mac';
37299 detected.platform = 'Macintosh';
37301 else if (nav('X11') || nav('Linux')) {
37302 detected.os = 'linux';
37303 detected.platform = 'Linux';
37306 detected.os = 'win';
37307 detected.platform = 'Unknown';
37313 var remove$1 = removeDiacritics;
37315 var replacementList = [
37324 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",
37330 chars: "\u00C6\u01FC\u01E2",
37339 chars: "\uA738\uA73A",
37345 chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
37348 chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
37351 chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
37357 chars: "\u01F1\u01C4",
37360 chars: "\u01F2\u01C5",
37363 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",
37366 chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
37369 chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
37372 chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
37375 chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
37378 chars: "\u24BF\uFF2A\u0134\u0248\u0237",
37381 chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
37384 chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
37393 chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
37396 chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
37405 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",
37420 chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
37423 chars: "\u24C6\uFF31\uA756\uA758\u024A",
37426 chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
37429 chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
37432 chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
37441 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",
37444 chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
37450 chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
37453 chars: "\u24CD\uFF38\u1E8A\u1E8C",
37456 chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
37459 chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
37462 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",
37468 chars: "\u00E6\u01FD\u01E3",
37477 chars: "\uA739\uA73B",
37483 chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
37486 chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
37489 chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
37495 chars: "\u01F3\u01C6",
37498 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",
37501 chars: "\u24D5\uFF46\u1E1F\u0192",
37519 chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
37522 chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
37528 chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
37531 chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
37534 chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
37537 chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
37543 chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
37546 chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
37552 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",
37567 chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
37570 chars: "\u24E0\uFF51\u024B\uA757\uA759",
37573 chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
37576 chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
37582 chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
37591 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",
37594 chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
37600 chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
37603 chars: "\u24E7\uFF58\u1E8B\u1E8D",
37606 chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
37609 chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
37613 var diacriticsMap = {};
37614 for (var i = 0; i < replacementList.length; i += 1) {
37615 var chars = replacementList[i].chars;
37616 for (var j = 0; j < chars.length; j += 1) {
37617 diacriticsMap[chars[j]] = replacementList[i].base;
37621 function removeDiacritics(str) {
37622 return str.replace(/[^\u0000-\u007e]/g, function(c) {
37623 return diacriticsMap[c] || c;
37627 // see https://github.com/openstreetmap/iD/pull/3707
37628 // https://gist.github.com/mapmeld/556b09ddec07a2044c76e1ef45f01c60
37631 // madda above alef
37632 1570: { initial: 'آ', isolated: 'ﺁ', medial: 'ﺁ', final: 'ﺂ' },
37634 // hamza above and below alef
37635 1571: { initial: 'أ', isolated: 'ﺃ', medial: '', final: 'ﺄ' },
37637 1573: { initial: 'إ', isolated: 'ﺇ', medial: '', final: 'ﺈ' },
37639 1575: { initial: 'ا', isolated: 'ا', medial: '', final: 'ﺎ' },
37640 1576: { initial: 'ﺑ', isolated: 'ﺏ', medial: 'ﺒ', final: 'ﺐ' },
37643 1577: { initial: '', isolated: 'ة', medial: '', final: 'ﺔ' },
37645 1578: { initial: 'ﺗ', isolated: 'ﺕ', medial: 'ﺘ', final: 'ﺖ' },
37646 1579: { initial: 'ﺛ', isolated: 'ﺙ', medial: 'ﺜ', final: 'ﺚ' },
37647 1580: { initial: 'ﺟ', isolated: 'ﺝ', medial: 'ﺠ', final: 'ﺞ' },
37648 1581: { initial: 'ﺣ', isolated: 'ﺡ', medial: 'ﺤ', final: 'ﺢ' },
37649 1582: { initial: 'ﺧ', isolated: 'ﺥ', medial: 'ﺨ', final: 'ﺦ' },
37650 1583: { initial: 'ﺩ', isolated: 'ﺩ', medial: '', final: 'ﺪ' },
37651 1584: { initial: 'ﺫ', isolated: 'ﺫ', medial: '', final: 'ﺬ' },
37652 1585: { initial: 'ﺭ', isolated: 'ﺭ', medial: '', final: 'ﺮ' },
37653 1586: { initial: 'ﺯ', isolated: 'ﺯ', medial: '', final: 'ﺰ' },
37654 1688: { initial: 'ﮊ', isolated: 'ﮊ', medial: '', final: 'ﮋ' },
37655 1587: { initial: 'ﺳ', isolated: 'ﺱ', medial: 'ﺴ', final: 'ﺲ' },
37656 1588: { initial: 'ﺷ', isolated: 'ﺵ', medial: 'ﺸ', final: 'ﺶ' },
37657 1589: { initial: 'ﺻ', isolated: 'ﺹ', medial: 'ﺼ', final: 'ﺺ' },
37658 1590: { initial: 'ﺿ', isolated: 'ﺽ', medial: 'ﻀ', final: 'ﺾ' },
37659 1591: { initial: 'ﻃ', isolated: 'ﻁ', medial: 'ﻄ', final: 'ﻂ' },
37660 1592: { initial: 'ﻇ', isolated: 'ﻅ', medial: 'ﻈ', final: 'ﻆ' },
37661 1593: { initial: 'ﻋ', isolated: 'ﻉ', medial: 'ﻌ', final: 'ﻊ' },
37662 1594: { initial: 'ﻏ', isolated: 'ﻍ', medial: 'ﻐ', final: 'ﻎ' },
37664 // 1595 ػ - may be very rare
37666 1601: { initial: 'ﻓ', isolated: 'ﻑ', medial: 'ﻔ', final: 'ﻒ' },
37667 1602: { initial: 'ﻗ', isolated: 'ﻕ', medial: 'ﻘ', final: 'ﻖ' },
37668 1604: { initial: 'ﻟ', isolated: 'ﻝ', medial: 'ﻠ', final: 'ﻞ' },
37669 1605: { initial: 'ﻣ', isolated: 'ﻡ', medial: 'ﻤ', final: 'ﻢ' },
37670 1606: { initial: 'ﻧ', isolated: 'ﻥ', medial: 'ﻨ', final: 'ﻦ' },
37671 1607: { initial: 'ﻫ', isolated: 'ﻩ', medial: 'ﻬ', final: 'ﻪ' },
37672 1608: { initial: 'ﻭ', isolated: 'ﻭ', medial: '', final: 'ﻮ' },
37675 1609: { initial: 'ﯨ', isolated: 'ﻯ', medial: 'ﯩ', final: 'ﻰ' },
37677 1610: { initial: 'ﻳ', isolated: 'ﻱ', medial: 'ﻴ', final: 'ﻲ' },
37679 // short vowel sounds / tashkil markings
37681 1662: { initial: 'ﭘ', isolated: 'ﭖ', medial: 'ﭙ', final: 'ﭗ' },
37683 1670: { initial: 'ﭼ', isolated: 'ﭺ', medial: 'ﭽ', final: 'ﭻ' },
37684 1603: { initial: 'ﻛ', isolated: 'ﻙ', medial: 'ﻜ', final: 'ﻚ' },
37685 1705: { initial: 'ﻛ', isolated: 'ﮎ', medial: 'ﻜ', final: 'ﮏ' },
37686 1711: { initial: 'ﮔ', isolated: 'ﮒ', medial: 'ﮕ', final: 'ﮓ' },
37687 1740: { initial: 'ﻳ', isolated: 'ﻯ', medial: 'ﻴ', final: 'ﻰ' },
37688 5000: { initial: 'ﻻ', isolated: 'ﻻ', medial: '', final: 'ﻼ' }
37692 function fixArabicScriptTextForSvg(inputText) {
37693 var context = true;
37695 var rtlBuffer = [];
37697 for (var i = 0, l = inputText.length; i < l; i++) {
37698 var code = inputText[i].charCodeAt(0);
37699 var nextCode = inputText[i + 1] ? inputText[i + 1].charCodeAt(0) : 0;
37701 if (!chars$1[code]) {
37702 if (code === 32 && rtlBuffer.length) {
37704 rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
37706 // non-RTL character
37707 ret += rtlBuffer.reverse().join('') + inputText[i];
37713 if (i === l - 1 || nextCode === 32) {
37714 rtlBuffer.push(chars$1[code].isolated);
37716 // special case for لا
37717 if (code === 1604 && nextCode === 1575) {
37718 rtlBuffer.push(chars$1[5000].initial);
37723 rtlBuffer.push(chars$1[code].initial);
37726 if (i === l - 1 || nextCode === 32){
37727 rtlBuffer.push(chars$1[code].final);
37729 // special case for ﻼ
37730 if (code === 1604 && nextCode === 1575){
37731 rtlBuffer.push(chars$1[5000].final);
37736 if (chars$1[code].medial === ''){
37737 rtlBuffer.push(chars$1[code].final);
37739 rtlBuffer.push(chars$1[code].medial);
37743 context = (chars$1[code].medial === '') || nextCode === 32;
37746 ret += rtlBuffer.reverse().join('');
37750 function utilTagText(entity) {
37751 return entries(entity.tags).map(function(e) {
37752 return e.key + '=' + e.value;
37757 function utilEntitySelector(ids) {
37758 return ids.length ? '.' + ids.join(',.') : 'nothing';
37762 function utilEntityOrMemberSelector(ids, graph) {
37763 var s = utilEntitySelector(ids);
37765 ids.forEach(function(id) {
37766 var entity = graph.hasEntity(id);
37767 if (entity && entity.type === 'relation') {
37768 entity.members.forEach(function(member) {
37769 s += ',.' + member.id;
37778 function utilGetAllNodes(ids, graph) {
37781 ids.forEach(getNodes);
37784 function getNodes(id) {
37785 if (seen[id]) return;
37788 var entity = graph.hasEntity(id);
37789 if (!entity) return;
37791 if (entity.type === 'node') {
37792 nodes.push(entity);
37793 } else if (entity.type === 'way') {
37794 entity.nodes.forEach(getNodes);
37796 entity.members.map(function(member) { return member.id; }).forEach(getNodes);
37802 function utilDisplayName(entity) {
37803 var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
37804 name = entity.tags[localizedNameKey] || entity.tags.name || '',
37805 network = entity.tags.cycle_network || entity.tags.network;
37807 if (!name && entity.tags.ref) {
37808 name = entity.tags.ref;
37810 name = network + ' ' + name;
37818 function utilDisplayNameForPath(entity) {
37819 var name = utilDisplayName(entity);
37820 var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1;
37821 var arabicRegex = /[\u0600-\u06FF]/g;
37823 if (!isFirefox && name && arabicRegex.test(name)) {
37824 name = fixArabicScriptTextForSvg(name);
37831 function utilDisplayType(id) {
37833 n: t('inspector.node'),
37834 w: t('inspector.way'),
37835 r: t('inspector.relation')
37840 function utilStringQs(str) {
37841 return str.split('&').reduce(function(obj, pair){
37842 var parts = pair.split('=');
37843 if (parts.length === 2) {
37844 obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
37851 function utilQsString(obj, noencode) {
37852 function softEncode(s) {
37853 // encode everything except special characters used in certain hash parameters:
37854 // "/" in map states, ":", ",", {" and "}" in background
37855 return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
37857 return Object.keys(obj).sort().map(function(key) {
37858 return encodeURIComponent(key) + '=' + (
37859 noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
37864 function utilPrefixDOMProperty(property) {
37865 var prefixes = ['webkit', 'ms', 'moz', 'o'],
37867 n = prefixes.length,
37873 property = property.substr(0, 1).toUpperCase() + property.substr(1);
37876 if (prefixes[i] + property in s)
37877 return prefixes[i] + property;
37883 function utilPrefixCSSProperty(property) {
37884 var prefixes = ['webkit', 'ms', 'Moz', 'O'],
37886 n = prefixes.length,
37887 s = document.body.style;
37889 if (property.toLowerCase() in s)
37890 return property.toLowerCase();
37893 if (prefixes[i] + property in s)
37894 return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
37900 var transformProperty;
37901 function utilSetTransform(el, x, y, scale) {
37902 var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
37903 translate = utilDetect().opera ?
37904 'translate(' + x + 'px,' + y + 'px)' :
37905 'translate3d(' + x + 'px,' + y + 'px,0)';
37906 return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
37910 // Calculates Levenshtein distance between two strings
37911 // see: https://en.wikipedia.org/wiki/Levenshtein_distance
37912 // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents.
37913 function utilEditDistance(a, b) {
37914 a = remove$1(a.toLowerCase());
37915 b = remove$1(b.toLowerCase());
37916 if (a.length === 0) return b.length;
37917 if (b.length === 0) return a.length;
37919 for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
37920 for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
37921 for (i = 1; i <= b.length; i++) {
37922 for (j = 1; j <= a.length; j++) {
37923 if (b.charAt(i-1) === a.charAt(j-1)) {
37924 matrix[i][j] = matrix[i-1][j-1];
37926 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
37927 Math.min(matrix[i][j-1] + 1, // insertion
37928 matrix[i-1][j] + 1)); // deletion
37932 return matrix[b.length][a.length];
37936 // a d3.mouse-alike which
37937 // 1. Only works on HTML elements, not SVG
37938 // 2. Does not cause style recalculation
37939 function utilFastMouse(container) {
37940 var rect = container.getBoundingClientRect(),
37941 rectLeft = rect.left,
37942 rectTop = rect.top,
37943 clientLeft = +container.clientLeft,
37944 clientTop = +container.clientTop;
37945 if (textDirection === 'rtl') {
37948 return function(e) {
37950 e.clientX - rectLeft - clientLeft,
37951 e.clientY - rectTop - clientTop];
37956 /* eslint-disable no-proto */
37957 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
37958 /* eslint-enable no-proto */
37961 function utilAsyncMap(inputs, func, callback) {
37962 var remaining = inputs.length,
37966 inputs.forEach(function(d, i) {
37967 func(d, function done(err, data) {
37971 if (!remaining) callback(errors, results);
37977 // wraps an index to an interval [0..length-1]
37978 function utilWrap(index, length) {
37980 index += Math.ceil(-index/length)*length;
37981 return index % length;
37986 * a replacement for functor
37988 * @param {*} value any value
37989 * @returns {Function} a function that returns that value or the value if it's a function
37991 function utilFunctor(value) {
37992 if (typeof value === 'function') return value;
37993 return function() {
37998 // A per-domain session mutex backed by a cookie and dead man's
37999 // switch. If the session crashes, the mutex will auto-release
38000 // after 5 seconds.
38002 function utilSessionMutex(name) {
38007 var expires = new Date();
38008 expires.setSeconds(expires.getSeconds() + 5);
38009 document.cookie = name + '=1; expires=' + expires.toUTCString();
38012 mutex.lock = function() {
38013 if (intervalID) return true;
38014 var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
38015 if (cookie) return false;
38017 intervalID = window.setInterval(renew, 4000);
38021 mutex.unlock = function() {
38022 if (!intervalID) return;
38023 document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
38024 clearInterval(intervalID);
38028 mutex.locked = function() {
38029 return !!intervalID;
38035 function utilSuggestNames(preset, suggestions) {
38036 preset = preset.id.split('/', 2);
38040 return function(value, callback) {
38042 if (value && value.length > 2) {
38043 if (suggestions[k] && suggestions[k][v]) {
38044 for (var sugg in suggestions[k][v]) {
38045 var dist = utilEditDistance(value, sugg.substring(0, value.length));
38055 result.sort(function(a, b) {
38056 return a.dist - b.dist;
38059 result = result.slice(0,3);
38064 function utilTriggerEvent(target, type) {
38065 target.each(function() {
38066 var evt = document.createEvent('HTMLEvents');
38067 evt.initEvent(type, true, true);
38068 this.dispatchEvent(evt);
38072 // Like selection.property('value', ...), but avoids no-op value sets,
38073 // which can result in layout/repaint thrashing in some situations.
38074 function utilGetSetValue(selection, value) {
38075 function d3_selection_value(value) {
38076 function valueNull() {
38080 function valueConstant() {
38081 if (this.value !== value) {
38082 this.value = value;
38086 function valueFunction() {
38087 var x = value.apply(this, arguments);
38090 } else if (this.value !== x) {
38095 return value == null
38096 ? valueNull : (typeof value === 'function'
38097 ? valueFunction : valueConstant);
38100 if (arguments.length === 1) {
38101 return selection.property('value');
38104 return selection.each(d3_selection_value(value));
38107 function validationDeprecatedTag() {
38109 var validation = function(changes) {
38111 for (var i = 0; i < changes.created.length; i++) {
38112 var change = changes.created[i],
38113 deprecatedTags = change.deprecatedTags();
38115 if (!lodash.isEmpty(deprecatedTags)) {
38116 var tags = utilTagText({ tags: deprecatedTags });
38118 id: 'deprecated_tags',
38119 message: t('validations.deprecated_tags', { tags: tags }),
38132 function validationDisconnectedHighway() {
38135 function isDisconnectedHighway(entity, graph) {
38136 if (!entity.tags.highway) return false;
38137 if (entity.geometry(graph) !== 'line') return false;
38139 return graph.childNodes(entity)
38140 .every(function(vertex) {
38141 return graph.parentWays(vertex)
38142 .filter(function(parent) {
38143 return parent.tags.highway && parent !== entity;
38150 var validation = function(changes, graph) {
38152 for (var i = 0; i < changes.created.length; i++) {
38153 var entity = changes.created[i];
38155 if (isDisconnectedHighway(entity, graph)) {
38158 message: t('validations.disconnected_highway'),
38159 tooltip: t('validations.disconnected_highway_tooltip'),
38172 function validationManyDeletions() {
38173 var threshold = 100;
38175 var validation = function(changes) {
38177 if (changes.deleted.length > threshold) {
38179 id: 'many_deletions',
38180 message: t('validations.many_deletions', { n: changes.deleted.length })
38191 function validationMissingTag() {
38193 // Slightly stricter check than Entity#isUsed (#3091)
38194 function hasTags(entity, graph) {
38195 return lodash.without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
38196 graph.parentRelations(entity).length > 0;
38199 var validation = function(changes, graph) {
38200 var types = ['point', 'line', 'area', 'relation'],
38203 for (var i = 0; i < changes.created.length; i++) {
38204 var change = changes.created[i],
38205 geometry = change.geometry(graph);
38207 if (types.indexOf(geometry) !== -1 && !hasTags(change, graph)) {
38210 message: t('validations.untagged_' + geometry),
38211 tooltip: t('validations.untagged_' + geometry + '_tooltip'),
38224 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
38225 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
38226 function validationTagSuggestsArea() {
38228 function tagSuggestsArea(tags) {
38229 if (lodash.isEmpty(tags)) return false;
38231 var presence = ['landuse', 'amenities', 'tourism', 'shop'];
38232 for (var i = 0; i < presence.length; i++) {
38233 if (tags[presence[i]] !== undefined) {
38234 return presence[i] + '=' + tags[presence[i]];
38238 if (tags.building && tags.building === 'yes') return 'building=yes';
38242 var validation = function(changes, graph) {
38244 for (var i = 0; i < changes.created.length; i++) {
38245 var change = changes.created[i],
38246 geometry = change.geometry(graph),
38247 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
38251 id: 'tag_suggests_area',
38252 message: t('validations.tag_suggests_area', { tag: suggestion }),
38267 var Validations = Object.freeze({
38268 validationDeprecatedTag: validationDeprecatedTag,
38269 validationDisconnectedHighway: validationDisconnectedHighway,
38270 validationManyDeletions: validationManyDeletions,
38271 validationMissingTag: validationMissingTag,
38272 validationTagSuggestsArea: validationTagSuggestsArea
38276 iD.Difference represents the difference between two graphs.
38277 It knows how to calculate the set of entities that were
38278 created, modified, or deleted, and also contains the logic
38279 for recursively extending a difference to the complete set
38280 of entities that will require a redraw, taking into account
38281 child and parent relationships.
38283 function coreDifference(base, head) {
38289 function changed(h, b) {
38290 return h !== b && !lodash.isEqual(lodash.omit(h, 'v'), lodash.omit(b, 'v'));
38294 lodash.each(head.entities, function(h, id) {
38295 var b = base.entities[id];
38296 if (changed(h, b)) {
38297 changes[id] = {base: b, head: h};
38303 lodash.each(base.entities, function(b, id) {
38304 var h = head.entities[id];
38305 if (!changes[id] && changed(h, b)) {
38306 changes[id] = {base: b, head: h};
38312 function addParents(parents, result) {
38313 for (var i = 0; i < parents.length; i++) {
38314 var parent = parents[i];
38316 if (parent.id in result)
38319 result[parent.id] = parent;
38320 addParents(head.parentRelations(parent), result);
38325 difference.length = function() {
38330 difference.changes = function() {
38335 difference.extantIDs = function() {
38337 lodash.each(changes, function(change, id) {
38338 if (change.head) result.push(id);
38344 difference.modified = function() {
38346 lodash.each(changes, function(change) {
38347 if (change.base && change.head) result.push(change.head);
38353 difference.created = function() {
38355 lodash.each(changes, function(change) {
38356 if (!change.base && change.head) result.push(change.head);
38362 difference.deleted = function() {
38364 lodash.each(changes, function(change) {
38365 if (change.base && !change.head) result.push(change.base);
38371 difference.summary = function() {
38374 function addEntity(entity, graph, changeType) {
38375 relevant[entity.id] = {
38378 changeType: changeType
38382 function addParents(entity) {
38383 var parents = head.parentWays(entity);
38384 for (var j = parents.length - 1; j >= 0; j--) {
38385 var parent = parents[j];
38386 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
38390 lodash.each(changes, function(change) {
38391 if (change.head && change.head.geometry(head) !== 'vertex') {
38392 addEntity(change.head, head, change.base ? 'modified' : 'created');
38394 } else if (change.base && change.base.geometry(base) !== 'vertex') {
38395 addEntity(change.base, base, 'deleted');
38397 } else if (change.base && change.head) { // modified vertex
38398 var moved = !lodash.isEqual(change.base.loc, change.head.loc),
38399 retagged = !lodash.isEqual(change.base.tags, change.head.tags);
38402 addParents(change.head);
38405 if (retagged || (moved && change.head.hasInterestingTags())) {
38406 addEntity(change.head, head, 'modified');
38409 } else if (change.head && change.head.hasInterestingTags()) { // created vertex
38410 addEntity(change.head, head, 'created');
38412 } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
38413 addEntity(change.base, base, 'deleted');
38417 return values(relevant);
38421 difference.complete = function(extent$$1) {
38422 var result = {}, id, change;
38424 for (id in changes) {
38425 change = changes[id];
38427 var h = change.head,
38432 (!h || !h.intersects(extent$$1, head)) &&
38433 (!b || !b.intersects(extent$$1, base)))
38438 if (entity.type === 'way') {
38439 var nh = h ? h.nodes : [],
38440 nb = b ? b.nodes : [],
38443 diff = lodash.difference(nh, nb);
38444 for (i = 0; i < diff.length; i++) {
38445 result[diff[i]] = head.hasEntity(diff[i]);
38448 diff = lodash.difference(nb, nh);
38449 for (i = 0; i < diff.length; i++) {
38450 result[diff[i]] = head.hasEntity(diff[i]);
38454 addParents(head.parentWays(entity), result);
38455 addParents(head.parentRelations(entity), result);
38465 function coreGraph$$1(other, mutable) {
38466 if (!(this instanceof coreGraph$$1)) return new coreGraph$$1(other, mutable);
38468 if (other instanceof coreGraph$$1) {
38469 var base = other.base();
38470 this.entities = lodash.assign(Object.create(base.entities), other.entities);
38471 this._parentWays = lodash.assign(Object.create(base.parentWays), other._parentWays);
38472 this._parentRels = lodash.assign(Object.create(base.parentRels), other._parentRels);
38475 this.entities = Object.create({});
38476 this._parentWays = Object.create({});
38477 this._parentRels = Object.create({});
38478 this.rebase(other || [], [this]);
38481 this.transients = {};
38482 this._childNodes = {};
38483 this.frozen = !mutable;
38487 coreGraph$$1.prototype = {
38489 hasEntity: function(id) {
38490 return this.entities[id];
38494 entity: function(id) {
38495 var entity = this.entities[id];
38497 throw new Error('entity ' + id + ' not found');
38503 transient: function(entity, key, fn) {
38504 var id = entity.id,
38505 transients = this.transients[id] ||
38506 (this.transients[id] = {});
38508 if (transients[key] !== undefined) {
38509 return transients[key];
38512 transients[key] = fn.call(entity);
38514 return transients[key];
38518 parentWays: function(entity) {
38519 var parents = this._parentWays[entity.id],
38523 for (var i = 0; i < parents.length; i++) {
38524 result.push(this.entity(parents[i]));
38531 isPoi: function(entity) {
38532 var parentWays = this._parentWays[entity.id];
38533 return !parentWays || parentWays.length === 0;
38537 isShared: function(entity) {
38538 var parentWays = this._parentWays[entity.id];
38539 return parentWays && parentWays.length > 1;
38543 parentRelations: function(entity) {
38544 var parents = this._parentRels[entity.id],
38548 for (var i = 0; i < parents.length; i++) {
38549 result.push(this.entity(parents[i]));
38556 childNodes: function(entity) {
38557 if (this._childNodes[entity.id]) return this._childNodes[entity.id];
38558 if (!entity.nodes) return [];
38561 for (var i = 0; i < entity.nodes.length; i++) {
38562 nodes[i] = this.entity(entity.nodes[i]);
38565 if (debug) Object.freeze(nodes);
38567 this._childNodes[entity.id] = nodes;
38568 return this._childNodes[entity.id];
38574 'entities': utilGetPrototypeOf(this.entities),
38575 'parentWays': utilGetPrototypeOf(this._parentWays),
38576 'parentRels': utilGetPrototypeOf(this._parentRels)
38581 // Unlike other graph methods, rebase mutates in place. This is because it
38582 // is used only during the history operation that merges newly downloaded
38583 // data into each state. To external consumers, it should appear as if the
38584 // graph always contained the newly downloaded data.
38585 rebase: function(entities, stack, force) {
38586 var base = this.base(),
38589 for (i = 0; i < entities.length; i++) {
38590 var entity = entities[i];
38592 if (!entity.visible || (!force && base.entities[entity.id]))
38595 // Merging data into the base graph
38596 base.entities[entity.id] = entity;
38597 this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
38599 // Restore provisionally-deleted nodes that are discovered to have an extant parent
38600 if (entity.type === 'way') {
38601 for (j = 0; j < entity.nodes.length; j++) {
38602 id = entity.nodes[j];
38603 for (k = 1; k < stack.length; k++) {
38604 var ents = stack[k].entities;
38605 if (ents.hasOwnProperty(id) && ents[id] === undefined) {
38613 for (i = 0; i < stack.length; i++) {
38614 stack[i]._updateRebased();
38619 _updateRebased: function() {
38620 var base = this.base(),
38621 i, k, child, id, keys;
38623 keys = Object.keys(this._parentWays);
38624 for (i = 0; i < keys.length; i++) {
38626 if (base.parentWays[child]) {
38627 for (k = 0; k < base.parentWays[child].length; k++) {
38628 id = base.parentWays[child][k];
38629 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentWays[child], id)) {
38630 this._parentWays[child].push(id);
38636 keys = Object.keys(this._parentRels);
38637 for (i = 0; i < keys.length; i++) {
38639 if (base.parentRels[child]) {
38640 for (k = 0; k < base.parentRels[child].length; k++) {
38641 id = base.parentRels[child][k];
38642 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentRels[child], id)) {
38643 this._parentRels[child].push(id);
38649 this.transients = {};
38651 // this._childNodes is not updated, under the assumption that
38652 // ways are always downloaded with their child nodes.
38656 // Updates calculated properties (parentWays, parentRels) for the specified change
38657 _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
38659 parentWays = parentWays || this._parentWays;
38660 parentRels = parentRels || this._parentRels;
38662 var type = entity && entity.type || oldentity && oldentity.type,
38663 removed, added, ways, rels, i;
38666 if (type === 'way') {
38668 // Update parentWays
38669 if (oldentity && entity) {
38670 removed = lodash.difference(oldentity.nodes, entity.nodes);
38671 added = lodash.difference(entity.nodes, oldentity.nodes);
38672 } else if (oldentity) {
38673 removed = oldentity.nodes;
38675 } else if (entity) {
38677 added = entity.nodes;
38679 for (i = 0; i < removed.length; i++) {
38680 parentWays[removed[i]] = lodash.without(parentWays[removed[i]], oldentity.id);
38682 for (i = 0; i < added.length; i++) {
38683 ways = lodash.without(parentWays[added[i]], entity.id);
38684 ways.push(entity.id);
38685 parentWays[added[i]] = ways;
38688 } else if (type === 'relation') {
38690 // Update parentRels
38691 if (oldentity && entity) {
38692 removed = lodash.difference(oldentity.members, entity.members);
38693 added = lodash.difference(entity.members, oldentity);
38694 } else if (oldentity) {
38695 removed = oldentity.members;
38697 } else if (entity) {
38699 added = entity.members;
38701 for (i = 0; i < removed.length; i++) {
38702 parentRels[removed[i].id] = lodash.without(parentRels[removed[i].id], oldentity.id);
38704 for (i = 0; i < added.length; i++) {
38705 rels = lodash.without(parentRels[added[i].id], entity.id);
38706 rels.push(entity.id);
38707 parentRels[added[i].id] = rels;
38713 replace: function(entity) {
38714 if (this.entities[entity.id] === entity)
38717 return this.update(function() {
38718 this._updateCalculated(this.entities[entity.id], entity);
38719 this.entities[entity.id] = entity;
38724 remove: function(entity) {
38725 return this.update(function() {
38726 this._updateCalculated(entity, undefined);
38727 this.entities[entity.id] = undefined;
38732 revert: function(id) {
38733 var baseEntity = this.base().entities[id],
38734 headEntity = this.entities[id];
38736 if (headEntity === baseEntity)
38739 return this.update(function() {
38740 this._updateCalculated(headEntity, baseEntity);
38741 delete this.entities[id];
38746 update: function() {
38747 var graph = this.frozen ? coreGraph$$1(this, true) : this;
38749 for (var i = 0; i < arguments.length; i++) {
38750 arguments[i].call(graph, graph);
38753 if (this.frozen) graph.frozen = true;
38759 // Obliterates any existing entities
38760 load: function(entities) {
38761 var base = this.base();
38762 this.entities = Object.create(base.entities);
38764 for (var i in entities) {
38765 this.entities[i] = entities[i];
38766 this._updateCalculated(base.entities[i], this.entities[i]);
38773 var index$10 = partialSort;
38775 // Floyd-Rivest selection algorithm:
38776 // Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right];
38777 // The k-th element will have the (k - left + 1)th smallest value in [left, right]
38779 function partialSort(arr, k, left, right, compare) {
38781 right = right || (arr.length - 1);
38782 compare = compare || defaultCompare;
38784 while (right > left) {
38785 if (right - left > 600) {
38786 var n = right - left + 1;
38787 var m = k - left + 1;
38788 var z = Math.log(n);
38789 var s = 0.5 * Math.exp(2 * z / 3);
38790 var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
38791 var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
38792 var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
38793 partialSort(arr, k, newLeft, newRight, compare);
38800 swap(arr, left, k);
38801 if (compare(arr[right], t) > 0) swap(arr, left, right);
38807 while (compare(arr[i], t) < 0) i++;
38808 while (compare(arr[j], t) > 0) j--;
38811 if (compare(arr[left], t) === 0) swap(arr, left, j);
38814 swap(arr, j, right);
38817 if (j <= k) left = j + 1;
38818 if (k <= j) right = j - 1;
38822 function swap(arr, i, j) {
38828 function defaultCompare(a, b) {
38829 return a < b ? -1 : a > b ? 1 : 0;
38832 var index$9 = rbush;
38834 var quickselect = index$10;
38836 function rbush(maxEntries, format) {
38837 if (!(this instanceof rbush)) return new rbush(maxEntries, format);
38839 // max entries in a node is 9 by default; min node fill is 40% for best performance
38840 this._maxEntries = Math.max(4, maxEntries || 9);
38841 this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
38844 this._initFormat(format);
38850 rbush.prototype = {
38853 return this._all(this.data, []);
38856 search: function (bbox) {
38858 var node = this.data,
38860 toBBox = this.toBBox;
38862 if (!intersects$1(bbox, node)) return result;
38864 var nodesToSearch = [],
38865 i, len, child, childBBox;
38868 for (i = 0, len = node.children.length; i < len; i++) {
38870 child = node.children[i];
38871 childBBox = node.leaf ? toBBox(child) : child;
38873 if (intersects$1(bbox, childBBox)) {
38874 if (node.leaf) result.push(child);
38875 else if (contains$1(bbox, childBBox)) this._all(child, result);
38876 else nodesToSearch.push(child);
38879 node = nodesToSearch.pop();
38885 collides: function (bbox) {
38887 var node = this.data,
38888 toBBox = this.toBBox;
38890 if (!intersects$1(bbox, node)) return false;
38892 var nodesToSearch = [],
38893 i, len, child, childBBox;
38896 for (i = 0, len = node.children.length; i < len; i++) {
38898 child = node.children[i];
38899 childBBox = node.leaf ? toBBox(child) : child;
38901 if (intersects$1(bbox, childBBox)) {
38902 if (node.leaf || contains$1(bbox, childBBox)) return true;
38903 nodesToSearch.push(child);
38906 node = nodesToSearch.pop();
38912 load: function (data) {
38913 if (!(data && data.length)) return this;
38915 if (data.length < this._minEntries) {
38916 for (var i = 0, len = data.length; i < len; i++) {
38917 this.insert(data[i]);
38922 // recursively build the tree with the given data from stratch using OMT algorithm
38923 var node = this._build(data.slice(), 0, data.length - 1, 0);
38925 if (!this.data.children.length) {
38926 // save as is if tree is empty
38929 } else if (this.data.height === node.height) {
38930 // split root if trees have the same height
38931 this._splitRoot(this.data, node);
38934 if (this.data.height < node.height) {
38935 // swap trees if inserted one is bigger
38936 var tmpNode = this.data;
38941 // insert the small tree into the large tree at appropriate level
38942 this._insert(node, this.data.height - node.height - 1, true);
38948 insert: function (item) {
38949 if (item) this._insert(item, this.data.height - 1);
38953 clear: function () {
38954 this.data = createNode([]);
38958 remove: function (item, equalsFn) {
38959 if (!item) return this;
38961 var node = this.data,
38962 bbox = this.toBBox(item),
38965 i, parent, index, goingUp;
38967 // depth-first iterative tree traversal
38968 while (node || path.length) {
38970 if (!node) { // go up
38972 parent = path[path.length - 1];
38977 if (node.leaf) { // check current node
38978 index = findItem(item, node.children, equalsFn);
38980 if (index !== -1) {
38981 // item found, remove the item and condense tree upwards
38982 node.children.splice(index, 1);
38984 this._condense(path);
38989 if (!goingUp && !node.leaf && contains$1(node, bbox)) { // go down
38994 node = node.children[0];
38996 } else if (parent) { // go right
38998 node = parent.children[i];
39001 } else node = null; // nothing found
39007 toBBox: function (item) { return item; },
39009 compareMinX: compareNodeMinX,
39010 compareMinY: compareNodeMinY,
39012 toJSON: function () { return this.data; },
39014 fromJSON: function (data) {
39019 _all: function (node, result) {
39020 var nodesToSearch = [];
39022 if (node.leaf) result.push.apply(result, node.children);
39023 else nodesToSearch.push.apply(nodesToSearch, node.children);
39025 node = nodesToSearch.pop();
39030 _build: function (items, left, right, height) {
39032 var N = right - left + 1,
39033 M = this._maxEntries,
39037 // reached leaf level; return leaf
39038 node = createNode(items.slice(left, right + 1));
39039 calcBBox(node, this.toBBox);
39044 // target height of the bulk-loaded tree
39045 height = Math.ceil(Math.log(N) / Math.log(M));
39047 // target number of root entries to maximize storage utilization
39048 M = Math.ceil(N / Math.pow(M, height - 1));
39051 node = createNode([]);
39053 node.height = height;
39055 // split the items into M mostly square tiles
39057 var N2 = Math.ceil(N / M),
39058 N1 = N2 * Math.ceil(Math.sqrt(M)),
39059 i, j, right2, right3;
39061 multiSelect(items, left, right, N1, this.compareMinX);
39063 for (i = left; i <= right; i += N1) {
39065 right2 = Math.min(i + N1 - 1, right);
39067 multiSelect(items, i, right2, N2, this.compareMinY);
39069 for (j = i; j <= right2; j += N2) {
39071 right3 = Math.min(j + N2 - 1, right2);
39073 // pack each entry recursively
39074 node.children.push(this._build(items, j, right3, height - 1));
39078 calcBBox(node, this.toBBox);
39083 _chooseSubtree: function (bbox, node, level, path) {
39085 var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
39090 if (node.leaf || path.length - 1 === level) break;
39092 minArea = minEnlargement = Infinity;
39094 for (i = 0, len = node.children.length; i < len; i++) {
39095 child = node.children[i];
39096 area = bboxArea(child);
39097 enlargement = enlargedArea(bbox, child) - area;
39099 // choose entry with the least area enlargement
39100 if (enlargement < minEnlargement) {
39101 minEnlargement = enlargement;
39102 minArea = area < minArea ? area : minArea;
39103 targetNode = child;
39105 } else if (enlargement === minEnlargement) {
39106 // otherwise choose one with the smallest area
39107 if (area < minArea) {
39109 targetNode = child;
39114 node = targetNode || node.children[0];
39120 _insert: function (item, level, isNode) {
39122 var toBBox = this.toBBox,
39123 bbox = isNode ? item : toBBox(item),
39126 // find the best node for accommodating the item, saving all nodes along the path too
39127 var node = this._chooseSubtree(bbox, this.data, level, insertPath);
39129 // put the item into the node
39130 node.children.push(item);
39131 extend$1(node, bbox);
39133 // split on node overflow; propagate upwards if necessary
39134 while (level >= 0) {
39135 if (insertPath[level].children.length > this._maxEntries) {
39136 this._split(insertPath, level);
39141 // adjust bboxes along the insertion path
39142 this._adjustParentBBoxes(bbox, insertPath, level);
39145 // split overflowed node into two
39146 _split: function (insertPath, level) {
39148 var node = insertPath[level],
39149 M = node.children.length,
39150 m = this._minEntries;
39152 this._chooseSplitAxis(node, m, M);
39154 var splitIndex = this._chooseSplitIndex(node, m, M);
39156 var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
39157 newNode.height = node.height;
39158 newNode.leaf = node.leaf;
39160 calcBBox(node, this.toBBox);
39161 calcBBox(newNode, this.toBBox);
39163 if (level) insertPath[level - 1].children.push(newNode);
39164 else this._splitRoot(node, newNode);
39167 _splitRoot: function (node, newNode) {
39169 this.data = createNode([node, newNode]);
39170 this.data.height = node.height + 1;
39171 this.data.leaf = false;
39172 calcBBox(this.data, this.toBBox);
39175 _chooseSplitIndex: function (node, m, M) {
39177 var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
39179 minOverlap = minArea = Infinity;
39181 for (i = m; i <= M - m; i++) {
39182 bbox1 = distBBox(node, 0, i, this.toBBox);
39183 bbox2 = distBBox(node, i, M, this.toBBox);
39185 overlap = intersectionArea(bbox1, bbox2);
39186 area = bboxArea(bbox1) + bboxArea(bbox2);
39188 // choose distribution with minimum overlap
39189 if (overlap < minOverlap) {
39190 minOverlap = overlap;
39193 minArea = area < minArea ? area : minArea;
39195 } else if (overlap === minOverlap) {
39196 // otherwise choose distribution with minimum area
39197 if (area < minArea) {
39207 // sorts node children by the best axis for split
39208 _chooseSplitAxis: function (node, m, M) {
39210 var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
39211 compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
39212 xMargin = this._allDistMargin(node, m, M, compareMinX),
39213 yMargin = this._allDistMargin(node, m, M, compareMinY);
39215 // if total distributions margin value is minimal for x, sort by minX,
39216 // otherwise it's already sorted by minY
39217 if (xMargin < yMargin) node.children.sort(compareMinX);
39220 // total margin of all possible split distributions where each node is at least m full
39221 _allDistMargin: function (node, m, M, compare) {
39223 node.children.sort(compare);
39225 var toBBox = this.toBBox,
39226 leftBBox = distBBox(node, 0, m, toBBox),
39227 rightBBox = distBBox(node, M - m, M, toBBox),
39228 margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
39231 for (i = m; i < M - m; i++) {
39232 child = node.children[i];
39233 extend$1(leftBBox, node.leaf ? toBBox(child) : child);
39234 margin += bboxMargin(leftBBox);
39237 for (i = M - m - 1; i >= m; i--) {
39238 child = node.children[i];
39239 extend$1(rightBBox, node.leaf ? toBBox(child) : child);
39240 margin += bboxMargin(rightBBox);
39246 _adjustParentBBoxes: function (bbox, path, level) {
39247 // adjust bboxes along the given tree path
39248 for (var i = level; i >= 0; i--) {
39249 extend$1(path[i], bbox);
39253 _condense: function (path) {
39254 // go through the path, removing empty nodes and updating bboxes
39255 for (var i = path.length - 1, siblings; i >= 0; i--) {
39256 if (path[i].children.length === 0) {
39258 siblings = path[i - 1].children;
39259 siblings.splice(siblings.indexOf(path[i]), 1);
39261 } else this.clear();
39263 } else calcBBox(path[i], this.toBBox);
39267 _initFormat: function (format) {
39268 // data format (minX, minY, maxX, maxY accessors)
39270 // uses eval-type function compilation instead of just accepting a toBBox function
39271 // because the algorithms are very sensitive to sorting functions performance,
39272 // so they should be dead simple and without inner calls
39274 var compareArr = ['return a', ' - b', ';'];
39276 this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
39277 this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
39279 this.toBBox = new Function('a',
39280 'return {minX: a' + format[0] +
39281 ', minY: a' + format[1] +
39282 ', maxX: a' + format[2] +
39283 ', maxY: a' + format[3] + '};');
39287 function findItem(item, items, equalsFn) {
39288 if (!equalsFn) return items.indexOf(item);
39290 for (var i = 0; i < items.length; i++) {
39291 if (equalsFn(item, items[i])) return i;
39296 // calculate node's bbox from bboxes of its children
39297 function calcBBox(node, toBBox) {
39298 distBBox(node, 0, node.children.length, toBBox, node);
39301 // min bounding rectangle of node children from k to p-1
39302 function distBBox(node, k, p, toBBox, destNode) {
39303 if (!destNode) destNode = createNode(null);
39304 destNode.minX = Infinity;
39305 destNode.minY = Infinity;
39306 destNode.maxX = -Infinity;
39307 destNode.maxY = -Infinity;
39309 for (var i = k, child; i < p; i++) {
39310 child = node.children[i];
39311 extend$1(destNode, node.leaf ? toBBox(child) : child);
39317 function extend$1(a, b) {
39318 a.minX = Math.min(a.minX, b.minX);
39319 a.minY = Math.min(a.minY, b.minY);
39320 a.maxX = Math.max(a.maxX, b.maxX);
39321 a.maxY = Math.max(a.maxY, b.maxY);
39325 function compareNodeMinX(a, b) { return a.minX - b.minX; }
39326 function compareNodeMinY(a, b) { return a.minY - b.minY; }
39328 function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }
39329 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
39331 function enlargedArea(a, b) {
39332 return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
39333 (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
39336 function intersectionArea(a, b) {
39337 var minX = Math.max(a.minX, b.minX),
39338 minY = Math.max(a.minY, b.minY),
39339 maxX = Math.min(a.maxX, b.maxX),
39340 maxY = Math.min(a.maxY, b.maxY);
39342 return Math.max(0, maxX - minX) *
39343 Math.max(0, maxY - minY);
39346 function contains$1(a, b) {
39347 return a.minX <= b.minX &&
39348 a.minY <= b.minY &&
39349 b.maxX <= a.maxX &&
39353 function intersects$1(a, b) {
39354 return b.minX <= a.maxX &&
39355 b.minY <= a.maxY &&
39356 b.maxX >= a.minX &&
39360 function createNode(children) {
39362 children: children,
39372 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
39373 // combines selection algorithm with binary divide & conquer approach
39375 function multiSelect(arr, left, right, n, compare) {
39376 var stack = [left, right],
39379 while (stack.length) {
39380 right = stack.pop();
39381 left = stack.pop();
39383 if (right - left <= n) continue;
39385 mid = left + Math.ceil((right - left) / n / 2) * n;
39386 quickselect(arr, mid, left, right, compare);
39388 stack.push(left, mid, mid, right);
39392 function coreTree(head) {
39393 var rtree = index$9(),
39398 function entityBBox(entity) {
39399 var bbox = entity.extent(head).bbox();
39400 bbox.id = entity.id;
39401 bboxes[entity.id] = bbox;
39406 function updateParents(entity, insertions, memo) {
39407 head.parentWays(entity).forEach(function(way) {
39408 if (bboxes[way.id]) {
39409 rtree.remove(bboxes[way.id]);
39410 insertions[way.id] = way;
39412 updateParents(way, insertions, memo);
39415 head.parentRelations(entity).forEach(function(relation) {
39416 if (memo[entity.id]) return;
39417 memo[entity.id] = true;
39418 if (bboxes[relation.id]) {
39419 rtree.remove(bboxes[relation.id]);
39420 insertions[relation.id] = relation;
39422 updateParents(relation, insertions, memo);
39427 tree.rebase = function(entities, force) {
39428 var insertions = {};
39430 for (var i = 0; i < entities.length; i++) {
39431 var entity = entities[i];
39433 if (!entity.visible)
39436 if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
39439 } else if (bboxes[entity.id]) {
39440 rtree.remove(bboxes[entity.id]);
39444 insertions[entity.id] = entity;
39445 updateParents(entity, insertions, {});
39448 rtree.load(lodash.map(insertions, entityBBox));
39454 tree.intersects = function(extent, graph) {
39455 if (graph !== head) {
39456 var diff = coreDifference(head, graph),
39461 diff.deleted().forEach(function(entity) {
39462 rtree.remove(bboxes[entity.id]);
39463 delete bboxes[entity.id];
39466 diff.modified().forEach(function(entity) {
39467 rtree.remove(bboxes[entity.id]);
39468 insertions[entity.id] = entity;
39469 updateParents(entity, insertions, {});
39472 diff.created().forEach(function(entity) {
39473 insertions[entity.id] = entity;
39476 rtree.load(lodash.map(insertions, entityBBox));
39479 return rtree.search(extent.bbox()).map(function(bbox) {
39480 return head.entity(bbox.id);
39489 * This code is licensed under the MIT license.
39491 * Copyright © 2013, iD authors.
39493 * Portions copyright © 2011, Keith Cirkel
39494 * See https://github.com/keithamus/jwerty
39497 function d3keybinding(namespace$$1) {
39500 function matches(binding, event$$1) {
39501 for (var p in binding.event) {
39502 if (event$$1[p] !== binding.event[p])
39508 function testBindings(isCapturing) {
39509 for (var i = 0; i < bindings.length; i++) {
39510 var binding = bindings[i];
39512 if (!!binding.capture === isCapturing && matches(binding, event)) {
39513 binding.callback();
39518 function capture() {
39519 testBindings(true);
39522 function bubble() {
39523 var tagName = select(event.target).node().tagName;
39524 if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
39527 testBindings(false);
39530 function keybinding(selection$$1) {
39531 selection$$1 = selection$$1 || select(document);
39532 selection$$1.on('keydown.capture' + namespace$$1, capture, true);
39533 selection$$1.on('keydown.bubble' + namespace$$1, bubble, false);
39537 keybinding.off = function(selection$$1) {
39539 selection$$1 = selection$$1 || select(document);
39540 selection$$1.on('keydown.capture' + namespace$$1, null);
39541 selection$$1.on('keydown.bubble' + namespace$$1, null);
39545 keybinding.on = function(codes, callback, capture) {
39546 var arr = [].concat(codes);
39547 for (var i = 0; i < arr.length; i++) {
39561 code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
39563 for (var j = 0; j < code.length; j++) {
39564 // Normalise matching errors
39565 if (code[j] === '++') code[i] = '+';
39567 if (code[j] in d3keybinding.modifierCodes) {
39568 binding.event[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
39569 } else if (code[j] in d3keybinding.keyCodes) {
39570 binding.event.keyCode = d3keybinding.keyCodes[code[j]];
39574 bindings.push(binding);
39584 d3keybinding.modifierCodes = {
39586 '⇧': 16, shift: 16,
39587 // CTRL key, on Mac: ⌃
39589 // ALT key, on Mac: ⌥ (Alt)
39590 '⌥': 18, alt: 18, option: 18,
39591 // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
39592 '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
39595 d3keybinding.modifierProperties = {
39602 d3keybinding.keyCodes = {
39603 // Backspace key, on Mac: ⌫ (Backspace)
39604 '⌫': 8, backspace: 8,
39605 // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
39606 '⇥': 9, '⇆': 9, tab: 9,
39608 '↩': 13, 'return': 13, enter: 13, '⌅': 13,
39610 'pause': 19, 'pause-break': 19,
39611 // Caps Lock key, ⇪
39612 '⇪': 20, caps: 20, 'caps-lock': 20,
39613 // Escape key, on Mac: ⎋, on Windows: Esc
39614 '⎋': 27, escape: 27, esc: 27,
39617 // Page-Up key, or pgup, on Mac: ↖
39618 '↖': 33, pgup: 33, 'page-up': 33,
39619 // Page-Down key, or pgdown, on Mac: ↘
39620 '↘': 34, pgdown: 34, 'page-down': 34,
39621 // END key, on Mac: ⇟
39623 // HOME key, on Mac: ⇞
39625 // Insert key, or ins
39626 ins: 45, insert: 45,
39627 // Delete key, on Mac: ⌦ (Delete)
39628 '⌦': 46, del: 46, 'delete': 46,
39629 // Left Arrow Key, or ←
39630 '←': 37, left: 37, 'arrow-left': 37,
39631 // Up Arrow Key, or ↑
39632 '↑': 38, up: 38, 'arrow-up': 38,
39633 // Right Arrow Key, or →
39634 '→': 39, right: 39, 'arrow-right': 39,
39635 // Up Arrow Key, or ↓
39636 '↓': 40, down: 40, 'arrow-down': 40,
39637 // odities, printing characters that come out wrong:
39640 // Num-Multiply, or *
39641 '*': 106, star: 106, asterisk: 106, multiply: 106,
39643 '+': 107, 'plus': 107,
39644 // Num-Subtract, or -
39645 '-': 109, subtract: 109,
39651 ';': 186, semicolon: 186,
39653 '=': 187, 'equals': 187,
39655 ',': 188, comma: 188,
39656 // Dash / Underscore key
39658 // Period, or ., or full-stop
39659 '.': 190, period: 190, 'full-stop': 190,
39660 // Slash, or /, or forward-slash
39661 '/': 191, slash: 191, 'forward-slash': 191,
39662 // Tick, or `, or back-quote
39663 '`': 192, tick: 192, 'back-quote': 192,
39664 // Open bracket, or [
39665 '[': 219, 'open-bracket': 219,
39666 // Back slash, or \
39667 '\\': 220, 'back-slash': 220,
39668 // Close backet, or ]
39669 ']': 221, 'close-bracket': 221,
39670 // Apostrophe, or Quote, or '
39671 '\'': 222, quote: 222, apostrophe: 222
39677 while (++i$1 < 106) {
39678 d3keybinding.keyCodes['num-' + n] = i$1;
39684 while (++i$1 < 58) {
39685 d3keybinding.keyCodes[n] = i$1;
39691 while (++i$1 < 136) {
39692 d3keybinding.keyCodes['f' + n] = i$1;
39698 while (++i$1 < 91) {
39699 d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
39702 function tooltip() {
39703 var tooltip = function(selection$$1) {
39704 selection$$1.each(setup);
39706 animation = utilFunctor(false),
39707 html$$1 = utilFunctor(false),
39708 title = function() {
39709 var title = this.getAttribute('data-original-title');
39713 title = this.getAttribute('title');
39714 this.removeAttribute('title');
39715 this.setAttribute('data-original-title', title);
39719 over = 'mouseenter.tooltip',
39720 out = 'mouseleave.tooltip',
39721 placement = utilFunctor('top');
39724 tooltip.title = function(_) {
39725 if (arguments.length) {
39726 title = utilFunctor(_);
39734 tooltip.html = function(_) {
39735 if (arguments.length) {
39736 html$$1 = utilFunctor(_);
39744 tooltip.placement = function(_) {
39745 if (arguments.length) {
39746 placement = utilFunctor(_);
39754 tooltip.show = function(selection$$1) {
39755 selection$$1.each(show);
39759 tooltip.hide = function(selection$$1) {
39760 selection$$1.each(hide);
39764 tooltip.toggle = function(selection$$1) {
39765 selection$$1.each(toggle);
39769 tooltip.destroy = function(selection$$1) {
39773 .attr('title', function() {
39774 return this.getAttribute('data-original-title') || this.getAttribute('title');
39776 .attr('data-original-title', null)
39777 .selectAll('.tooltip')
39783 var root = select(this),
39784 animate = animation.apply(this, arguments),
39785 tip = root.selectAll('.tooltip').data([0]);
39787 var enter = tip.enter()
39789 .attr('class', 'tooltip');
39793 .attr('class', 'tooltip-arrow');
39797 .attr('class', 'tooltip-inner');
39803 tip.classed('fade', true);
39806 var place = placement.apply(this, arguments);
39807 tip.classed(place, true);
39809 root.on(over, show);
39810 root.on(out, hide);
39815 var root = select(this),
39816 content = title.apply(this, arguments),
39817 tip = root.selectAll('.tooltip')
39818 .classed('in', true),
39819 markup = html$$1.apply(this, arguments);
39821 tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
39822 var place = placement.apply(this, arguments),
39823 outer = getPosition(root.node()),
39824 inner = getPosition(tip.node()),
39829 pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
39832 pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
39835 pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
39838 pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
39843 tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
39845 tip.style('left', null).style('top', null);
39848 this.tooltipVisible = true;
39853 select(this).selectAll('.tooltip')
39854 .classed('in', false);
39856 this.tooltipVisible = false;
39860 function toggle() {
39861 if (this.tooltipVisible) {
39862 hide.apply(this, arguments);
39864 show.apply(this, arguments);
39872 function getPosition(node) {
39873 var mode = select(node).style('position');
39874 if (mode === 'absolute' || mode === 'static') {
39876 x: node.offsetLeft,
39878 w: node.offsetWidth,
39879 h: node.offsetHeight
39885 w: node.offsetWidth,
39886 h: node.offsetHeight
39891 function svgAreas$$1(projection, context) {
39892 // Patterns only work in Firefox when set directly on element.
39893 // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
39896 cemetery: 'cemetery',
39897 construction: 'construction',
39899 farmland: 'farmland',
39900 grave_yard: 'cemetery',
39902 military: 'construction',
39903 orchard: 'orchard',
39906 wetland: 'wetland',
39909 var patternKeys = ['landuse', 'natural', 'amenity'];
39912 function setPattern(d) {
39913 for (var i = 0; i < patternKeys.length; i++) {
39914 if (d.tags.building && d.tags.building !== 'no') continue;
39916 if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
39917 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
39921 this.style.fill = this.style.stroke = '';
39925 return function drawAreas(selection$$1, graph, entities, filter) {
39926 var path$$1 = svgPath(projection, graph, true),
39930 for (var i = 0; i < entities.length; i++) {
39931 var entity = entities[i];
39932 if (entity.geometry(graph) !== 'area') continue;
39934 multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
39935 if (multipolygon) {
39936 areas[multipolygon.id] = {
39937 entity: multipolygon.mergeTags(entity.tags),
39938 area: Math.abs(entity.area(graph))
39940 } else if (!areas[entity.id]) {
39941 areas[entity.id] = {
39943 area: Math.abs(entity.area(graph))
39948 areas = values(areas).filter(function hasPath(a) { return path$$1(a.entity); });
39949 areas.sort(function areaSort(a, b) { return b.area - a.area; });
39950 areas = lodash.map(areas, 'entity');
39952 var strokes = areas.filter(function(area$$1) {
39953 return area$$1.type === 'way';
39963 var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
39965 .data(data.clip, osmEntity$$1.key);
39970 var clipPathsEnter = clipPaths.enter()
39971 .append('clipPath')
39972 .attr('class', 'clipPath')
39973 .attr('id', function(entity) { return entity.id + '-clippath'; });
39978 clipPaths.merge(clipPathsEnter)
39980 .attr('d', path$$1);
39983 var layer = selection$$1.selectAll('.layer-areas');
39985 var areagroup = layer
39986 .selectAll('g.areagroup')
39987 .data(['fill', 'shadow', 'stroke']);
39989 areagroup = areagroup.enter()
39991 .attr('class', function(d) { return 'areagroup area-' + d; })
39994 var paths = areagroup
39997 .data(function(layer) { return data[layer]; }, osmEntity$$1.key);
40002 var fills = selection$$1.selectAll('.area-fill path.area').nodes();
40004 var bisect$$1 = bisector(function(node) {
40005 return -node.__data__.area(graph);
40008 function sortedByArea(entity) {
40009 if (this._parent.__data__ === 'fill') {
40010 return fills[bisect$$1(fills, -entity.area(graph))];
40014 paths = paths.enter()
40015 .insert('path', sortedByArea)
40017 .each(function(entity) {
40018 var layer = this.parentNode.__data__;
40020 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
40022 if (layer === 'fill') {
40023 this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
40024 setPattern.apply(this, arguments);
40027 .call(svgTagClasses())
40028 .attr('d', path$$1);
40032 function svgDebug(projection, context) {
40034 function multipolygons(imagery) {
40035 return imagery.map(function(data$$1) {
40037 type: 'MultiPolygon',
40038 coordinates: [ data$$1.polygon ]
40043 function drawDebug(selection$$1) {
40044 var showsTile = context.getDebug('tile'),
40045 showsCollision = context.getDebug('collision'),
40046 showsImagery = context.getDebug('imagery'),
40047 showsImperial = context.getDebug('imperial'),
40048 showsDriveLeft = context.getDebug('driveLeft'),
40049 path$$1 = index$4(projection);
40052 var debugData = [];
40054 debugData.push({ class: 'red', label: 'tile' });
40056 if (showsCollision) {
40057 debugData.push({ class: 'yellow', label: 'collision' });
40059 if (showsImagery) {
40060 debugData.push({ class: 'orange', label: 'imagery' });
40062 if (showsImperial) {
40063 debugData.push({ class: 'cyan', label: 'imperial' });
40065 if (showsDriveLeft) {
40066 debugData.push({ class: 'green', label: 'driveLeft' });
40070 var legend = select('#content')
40071 .selectAll('.debug-legend')
40072 .data(debugData.length ? [0] : []);
40077 legend = legend.enter()
40079 .attr('class', 'fillD debug-legend')
40083 var legendItems = legend.selectAll('.debug-legend-item')
40084 .data(debugData, function(d) { return d.label; });
40089 legendItems.enter()
40091 .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
40092 .text(function(d) { return d.label; });
40095 var layer = selection$$1.selectAll('.layer-debug')
40096 .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
40101 layer = layer.enter()
40103 .attr('class', 'layer-debug')
40107 var extent$$1 = context.map().extent(),
40108 dataImagery = data.imagery || [],
40109 availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
40110 if (!source.polygon) return false;
40111 return source.polygon.some(function(polygon) {
40112 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
40116 var imagery = layer.selectAll('path.debug-imagery')
40117 .data(showsImagery ? availableImagery : []);
40124 .attr('class', 'debug-imagery debug orange');
40127 var imperial = layer
40128 .selectAll('path.debug-imperial')
40129 .data(showsImperial ? [dataImperial] : []);
40136 .attr('class', 'debug-imperial debug cyan');
40139 var driveLeft = layer
40140 .selectAll('path.debug-drive-left')
40141 .data(showsDriveLeft ? [dataDriveLeft] : []);
40148 .attr('class', 'debug-drive-left debug green');
40152 layer.selectAll('path')
40153 .attr('d', path$$1);
40157 // This looks strange because `enabled` methods on other layers are
40158 // chainable getter/setters, and this one is just a getter.
40159 drawDebug.enabled = function() {
40160 if (!arguments.length) {
40161 return context.getDebug('tile') ||
40162 context.getDebug('collision') ||
40163 context.getDebug('imagery') ||
40164 context.getDebug('imperial') ||
40165 context.getDebug('driveLeft');
40176 A standalone SVG element that contains only a `defs` sub-element. To be
40177 used once globally, since defs IDs must be unique within a document.
40179 function svgDefs(context) {
40181 function SVGSpriteDefinition(id, href) {
40182 return function(defs) {
40184 .mimeType('image/svg+xml')
40185 .response(function(xhr) { return xhr.responseXML; })
40186 .get(function(err, svg) {
40188 defs.node().appendChild(
40189 select(svg.documentElement).attr('id', id).node()
40196 return function drawDefs(selection$$1) {
40197 var defs = selection$$1.append('defs');
40200 defs.append('marker')
40201 .attr('id', 'oneway-marker')
40202 .attr('viewBox', '0 0 10 10')
40205 .attr('markerWidth', 2)
40206 .attr('markerHeight', 2)
40207 .attr('markerUnits', 'strokeWidth')
40208 .attr('orient', 'auto')
40211 .attr('class', 'oneway')
40212 .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')
40213 .attr('stroke', 'none')
40214 .attr('fill', '#000')
40215 .attr('opacity', '0.5');
40218 var patterns = defs.selectAll('pattern')
40220 // pattern name, pattern image name
40221 ['wetland', 'wetland'],
40222 ['construction', 'construction'],
40223 ['cemetery', 'cemetery'],
40224 ['orchard', 'orchard'],
40225 ['farmland', 'farmland'],
40232 .attr('id', function (d) {
40233 return 'pattern-' + d[0];
40236 .attr('height', 32)
40237 .attr('patternUnits', 'userSpaceOnUse');
40239 patterns.append('rect')
40243 .attr('height', 32)
40244 .attr('class', function (d) {
40245 return 'pattern-color-' + d[0];
40248 patterns.append('image')
40252 .attr('height', 32)
40253 .attr('xlink:href', function (d) {
40254 return context.imagePath('pattern/' + d[1] + '.png');
40259 .data([12, 18, 20, 32, 45])
40261 .append('clipPath')
40262 .attr('id', function (d) {
40263 return 'clip-square-' + d;
40268 .attr('width', function (d) {
40271 .attr('height', function (d) {
40275 defs.call(SVGSpriteDefinition(
40277 context.imagePath('iD-sprite.svg')));
40279 defs.call(SVGSpriteDefinition(
40281 context.imagePath('maki-sprite.svg')));
40285 var sax = createCommonjsModule(function (module, exports) {
40286 //[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]
40287 //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
40288 //[5] Name ::= NameStartChar (NameChar)*
40289 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
40290 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]");
40291 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
40292 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
40293 //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(',')
40295 //S_TAG, S_ATTR, S_EQ, S_V
40296 //S_ATTR_S, S_E, S_S, S_C
40297 var S_TAG = 0;//tag name offerring
40298 var S_ATTR = 1;//attr name offerring
40299 var S_ATTR_S=2;//attr name end and space offer
40300 var S_EQ = 3;//=space?
40301 var S_V = 4;//attr value(no quot value only)
40302 var S_E = 5;//attr value end and no space(quot end)
40303 var S_S = 6;//(attr value end || tag end ) && (space offer)
40304 var S_C = 7;//closed el<el />
40306 function XMLReader(){
40310 XMLReader.prototype = {
40311 parse:function(source,defaultNSMap,entityMap){
40312 var domBuilder = this.domBuilder;
40313 domBuilder.startDocument();
40314 _copy(defaultNSMap ,defaultNSMap = {});
40315 parse(source,defaultNSMap,entityMap,
40316 domBuilder,this.errorHandler);
40317 domBuilder.endDocument();
40320 function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
40321 function fixedFromCharCode(code) {
40322 // String.prototype.fromCharCode does not supports
40323 // > 2 bytes unicode chars directly
40324 if (code > 0xffff) {
40326 var surrogate1 = 0xd800 + (code >> 10)
40327 , surrogate2 = 0xdc00 + (code & 0x3ff);
40329 return String.fromCharCode(surrogate1, surrogate2);
40331 return String.fromCharCode(code);
40334 function entityReplacer(a){
40335 var k = a.slice(1,-1);
40336 if(k in entityMap){
40337 return entityMap[k];
40338 }else if(k.charAt(0) === '#'){
40339 return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
40341 errorHandler.error('entity not found:'+a);
40345 function appendText(end){//has some bugs
40347 var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
40348 locator&&position(start);
40349 domBuilder.characters(xt,0,end-start);
40353 function position(p,m){
40354 while(p>=lineEnd && (m = linePattern.exec(source))){
40355 lineStart = m.index;
40356 lineEnd = lineStart + m[0].length;
40357 locator.lineNumber++;
40358 //console.log('line++:',locator,startPos,endPos)
40360 locator.columnNumber = p-lineStart+1;
40364 var linePattern = /.+(?:\r\n?|\n)|.*$/g;
40365 var locator = domBuilder.locator;
40367 var parseStack = [{currentNSMap:defaultNSMapCopy}];
40372 var tagStart = source.indexOf('<',start);
40374 if(!source.substr(start).match(/^\s*$/)){
40375 var doc = domBuilder.document;
40376 var text = doc.createTextNode(source.substr(start));
40377 doc.appendChild(text);
40378 domBuilder.currentElement = text;
40382 if(tagStart>start){
40383 appendText(tagStart);
40385 switch(source.charAt(tagStart+1)){
40387 var end = source.indexOf('>',tagStart+3);
40388 var tagName = source.substring(tagStart+2,end);
40389 var config = parseStack.pop();
40390 var localNSMap = config.localNSMap;
40391 if(config.tagName != tagName){
40392 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
40394 domBuilder.endElement(config.uri,config.localName,tagName);
40396 for(var prefix in localNSMap){
40397 domBuilder.endPrefixMapping(prefix) ;
40403 case '?':// <?...?>
40404 locator&&position(tagStart);
40405 end = parseInstruction(source,tagStart,domBuilder);
40407 case '!':// <!doctype,<![CDATA,<!--
40408 locator&&position(tagStart);
40409 end = parseDCC(source,tagStart,domBuilder,errorHandler);
40413 locator&&position(tagStart);
40415 var el = new ElementAttributes();
40418 var end = parseElementStartPart(source,tagStart,el,entityReplacer,errorHandler);
40419 var len = el.length;
40423 //attribute position fixed
40424 for(var i = 0;i<len;i++){
40426 position(a.offset);
40427 a.offset = copyLocator(locator,{});
40432 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
40434 if(!entityMap.nbsp){
40435 errorHandler.warning('unclosed xml attribute');
40438 appendElement(el,domBuilder,parseStack);
40441 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
40442 end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
40448 errorHandler.error('element parse error: '+e);
40454 //TODO: 这里有可能sax回退,有位置错误风险
40455 appendText(Math.max(tagStart,start)+1);
40459 function copyLocator(f,t){
40460 t.lineNumber = f.lineNumber;
40461 t.columnNumber = f.columnNumber;
40466 * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
40467 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40469 function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
40473 var s = S_TAG;//status
40475 var c = source.charAt(p);
40478 if(s === S_ATTR){//attrName
40479 attrName = source.slice(start,p);
40481 }else if(s === S_ATTR_S){
40484 //fatalError: equal must after attrName or space after attrName
40485 throw new Error('attribute equal must after attrName');
40490 if(s === S_EQ){//equal
40492 p = source.indexOf(c,start);
40494 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40495 el.add(attrName,value,start-1);
40498 //fatalError: no end quot match
40499 throw new Error('attribute value no end \''+c+'\' match');
40501 }else if(s == S_V){
40502 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40503 //console.log(attrName,value,start,p)
40504 el.add(attrName,value,start);
40506 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
40510 //fatalError: no equal before
40511 throw new Error('attribute value must after "="');
40517 el.setTagName(source.slice(start,p));
40529 throw new Error("attribute invalid close char('/')")
40532 case ''://end document
40533 //throw new Error('unexpected end of input')
40534 errorHandler.error('unexpected end of input');
40538 el.setTagName(source.slice(start,p));
40543 case S_V://Compatible state
40545 value = source.slice(start,p);
40546 if(value.slice(-1) === '/'){
40548 value = value.slice(0,-1);
40551 if(s === S_ATTR_S){
40555 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40556 el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
40558 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
40559 el.add(value,value,start);
40563 throw new Error('attribute value missed!!');
40565 // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
40567 /*xml space '\x20' | #x9 | #xD | #xA; */
40571 if(c<= ' '){//space
40574 el.setTagName(source.slice(start,p));//tagName
40578 attrName = source.slice(start,p);
40582 var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40583 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40584 el.add(attrName,value,start);
40596 //S_TAG, S_ATTR, S_EQ, S_V
40597 //S_ATTR_S, S_E, S_S, S_C
40599 //case S_TAG:void();break;
40600 //case S_ATTR:void();break;
40601 //case S_V:void();break;
40603 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!');
40604 el.add(attrName,attrName,start);
40609 errorHandler.warning('attribute space is required"'+attrName+'"!!');
40619 throw new Error("elements closed character '/' and '>' must be connected to");
40627 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40629 function appendElement(el,domBuilder,parseStack){
40630 var tagName = el.tagName;
40631 var localNSMap = null;
40632 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
40636 var qName = a.qName;
40637 var value = a.value;
40638 var nsp = qName.indexOf(':');
40640 var prefix = a.prefix = qName.slice(0,nsp);
40641 var localName = qName.slice(nsp+1);
40642 var nsPrefix = prefix === 'xmlns' && localName;
40646 nsPrefix = qName === 'xmlns' && '';
40648 //can not set prefix,because prefix !== ''
40649 a.localName = localName ;
40650 //prefix == null for no ns prefix attribute
40651 if(nsPrefix !== false){//hack!!
40652 if(localNSMap == null){
40654 //console.log(currentNSMap,0)
40655 _copy(currentNSMap,currentNSMap={});
40656 //console.log(currentNSMap,1)
40658 currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
40659 a.uri = 'http://www.w3.org/2000/xmlns/';
40660 domBuilder.startPrefixMapping(nsPrefix, value);
40666 var prefix = a.prefix;
40667 if(prefix){//no prefix attribute has no namespace
40668 if(prefix === 'xml'){
40669 a.uri = 'http://www.w3.org/XML/1998/namespace';
40670 }if(prefix !== 'xmlns'){
40671 a.uri = currentNSMap[prefix];
40673 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
40677 var nsp = tagName.indexOf(':');
40679 prefix = el.prefix = tagName.slice(0,nsp);
40680 localName = el.localName = tagName.slice(nsp+1);
40682 prefix = null;//important!!
40683 localName = el.localName = tagName;
40685 //no prefix element has default namespace
40686 var ns = el.uri = currentNSMap[prefix || ''];
40687 domBuilder.startElement(ns,localName,tagName,el);
40688 //endPrefixMapping and startPrefixMapping have not any help for dom builder
40689 //localNSMap = null
40691 domBuilder.endElement(ns,localName,tagName);
40693 for(prefix in localNSMap){
40694 domBuilder.endPrefixMapping(prefix);
40698 el.currentNSMap = currentNSMap;
40699 el.localNSMap = localNSMap;
40700 parseStack.push(el);
40703 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
40704 if(/^(?:script|textarea)$/i.test(tagName)){
40705 var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
40706 var text = source.substring(elStartEnd+1,elEndStart);
40707 if(/[&<]/.test(text)){
40708 if(/^script$/i.test(tagName)){
40709 //if(!/\]\]>/.test(text)){
40710 //lexHandler.startCDATA();
40711 domBuilder.characters(text,0,text.length);
40712 //lexHandler.endCDATA();
40715 }//}else{//text area
40716 text = text.replace(/&#?\w+;/g,entityReplacer);
40717 domBuilder.characters(text,0,text.length);
40723 return elStartEnd+1;
40725 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
40726 //if(tagName in closeMap){
40727 var pos = closeMap[tagName];
40729 //console.log(tagName)
40730 pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>');
40732 return pos<elStartEnd;
40735 function _copy(source,target){
40736 for(var n in source){target[n] = source[n];}
40738 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
40739 var next= source.charAt(start+2);
40742 if(source.charAt(start + 3) === '-'){
40743 var end = source.indexOf('-->',start+4);
40744 //append comment source.substring(4,end)//<!--
40746 domBuilder.comment(source,start+4,end-start-4);
40749 errorHandler.error("Unclosed comment");
40757 if(source.substr(start+3,6) == 'CDATA['){
40758 var end = source.indexOf(']]>',start+9);
40759 domBuilder.startCDATA();
40760 domBuilder.characters(source,start+9,end-start-9);
40761 domBuilder.endCDATA();
40765 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
40766 var matchs = split(source,start);
40767 var len = matchs.length;
40768 if(len>1 && /!doctype/i.test(matchs[0][0])){
40769 var name = matchs[1][0];
40770 var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
40771 var sysid = len>4 && matchs[4][0];
40772 var lastMatch = matchs[len-1];
40773 domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
40774 sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
40775 domBuilder.endDTD();
40777 return lastMatch.index+lastMatch[0].length
40785 function parseInstruction(source,start,domBuilder){
40786 var end = source.indexOf('?>',start);
40788 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
40790 var len = match[0].length;
40791 domBuilder.processingInstruction(match[1], match[2]) ;
40803 function ElementAttributes(source){
40806 ElementAttributes.prototype = {
40807 setTagName:function(tagName){
40808 if(!tagNamePattern.test(tagName)){
40809 throw new Error('invalid tagName:'+tagName)
40811 this.tagName = tagName;
40813 add:function(qName,value,offset){
40814 if(!tagNamePattern.test(qName)){
40815 throw new Error('invalid attribute:'+qName)
40817 this[this.length++] = {qName:qName,value:value,offset:offset};
40820 getLocalName:function(i){return this[i].localName},
40821 getOffset:function(i){return this[i].offset},
40822 getQName:function(i){return this[i].qName},
40823 getURI:function(i){return this[i].uri},
40824 getValue:function(i){return this[i].value}
40825 // ,getIndex:function(uri, localName)){
40832 // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
40833 // getType:function(uri,localName){}
40834 // getType:function(i){},
40840 function _set_proto_(thiz,parent){
40841 thiz.__proto__ = parent;
40844 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
40845 _set_proto_ = function(thiz,parent){
40847 p.prototype = parent;
40849 for(parent in thiz){
40850 p[parent] = thiz[parent];
40856 function split(source,start){
40859 var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
40860 reg.lastIndex = start;
40861 reg.exec(source);//skip <
40862 while(match = reg.exec(source)){
40864 if(match[1])return buf;
40868 if(typeof commonjsRequire == 'function'){
40869 exports.XMLReader = XMLReader;
40873 var dom = createCommonjsModule(function (module, exports) {
40876 * Object DOMException
40877 * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
40878 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
40881 function copy(src,dest){
40887 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
40888 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
40890 function _extends(Class,Super){
40891 var pt = Class.prototype;
40893 var ppt = Object.create(Super.prototype);
40894 pt.__proto__ = ppt;
40896 if(!(pt instanceof Super)){
40898 t.prototype = Super.prototype;
40901 Class.prototype = pt = t;
40903 if(pt.constructor != Class){
40904 if(typeof Class != 'function'){
40905 console.error("unknow Class:"+Class);
40907 pt.constructor = Class;
40910 var htmlns = 'http://www.w3.org/1999/xhtml';
40913 var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
40914 var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
40915 var TEXT_NODE = NodeType.TEXT_NODE = 3;
40916 var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
40917 var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
40918 var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
40919 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
40920 var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
40921 var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
40922 var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
40923 var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
40924 var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
40927 var ExceptionCode = {};
40928 var ExceptionMessage = {};
40929 var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
40930 var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
40931 var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
40932 var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
40933 var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
40934 var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
40935 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
40936 var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
40937 var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
40938 var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
40940 var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
40941 var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
40942 var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
40943 var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
40944 var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
40947 function DOMException(code, message) {
40948 if(message instanceof Error){
40949 var error = message;
40952 Error.call(this, ExceptionMessage[code]);
40953 this.message = ExceptionMessage[code];
40954 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
40957 if(message) this.message = this.message + ": " + message;
40960 DOMException.prototype = Error.prototype;
40961 copy(ExceptionCode,DOMException);
40963 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
40964 * 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.
40965 * The items in the NodeList are accessible via an integral index, starting from 0.
40967 function NodeList() {
40969 NodeList.prototype = {
40971 * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
40976 * 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.
40978 * @param index unsigned long
40979 * Index into the collection.
40981 * The node at the indexth position in the NodeList, or null if that is not a valid index.
40983 item: function(index) {
40984 return this[index] || null;
40986 toString:function(){
40987 for(var buf = [], i = 0;i<this.length;i++){
40988 serializeToString(this[i],buf);
40990 return buf.join('');
40993 function LiveNodeList(node,refresh){
40995 this._refresh = refresh;
40996 _updateLiveList(this);
40998 function _updateLiveList(list){
40999 var inc = list._node._inc || list._node.ownerDocument._inc;
41000 if(list._inc != inc){
41001 var ls = list._refresh(list._node);
41002 //console.log(ls.length)
41003 __set__(list,'length',ls.length);
41008 LiveNodeList.prototype.item = function(i){
41009 _updateLiveList(this);
41013 _extends(LiveNodeList,NodeList);
41016 * 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.
41017 * NamedNodeMap objects in the DOM are live.
41018 * used for attributes or DocumentType entities
41020 function NamedNodeMap() {
41023 function _findNodeIndex(list,node){
41024 var i = list.length;
41026 if(list[i] === node){return i}
41030 function _addNamedNode(el,list,newAttr,oldAttr){
41032 list[_findNodeIndex(list,oldAttr)] = newAttr;
41034 list[list.length++] = newAttr;
41037 newAttr.ownerElement = el;
41038 var doc = el.ownerDocument;
41040 oldAttr && _onRemoveAttribute(doc,el,oldAttr);
41041 _onAddAttribute(doc,el,newAttr);
41045 function _removeNamedNode(el,list,attr){
41046 var i = _findNodeIndex(list,attr);
41048 var lastIndex = list.length-1;
41049 while(i<lastIndex){
41050 list[i] = list[++i];
41052 list.length = lastIndex;
41054 var doc = el.ownerDocument;
41056 _onRemoveAttribute(doc,el,attr);
41057 attr.ownerElement = null;
41061 throw DOMException(NOT_FOUND_ERR,new Error())
41064 NamedNodeMap.prototype = {
41066 item:NodeList.prototype.item,
41067 getNamedItem: function(key) {
41068 // if(key.indexOf(':')>0 || key == 'xmlns'){
41071 var i = this.length;
41073 var attr = this[i];
41074 if(attr.nodeName == key){
41079 setNamedItem: function(attr) {
41080 var el = attr.ownerElement;
41081 if(el && el!=this._ownerElement){
41082 throw new DOMException(INUSE_ATTRIBUTE_ERR);
41084 var oldAttr = this.getNamedItem(attr.nodeName);
41085 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41089 setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
41090 var el = attr.ownerElement, oldAttr;
41091 if(el && el!=this._ownerElement){
41092 throw new DOMException(INUSE_ATTRIBUTE_ERR);
41094 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
41095 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41100 removeNamedItem: function(key) {
41101 var attr = this.getNamedItem(key);
41102 _removeNamedNode(this._ownerElement,this,attr);
41106 },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
41109 removeNamedItemNS:function(namespaceURI,localName){
41110 var attr = this.getNamedItemNS(namespaceURI,localName);
41111 _removeNamedNode(this._ownerElement,this,attr);
41114 getNamedItemNS: function(namespaceURI, localName) {
41115 var i = this.length;
41117 var node = this[i];
41118 if(node.localName == localName && node.namespaceURI == namespaceURI){
41126 * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
41128 function DOMImplementation(/* Object */ features) {
41129 this._features = {};
41131 for (var feature in features) {
41132 this._features = features[feature];
41137 DOMImplementation.prototype = {
41138 hasFeature: function(/* string */ feature, /* string */ version) {
41139 var versions = this._features[feature.toLowerCase()];
41140 if (versions && (!version || version in versions)) {
41146 // Introduced in DOM Level 2:
41147 createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
41148 var doc = new Document();
41149 doc.implementation = this;
41150 doc.childNodes = new NodeList();
41151 doc.doctype = doctype;
41153 doc.appendChild(doctype);
41156 var root = doc.createElementNS(namespaceURI,qualifiedName);
41157 doc.appendChild(root);
41161 // Introduced in DOM Level 2:
41162 createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
41163 var node = new DocumentType();
41164 node.name = qualifiedName;
41165 node.nodeName = qualifiedName;
41166 node.publicId = publicId;
41167 node.systemId = systemId;
41168 // Introduced in DOM Level 2:
41169 //readonly attribute DOMString internalSubset;
41172 // readonly attribute NamedNodeMap entities;
41173 // readonly attribute NamedNodeMap notations;
41180 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
41189 previousSibling : null,
41190 nextSibling : null,
41194 ownerDocument : null,
41196 namespaceURI : null,
41199 // Modified in DOM Level 2:
41200 insertBefore:function(newChild, refChild){//raises
41201 return _insertBefore(this,newChild,refChild);
41203 replaceChild:function(newChild, oldChild){//raises
41204 this.insertBefore(newChild,oldChild);
41206 this.removeChild(oldChild);
41209 removeChild:function(oldChild){
41210 return _removeChild(this,oldChild);
41212 appendChild:function(newChild){
41213 return this.insertBefore(newChild,null);
41215 hasChildNodes:function(){
41216 return this.firstChild != null;
41218 cloneNode:function(deep){
41219 return cloneNode(this.ownerDocument||this,this,deep);
41221 // Modified in DOM Level 2:
41222 normalize:function(){
41223 var child = this.firstChild;
41225 var next = child.nextSibling;
41226 if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
41227 this.removeChild(next);
41228 child.appendData(next.data);
41235 // Introduced in DOM Level 2:
41236 isSupported:function(feature, version){
41237 return this.ownerDocument.implementation.hasFeature(feature,version);
41239 // Introduced in DOM Level 2:
41240 hasAttributes:function(){
41241 return this.attributes.length>0;
41243 lookupPrefix:function(namespaceURI){
41246 var map = el._nsMap;
41250 if(map[n] == namespaceURI){
41255 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
41259 // Introduced in DOM Level 3:
41260 lookupNamespaceURI:function(prefix){
41263 var map = el._nsMap;
41267 return map[prefix] ;
41270 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
41274 // Introduced in DOM Level 3:
41275 isDefaultNamespace:function(namespaceURI){
41276 var prefix = this.lookupPrefix(namespaceURI);
41277 return prefix == null;
41282 function _xmlEncoder(c){
41283 return c == '<' && '<' ||
41284 c == '>' && '>' ||
41285 c == '&' && '&' ||
41286 c == '"' && '"' ||
41287 '&#'+c.charCodeAt()+';'
41291 copy(NodeType,Node);
41292 copy(NodeType,Node.prototype);
41295 * @param callback return true for continue,false for break
41296 * @return boolean true: break visit;
41298 function _visitNode(node,callback){
41299 if(callback(node)){
41302 if(node = node.firstChild){
41304 if(_visitNode(node,callback)){return true}
41305 }while(node=node.nextSibling)
41311 function Document(){
41313 function _onAddAttribute(doc,el,newAttr){
41315 var ns = newAttr.namespaceURI;
41316 if(ns == 'http://www.w3.org/2000/xmlns/'){
41318 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
41321 function _onRemoveAttribute(doc,el,newAttr,remove){
41323 var ns = newAttr.namespaceURI;
41324 if(ns == 'http://www.w3.org/2000/xmlns/'){
41326 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
41329 function _onUpdateChild(doc,el,newChild){
41330 if(doc && doc._inc){
41332 //update childNodes
41333 var cs = el.childNodes;
41335 cs[cs.length++] = newChild;
41338 var child = el.firstChild;
41342 child =child.nextSibling;
41353 * writeable properties:
41354 * nodeValue,Attr:value,CharacterData:data
41357 function _removeChild(parentNode,child){
41358 var previous = child.previousSibling;
41359 var next = child.nextSibling;
41361 previous.nextSibling = next;
41363 parentNode.firstChild = next;
41366 next.previousSibling = previous;
41368 parentNode.lastChild = previous;
41370 _onUpdateChild(parentNode.ownerDocument,parentNode);
41374 * preformance key(refChild == null)
41376 function _insertBefore(parentNode,newChild,nextChild){
41377 var cp = newChild.parentNode;
41379 cp.removeChild(newChild);//remove and update
41381 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41382 var newFirst = newChild.firstChild;
41383 if (newFirst == null) {
41386 var newLast = newChild.lastChild;
41388 newFirst = newLast = newChild;
41390 var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
41392 newFirst.previousSibling = pre;
41393 newLast.nextSibling = nextChild;
41397 pre.nextSibling = newFirst;
41399 parentNode.firstChild = newFirst;
41401 if(nextChild == null){
41402 parentNode.lastChild = newLast;
41404 nextChild.previousSibling = newLast;
41407 newFirst.parentNode = parentNode;
41408 }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
41409 _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
41410 //console.log(parentNode.lastChild.nextSibling == null)
41411 if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
41412 newChild.firstChild = newChild.lastChild = null;
41416 function _appendSingleChild(parentNode,newChild){
41417 var cp = newChild.parentNode;
41419 var pre = parentNode.lastChild;
41420 cp.removeChild(newChild);//remove and update
41421 var pre = parentNode.lastChild;
41423 var pre = parentNode.lastChild;
41424 newChild.parentNode = parentNode;
41425 newChild.previousSibling = pre;
41426 newChild.nextSibling = null;
41428 pre.nextSibling = newChild;
41430 parentNode.firstChild = newChild;
41432 parentNode.lastChild = newChild;
41433 _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
41435 //console.log("__aa",parentNode.lastChild.nextSibling == null)
41437 Document.prototype = {
41438 //implementation : null,
41439 nodeName : '#document',
41440 nodeType : DOCUMENT_NODE,
41442 documentElement : null,
41445 insertBefore : function(newChild, refChild){//raises
41446 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
41447 var child = newChild.firstChild;
41449 var next = child.nextSibling;
41450 this.insertBefore(child,refChild);
41455 if(this.documentElement == null && newChild.nodeType == 1){
41456 this.documentElement = newChild;
41459 return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
41461 removeChild : function(oldChild){
41462 if(this.documentElement == oldChild){
41463 this.documentElement = null;
41465 return _removeChild(this,oldChild);
41467 // Introduced in DOM Level 2:
41468 importNode : function(importedNode,deep){
41469 return importNode(this,importedNode,deep);
41471 // Introduced in DOM Level 2:
41472 getElementById : function(id){
41474 _visitNode(this.documentElement,function(node){
41475 if(node.nodeType == 1){
41476 if(node.getAttribute('id') == id){
41485 //document factory method:
41486 createElement : function(tagName){
41487 var node = new Element();
41488 node.ownerDocument = this;
41489 node.nodeName = tagName;
41490 node.tagName = tagName;
41491 node.childNodes = new NodeList();
41492 var attrs = node.attributes = new NamedNodeMap();
41493 attrs._ownerElement = node;
41496 createDocumentFragment : function(){
41497 var node = new DocumentFragment();
41498 node.ownerDocument = this;
41499 node.childNodes = new NodeList();
41502 createTextNode : function(data){
41503 var node = new Text();
41504 node.ownerDocument = this;
41505 node.appendData(data);
41508 createComment : function(data){
41509 var node = new Comment();
41510 node.ownerDocument = this;
41511 node.appendData(data);
41514 createCDATASection : function(data){
41515 var node = new CDATASection();
41516 node.ownerDocument = this;
41517 node.appendData(data);
41520 createProcessingInstruction : function(target,data){
41521 var node = new ProcessingInstruction();
41522 node.ownerDocument = this;
41523 node.tagName = node.target = target;
41524 node.nodeValue= node.data = data;
41527 createAttribute : function(name){
41528 var node = new Attr();
41529 node.ownerDocument = this;
41531 node.nodeName = name;
41532 node.localName = name;
41533 node.specified = true;
41536 createEntityReference : function(name){
41537 var node = new EntityReference();
41538 node.ownerDocument = this;
41539 node.nodeName = name;
41542 // Introduced in DOM Level 2:
41543 createElementNS : function(namespaceURI,qualifiedName){
41544 var node = new Element();
41545 var pl = qualifiedName.split(':');
41546 var attrs = node.attributes = new NamedNodeMap();
41547 node.childNodes = new NodeList();
41548 node.ownerDocument = this;
41549 node.nodeName = qualifiedName;
41550 node.tagName = qualifiedName;
41551 node.namespaceURI = namespaceURI;
41552 if(pl.length == 2){
41553 node.prefix = pl[0];
41554 node.localName = pl[1];
41556 //el.prefix = null;
41557 node.localName = qualifiedName;
41559 attrs._ownerElement = node;
41562 // Introduced in DOM Level 2:
41563 createAttributeNS : function(namespaceURI,qualifiedName){
41564 var node = new Attr();
41565 var pl = qualifiedName.split(':');
41566 node.ownerDocument = this;
41567 node.nodeName = qualifiedName;
41568 node.name = qualifiedName;
41569 node.namespaceURI = namespaceURI;
41570 node.specified = true;
41571 if(pl.length == 2){
41572 node.prefix = pl[0];
41573 node.localName = pl[1];
41575 //el.prefix = null;
41576 node.localName = qualifiedName;
41581 _extends(Document,Node);
41584 function Element() {
41587 Element.prototype = {
41588 nodeType : ELEMENT_NODE,
41589 hasAttribute : function(name){
41590 return this.getAttributeNode(name)!=null;
41592 getAttribute : function(name){
41593 var attr = this.getAttributeNode(name);
41594 return attr && attr.value || '';
41596 getAttributeNode : function(name){
41597 return this.attributes.getNamedItem(name);
41599 setAttribute : function(name, value){
41600 var attr = this.ownerDocument.createAttribute(name);
41601 attr.value = attr.nodeValue = "" + value;
41602 this.setAttributeNode(attr);
41604 removeAttribute : function(name){
41605 var attr = this.getAttributeNode(name);
41606 attr && this.removeAttributeNode(attr);
41609 //four real opeartion method
41610 appendChild:function(newChild){
41611 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41612 return this.insertBefore(newChild,null);
41614 return _appendSingleChild(this,newChild);
41617 setAttributeNode : function(newAttr){
41618 return this.attributes.setNamedItem(newAttr);
41620 setAttributeNodeNS : function(newAttr){
41621 return this.attributes.setNamedItemNS(newAttr);
41623 removeAttributeNode : function(oldAttr){
41624 return this.attributes.removeNamedItem(oldAttr.nodeName);
41626 //get real attribute name,and remove it by removeAttributeNode
41627 removeAttributeNS : function(namespaceURI, localName){
41628 var old = this.getAttributeNodeNS(namespaceURI, localName);
41629 old && this.removeAttributeNode(old);
41632 hasAttributeNS : function(namespaceURI, localName){
41633 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
41635 getAttributeNS : function(namespaceURI, localName){
41636 var attr = this.getAttributeNodeNS(namespaceURI, localName);
41637 return attr && attr.value || '';
41639 setAttributeNS : function(namespaceURI, qualifiedName, value){
41640 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
41641 attr.value = attr.nodeValue = "" + value;
41642 this.setAttributeNode(attr);
41644 getAttributeNodeNS : function(namespaceURI, localName){
41645 return this.attributes.getNamedItemNS(namespaceURI, localName);
41648 getElementsByTagName : function(tagName){
41649 return new LiveNodeList(this,function(base){
41651 _visitNode(base,function(node){
41652 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
41659 getElementsByTagNameNS : function(namespaceURI, localName){
41660 return new LiveNodeList(this,function(base){
41662 _visitNode(base,function(node){
41663 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
41671 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
41672 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
41675 _extends(Element,Node);
41678 Attr.prototype.nodeType = ATTRIBUTE_NODE;
41679 _extends(Attr,Node);
41682 function CharacterData() {
41684 CharacterData.prototype = {
41686 substringData : function(offset, count) {
41687 return this.data.substring(offset, offset+count);
41689 appendData: function(text) {
41690 text = this.data+text;
41691 this.nodeValue = this.data = text;
41692 this.length = text.length;
41694 insertData: function(offset,text) {
41695 this.replaceData(offset,0,text);
41698 appendChild:function(newChild){
41699 //if(!(newChild instanceof CharacterData)){
41700 throw new Error(ExceptionMessage[3])
41702 return Node.prototype.appendChild.apply(this,arguments)
41704 deleteData: function(offset, count) {
41705 this.replaceData(offset,count,"");
41707 replaceData: function(offset, count, text) {
41708 var start = this.data.substring(0,offset);
41709 var end = this.data.substring(offset+count);
41710 text = start + text + end;
41711 this.nodeValue = this.data = text;
41712 this.length = text.length;
41715 _extends(CharacterData,Node);
41719 nodeName : "#text",
41720 nodeType : TEXT_NODE,
41721 splitText : function(offset) {
41722 var text = this.data;
41723 var newText = text.substring(offset);
41724 text = text.substring(0, offset);
41725 this.data = this.nodeValue = text;
41726 this.length = text.length;
41727 var newNode = this.ownerDocument.createTextNode(newText);
41728 if(this.parentNode){
41729 this.parentNode.insertBefore(newNode, this.nextSibling);
41734 _extends(Text,CharacterData);
41735 function Comment() {
41737 Comment.prototype = {
41738 nodeName : "#comment",
41739 nodeType : COMMENT_NODE
41741 _extends(Comment,CharacterData);
41743 function CDATASection() {
41745 CDATASection.prototype = {
41746 nodeName : "#cdata-section",
41747 nodeType : CDATA_SECTION_NODE
41749 _extends(CDATASection,CharacterData);
41752 function DocumentType() {
41754 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
41755 _extends(DocumentType,Node);
41757 function Notation() {
41759 Notation.prototype.nodeType = NOTATION_NODE;
41760 _extends(Notation,Node);
41762 function Entity() {
41764 Entity.prototype.nodeType = ENTITY_NODE;
41765 _extends(Entity,Node);
41767 function EntityReference() {
41769 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
41770 _extends(EntityReference,Node);
41772 function DocumentFragment() {
41774 DocumentFragment.prototype.nodeName = "#document-fragment";
41775 DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
41776 _extends(DocumentFragment,Node);
41779 function ProcessingInstruction() {
41781 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
41782 _extends(ProcessingInstruction,Node);
41783 function XMLSerializer(){}
41784 XMLSerializer.prototype.serializeToString = function(node,attributeSorter){
41785 return node.toString(attributeSorter);
41787 Node.prototype.toString =function(attributeSorter){
41789 serializeToString(this,buf,attributeSorter);
41790 return buf.join('');
41792 function serializeToString(node,buf,attributeSorter,isHTML){
41793 switch(node.nodeType){
41795 var attrs = node.attributes;
41796 var len = attrs.length;
41797 var child = node.firstChild;
41798 var nodeName = node.tagName;
41799 isHTML = (htmlns === node.namespaceURI) ||isHTML;
41800 buf.push('<',nodeName);
41801 if(attributeSorter){
41802 buf.sort.apply(attrs, attributeSorter);
41804 for(var i=0;i<len;i++){
41805 serializeToString(attrs.item(i),buf,attributeSorter,isHTML);
41807 if(child || isHTML && !/^(?:meta|link|img|br|hr|input|button)$/i.test(nodeName)){
41809 //if is cdata child node
41810 if(isHTML && /^script$/i.test(nodeName)){
41812 buf.push(child.data);
41816 serializeToString(child,buf,attributeSorter,isHTML);
41817 child = child.nextSibling;
41820 buf.push('</',nodeName,'>');
41825 case DOCUMENT_NODE:
41826 case DOCUMENT_FRAGMENT_NODE:
41827 var child = node.firstChild;
41829 serializeToString(child,buf,attributeSorter,isHTML);
41830 child = child.nextSibling;
41833 case ATTRIBUTE_NODE:
41834 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
41836 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
41837 case CDATA_SECTION_NODE:
41838 return buf.push( '<![CDATA[',node.data,']]>');
41840 return buf.push( "<!--",node.data,"-->");
41841 case DOCUMENT_TYPE_NODE:
41842 var pubid = node.publicId;
41843 var sysid = node.systemId;
41844 buf.push('<!DOCTYPE ',node.name);
41846 buf.push(' PUBLIC "',pubid);
41847 if (sysid && sysid!='.') {
41848 buf.push( '" "',sysid);
41851 }else if(sysid && sysid!='.'){
41852 buf.push(' SYSTEM "',sysid,'">');
41854 var sub = node.internalSubset;
41856 buf.push(" [",sub,"]");
41861 case PROCESSING_INSTRUCTION_NODE:
41862 return buf.push( "<?",node.target," ",node.data,"?>");
41863 case ENTITY_REFERENCE_NODE:
41864 return buf.push( '&',node.nodeName,';');
41865 //case ENTITY_NODE:
41866 //case NOTATION_NODE:
41868 buf.push('??',node.nodeName);
41871 function importNode(doc,node,deep){
41873 switch (node.nodeType) {
41875 node2 = node.cloneNode(false);
41876 node2.ownerDocument = doc;
41877 //var attrs = node2.attributes;
41878 //var len = attrs.length;
41879 //for(var i=0;i<len;i++){
41880 //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
41882 case DOCUMENT_FRAGMENT_NODE:
41884 case ATTRIBUTE_NODE:
41887 //case ENTITY_REFERENCE_NODE:
41888 //case PROCESSING_INSTRUCTION_NODE:
41889 ////case TEXT_NODE:
41890 //case CDATA_SECTION_NODE:
41891 //case COMMENT_NODE:
41894 //case DOCUMENT_NODE:
41895 //case DOCUMENT_TYPE_NODE:
41896 //cannot be imported.
41897 //case ENTITY_NODE:
41898 //case NOTATION_NODE:
41899 //can not hit in level3
41903 node2 = node.cloneNode(false);//false
41905 node2.ownerDocument = doc;
41906 node2.parentNode = null;
41908 var child = node.firstChild;
41910 node2.appendChild(importNode(doc,child,deep));
41911 child = child.nextSibling;
41917 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
41918 // attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
41919 function cloneNode(doc,node,deep){
41920 var node2 = new node.constructor();
41921 for(var n in node){
41923 if(typeof v != 'object' ){
41929 if(node.childNodes){
41930 node2.childNodes = new NodeList();
41932 node2.ownerDocument = doc;
41933 switch (node2.nodeType) {
41935 var attrs = node.attributes;
41936 var attrs2 = node2.attributes = new NamedNodeMap();
41937 var len = attrs.length;
41938 attrs2._ownerElement = node2;
41939 for(var i=0;i<len;i++){
41940 node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
41943 case ATTRIBUTE_NODE:
41947 var child = node.firstChild;
41949 node2.appendChild(cloneNode(doc,child,deep));
41950 child = child.nextSibling;
41956 function __set__(object,key,value){
41957 object[key] = value;
41961 if(Object.defineProperty){
41962 Object.defineProperty(LiveNodeList.prototype,'length',{
41964 _updateLiveList(this);
41965 return this.$$length;
41968 Object.defineProperty(Node.prototype,'textContent',{
41970 return getTextContent(this);
41972 set:function(data){
41973 switch(this.nodeType){
41976 while(this.firstChild){
41977 this.removeChild(this.firstChild);
41979 if(data || String(data)){
41980 this.appendChild(this.ownerDocument.createTextNode(data));
41986 this.value = value;
41987 this.nodeValue = data;
41992 function getTextContent(node){
41993 switch(node.nodeType){
41997 node = node.firstChild;
41999 if(node.nodeType!==7 && node.nodeType !==8){
42000 buf.push(getTextContent(node));
42002 node = node.nextSibling;
42004 return buf.join('');
42006 return node.nodeValue;
42009 __set__ = function(object,key,value){
42010 //console.log(value)
42011 object['$$'+key] = value;
42017 if(typeof commonjsRequire == 'function'){
42018 exports.DOMImplementation = DOMImplementation;
42019 exports.XMLSerializer = XMLSerializer;
42023 var domParser = createCommonjsModule(function (module, exports) {
42024 function DOMParser(options){
42025 this.options = options ||{locator:{}};
42028 DOMParser.prototype.parseFromString = function(source,mimeType){
42029 var options = this.options;
42030 var sax$$1 = new XMLReader();
42031 var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
42032 var errorHandler = options.errorHandler;
42033 var locator = options.locator;
42034 var defaultNSMap = options.xmlns||{};
42035 var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
42037 domBuilder.setDocumentLocator(locator);
42040 sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
42041 sax$$1.domBuilder = options.domBuilder || domBuilder;
42042 if(/\/x?html?$/.test(mimeType)){
42043 entityMap.nbsp = '\xa0';
42044 entityMap.copy = '\xa9';
42045 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
42047 defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
42049 sax$$1.parse(source,defaultNSMap,entityMap);
42051 sax$$1.errorHandler.error("invalid document source");
42053 return domBuilder.document;
42055 function buildErrorHandler(errorImpl,domBuilder,locator){
42057 if(domBuilder instanceof DOMHandler){
42060 errorImpl = domBuilder ;
42062 var errorHandler = {};
42063 var isCallback = errorImpl instanceof Function;
42064 locator = locator||{};
42065 function build(key){
42066 var fn = errorImpl[key];
42067 if(!fn && isCallback){
42068 fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
42070 errorHandler[key] = fn && function(msg){
42071 fn('[xmldom '+key+']\t'+msg+_locator(locator));
42076 build('fatalError');
42077 return errorHandler;
42080 //console.log('#\n\n\n\n\n\n\n####')
42082 * +ContentHandler+ErrorHandler
42083 * +LexicalHandler+EntityResolver2
42084 * -DeclHandler-DTDHandler
42086 * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
42087 * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
42088 * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
42090 function DOMHandler() {
42091 this.cdata = false;
42093 function position(locator,node){
42094 node.lineNumber = locator.lineNumber;
42095 node.columnNumber = locator.columnNumber;
42098 * @see org.xml.sax.ContentHandler#startDocument
42099 * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
42101 DOMHandler.prototype = {
42102 startDocument : function() {
42103 this.document = new DOMImplementation().createDocument(null, null, null);
42104 if (this.locator) {
42105 this.document.documentURI = this.locator.systemId;
42108 startElement:function(namespaceURI, localName, qName, attrs) {
42109 var doc = this.document;
42110 var el = doc.createElementNS(namespaceURI, qName||localName);
42111 var len = attrs.length;
42112 appendElement(this, el);
42113 this.currentElement = el;
42115 this.locator && position(this.locator,el);
42116 for (var i = 0 ; i < len; i++) {
42117 var namespaceURI = attrs.getURI(i);
42118 var value = attrs.getValue(i);
42119 var qName = attrs.getQName(i);
42120 var attr = doc.createAttributeNS(namespaceURI, qName);
42121 if( attr.getOffset){
42122 position(attr.getOffset(1),attr);
42124 attr.value = attr.nodeValue = value;
42125 el.setAttributeNode(attr);
42128 endElement:function(namespaceURI, localName, qName) {
42129 var current = this.currentElement;
42130 var tagName = current.tagName;
42131 this.currentElement = current.parentNode;
42133 startPrefixMapping:function(prefix, uri) {
42135 endPrefixMapping:function(prefix) {
42137 processingInstruction:function(target, data) {
42138 var ins = this.document.createProcessingInstruction(target, data);
42139 this.locator && position(this.locator,ins);
42140 appendElement(this, ins);
42142 ignorableWhitespace:function(ch, start, length) {
42144 characters:function(chars, start, length) {
42145 chars = _toString.apply(this,arguments);
42146 //console.log(chars)
42147 if(this.currentElement && chars){
42149 var charNode = this.document.createCDATASection(chars);
42150 this.currentElement.appendChild(charNode);
42152 var charNode = this.document.createTextNode(chars);
42153 this.currentElement.appendChild(charNode);
42155 this.locator && position(this.locator,charNode);
42158 skippedEntity:function(name) {
42160 endDocument:function() {
42161 this.document.normalize();
42163 setDocumentLocator:function (locator) {
42164 if(this.locator = locator){// && !('lineNumber' in locator)){
42165 locator.lineNumber = 0;
42169 comment:function(chars, start, length) {
42170 chars = _toString.apply(this,arguments);
42171 var comm = this.document.createComment(chars);
42172 this.locator && position(this.locator,comm);
42173 appendElement(this, comm);
42176 startCDATA:function() {
42177 //used in characters() methods
42180 endCDATA:function() {
42181 this.cdata = false;
42184 startDTD:function(name, publicId, systemId) {
42185 var impl = this.document.implementation;
42186 if (impl && impl.createDocumentType) {
42187 var dt = impl.createDocumentType(name, publicId, systemId);
42188 this.locator && position(this.locator,dt);
42189 appendElement(this, dt);
42193 * @see org.xml.sax.ErrorHandler
42194 * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
42196 warning:function(error) {
42197 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
42199 error:function(error) {
42200 console.error('[xmldom error]\t'+error,_locator(this.locator));
42202 fatalError:function(error) {
42203 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
42207 function _locator(l){
42209 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
42212 function _toString(chars,start,length){
42213 if(typeof chars == 'string'){
42214 return chars.substr(start,length)
42215 }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
42216 if(chars.length >= start+length || start){
42217 return new java.lang.String(chars,start,length)+'';
42224 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
42225 * used method of org.xml.sax.ext.LexicalHandler:
42226 * #comment(chars, start, length)
42229 * #startDTD(name, publicId, systemId)
42232 * IGNORED method of org.xml.sax.ext.LexicalHandler:
42234 * #startEntity(name)
42238 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
42239 * IGNORED method of org.xml.sax.ext.DeclHandler
42240 * #attributeDecl(eName, aName, type, mode, value)
42241 * #elementDecl(name, model)
42242 * #externalEntityDecl(name, publicId, systemId)
42243 * #internalEntityDecl(name, value)
42244 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
42245 * IGNORED method of org.xml.sax.EntityResolver2
42246 * #resolveEntity(String name,String publicId,String baseURI,String systemId)
42247 * #resolveEntity(publicId, systemId)
42248 * #getExternalSubset(name, baseURI)
42249 * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
42250 * IGNORED method of org.xml.sax.DTDHandler
42251 * #notationDecl(name, publicId, systemId) {};
42252 * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
42254 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
42255 DOMHandler.prototype[key] = function(){return null};
42258 /* 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 */
42259 function appendElement (hander,node) {
42260 if (!hander.currentElement) {
42261 hander.document.appendChild(node);
42263 hander.currentElement.appendChild(node);
42265 }//appendChild and setAttributeNS are preformance key
42267 if(typeof commonjsRequire == 'function'){
42268 var XMLReader = sax.XMLReader;
42269 var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
42270 exports.XMLSerializer = dom.XMLSerializer ;
42271 exports.DOMParser = DOMParser;
42275 var togeojson = createCommonjsModule(function (module, exports) {
42276 var toGeoJSON = (function() {
42279 var removeSpace = /\s*/g,
42280 trimSpace = /^\s*|\s*$/g,
42281 splitSpace = /\s+/;
42282 // generate a short, numeric hash of a string
42283 function okhash(x) {
42284 if (!x || !x.length) return 0;
42285 for (var i = 0, h = 0; i < x.length; i++) {
42286 h = ((h << 5) - h) + x.charCodeAt(i) | 0;
42289 // all Y children of X
42290 function get(x, y) { return x.getElementsByTagName(y); }
42291 function attr(x, y) { return x.getAttribute(y); }
42292 function attrf(x, y) { return parseFloat(attr(x, y)); }
42293 // one Y child of X, if any, otherwise null
42294 function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
42295 // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
42296 function norm(el) { if (el.normalize) { el.normalize(); } return el; }
42297 // cast array x into numbers
42298 function numarray(x) {
42299 for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
42302 // get the content of a text node, if any
42303 function nodeVal(x) {
42304 if (x) { norm(x); }
42305 return (x && x.textContent) || '';
42307 // get the contents of multiple text nodes, if present
42308 function getMulti(x, ys) {
42310 for (k = 0; k < ys.length; k++) {
42311 n = get1(x, ys[k]);
42312 if (n) o[ys[k]] = nodeVal(n);
42316 // add properties of Y to X, overwriting if present in both
42317 function extend(x, y) { for (var k in y) x[k] = y[k]; }
42318 // get one coordinate from a coordinate array, if any
42319 function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
42320 // get all coordinates from a coordinate array as [[],[]]
42321 function coord(v) {
42322 var coords = v.replace(trimSpace, '').split(splitSpace),
42324 for (var i = 0; i < coords.length; i++) {
42325 o.push(coord1(coords[i]));
42329 function coordPair(x) {
42330 var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
42331 ele = get1(x, 'ele'),
42332 // handle namespaced attribute in browser
42333 heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
42334 time = get1(x, 'time'),
42337 e = parseFloat(nodeVal(ele));
42344 time: time ? nodeVal(time) : null,
42345 heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
42349 // create a new feature collection parent object
42352 type: 'FeatureCollection',
42358 if (typeof XMLSerializer !== 'undefined') {
42359 /* istanbul ignore next */
42360 serializer = new XMLSerializer();
42361 // only require xmldom in a node environment
42362 } else if ('object' === 'object' && typeof process === 'object' && !process.browser) {
42363 serializer = new (domParser.XMLSerializer)();
42365 function xml2str(str) {
42366 // IE9 will create a new XMLSerializer but it'll crash immediately.
42367 // This line is ignored because we don't run coverage tests in IE9
42368 /* istanbul ignore next */
42369 if (str.xml !== undefined) return str.xml;
42370 return serializer.serializeToString(str);
42374 kml: function(doc) {
42377 // styleindex keeps track of hashed styles in order to match features
42378 styleIndex = {}, styleByHash = {},
42379 // stylemapindex keeps track of style maps to expose in properties
42380 styleMapIndex = {},
42381 // atomic geospatial types supported by KML - MultiGeometry is
42382 // handled separately
42383 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
42384 // all root placemarks in the file
42385 placemarks = get(doc, 'Placemark'),
42386 styles = get(doc, 'Style'),
42387 styleMaps = get(doc, 'StyleMap');
42389 for (var k = 0; k < styles.length; k++) {
42390 var hash = okhash(xml2str(styles[k])).toString(16);
42391 styleIndex['#' + attr(styles[k], 'id')] = hash;
42392 styleByHash[hash] = styles[k];
42394 for (var l = 0; l < styleMaps.length; l++) {
42395 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
42396 var pairs = get(styleMaps[l], 'Pair');
42398 for (var m = 0; m < pairs.length; m++) {
42399 pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
42401 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
42404 for (var j = 0; j < placemarks.length; j++) {
42405 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
42407 function kmlColor(v) {
42408 var color, opacity;
42410 if (v.substr(0, 1) === '#') { v = v.substr(1); }
42411 if (v.length === 6 || v.length === 3) { color = v; }
42412 if (v.length === 8) {
42413 opacity = parseInt(v.substr(0, 2), 16) / 255;
42414 color = '#' + v.substr(6, 2) +
42418 return [color, isNaN(opacity) ? undefined : opacity];
42420 function gxCoord(v) { return numarray(v.split(' ')); }
42421 function gxCoords(root) {
42422 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
42423 if (elems.length === 0) elems = get(root, 'gx:coord');
42424 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
42425 var timeElems = get(root, 'when');
42426 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
42432 function getGeometry(root) {
42433 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
42434 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
42435 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
42436 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
42437 for (i = 0; i < geotypes.length; i++) {
42438 geomNodes = get(root, geotypes[i]);
42440 for (j = 0; j < geomNodes.length; j++) {
42441 geomNode = geomNodes[j];
42442 if (geotypes[i] === 'Point') {
42445 coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
42447 } else if (geotypes[i] === 'LineString') {
42449 type: 'LineString',
42450 coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
42452 } else if (geotypes[i] === 'Polygon') {
42453 var rings = get(geomNode, 'LinearRing'),
42455 for (k = 0; k < rings.length; k++) {
42456 coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
42460 coordinates: coords
42462 } else if (geotypes[i] === 'Track' ||
42463 geotypes[i] === 'gx:Track') {
42464 var track = gxCoords(geomNode);
42466 type: 'LineString',
42467 coordinates: track.coords
42469 if (track.times.length) coordTimes.push(track.times);
42476 coordTimes: coordTimes
42479 function getPlacemark(root) {
42480 var geomsAndTimes = getGeometry(root), i, properties = {},
42481 name = nodeVal(get1(root, 'name')),
42482 address = nodeVal(get1(root, 'address')),
42483 styleUrl = nodeVal(get1(root, 'styleUrl')),
42484 description = nodeVal(get1(root, 'description')),
42485 timeSpan = get1(root, 'TimeSpan'),
42486 timeStamp = get1(root, 'TimeStamp'),
42487 extendedData = get1(root, 'ExtendedData'),
42488 lineStyle = get1(root, 'LineStyle'),
42489 polyStyle = get1(root, 'PolyStyle'),
42490 visibility = get1(root, 'visibility');
42492 if (!geomsAndTimes.geoms.length) return [];
42493 if (name) properties.name = name;
42494 if (address) properties.address = address;
42496 if (styleUrl[0] !== '#') {
42497 styleUrl = '#' + styleUrl;
42500 properties.styleUrl = styleUrl;
42501 if (styleIndex[styleUrl]) {
42502 properties.styleHash = styleIndex[styleUrl];
42504 if (styleMapIndex[styleUrl]) {
42505 properties.styleMapHash = styleMapIndex[styleUrl];
42506 properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
42508 // Try to populate the lineStyle or polyStyle since we got the style hash
42509 var style = styleByHash[properties.styleHash];
42511 if (!lineStyle) lineStyle = get1(style, 'LineStyle');
42512 if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
42515 if (description) properties.description = description;
42517 var begin = nodeVal(get1(timeSpan, 'begin'));
42518 var end = nodeVal(get1(timeSpan, 'end'));
42519 properties.timespan = { begin: begin, end: end };
42522 properties.timestamp = nodeVal(get1(timeStamp, 'when'));
42525 var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
42526 color = linestyles[0],
42527 opacity = linestyles[1],
42528 width = parseFloat(nodeVal(get1(lineStyle, 'width')));
42529 if (color) properties.stroke = color;
42530 if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
42531 if (!isNaN(width)) properties['stroke-width'] = width;
42534 var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
42535 pcolor = polystyles[0],
42536 popacity = polystyles[1],
42537 fill = nodeVal(get1(polyStyle, 'fill')),
42538 outline = nodeVal(get1(polyStyle, 'outline'));
42539 if (pcolor) properties.fill = pcolor;
42540 if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
42541 if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
42542 if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
42544 if (extendedData) {
42545 var datas = get(extendedData, 'Data'),
42546 simpleDatas = get(extendedData, 'SimpleData');
42548 for (i = 0; i < datas.length; i++) {
42549 properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
42551 for (i = 0; i < simpleDatas.length; i++) {
42552 properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
42556 properties.visibility = nodeVal(visibility);
42558 if (geomsAndTimes.coordTimes.length) {
42559 properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
42560 geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
42564 geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
42565 type: 'GeometryCollection',
42566 geometries: geomsAndTimes.geoms
42568 properties: properties
42570 if (attr(root, 'id')) feature.id = attr(root, 'id');
42575 gpx: function(doc) {
42577 tracks = get(doc, 'trk'),
42578 routes = get(doc, 'rte'),
42579 waypoints = get(doc, 'wpt'),
42580 // a feature collection
42583 for (i = 0; i < tracks.length; i++) {
42584 feature = getTrack(tracks[i]);
42585 if (feature) gj.features.push(feature);
42587 for (i = 0; i < routes.length; i++) {
42588 feature = getRoute(routes[i]);
42589 if (feature) gj.features.push(feature);
42591 for (i = 0; i < waypoints.length; i++) {
42592 gj.features.push(getPoint(waypoints[i]));
42594 function getPoints(node, pointname) {
42595 var pts = get(node, pointname),
42600 if (l < 2) return {}; // Invalid line in GeoJSON
42601 for (var i = 0; i < l; i++) {
42602 var c = coordPair(pts[i]);
42603 line.push(c.coordinates);
42604 if (c.time) times.push(c.time);
42605 if (c.heartRate) heartRates.push(c.heartRate);
42610 heartRates: heartRates
42613 function getTrack(node) {
42614 var segments = get(node, 'trkseg'),
42619 for (var i = 0; i < segments.length; i++) {
42620 line = getPoints(segments[i], 'trkpt');
42622 if (line.line) track.push(line.line);
42623 if (line.times && line.times.length) times.push(line.times);
42624 if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
42627 if (track.length === 0) return;
42628 var properties = getProperties(node);
42629 extend(properties, getLineStyle(get1(node, 'extensions')));
42630 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
42631 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
42634 properties: properties,
42636 type: track.length === 1 ? 'LineString' : 'MultiLineString',
42637 coordinates: track.length === 1 ? track[0] : track
42641 function getRoute(node) {
42642 var line = getPoints(node, 'rtept');
42643 if (!line.line) return;
42644 var prop = getProperties(node);
42645 extend(prop, getLineStyle(get1(node, 'extensions')));
42650 type: 'LineString',
42651 coordinates: line.line
42656 function getPoint(node) {
42657 var prop = getProperties(node);
42658 extend(prop, getMulti(node, ['sym']));
42664 coordinates: coordPair(node).coordinates
42668 function getLineStyle(extensions) {
42671 var lineStyle = get1(extensions, 'line');
42673 var color = nodeVal(get1(lineStyle, 'color')),
42674 opacity = parseFloat(nodeVal(get1(lineStyle, 'opacity'))),
42675 width = parseFloat(nodeVal(get1(lineStyle, 'width')));
42676 if (color) style.stroke = color;
42677 if (!isNaN(opacity)) style['stroke-opacity'] = opacity;
42678 // GPX width is in mm, convert to px with 96 px per inch
42679 if (!isNaN(width)) style['stroke-width'] = width * 96 / 25.4;
42684 function getProperties(node) {
42685 var prop = getMulti(node, ['name', 'cmt', 'desc', 'type', 'time', 'keywords']),
42686 links = get(node, 'link');
42687 if (links.length) prop.links = [];
42688 for (var i = 0, link; i < links.length; i++) {
42689 link = { href: attr(links[i], 'href') };
42690 extend(link, getMulti(links[i], ['text', 'type']));
42691 prop.links.push(link);
42701 module.exports = toGeoJSON;
42704 function svgGpx(projection, context, dispatch$$1) {
42705 var showLabels = true,
42706 detected = utilDetect(),
42711 if (svgGpx.initialized) return; // run once
42713 svgGpx.geojson = {};
42714 svgGpx.enabled = true;
42717 event.stopPropagation();
42718 event.preventDefault();
42719 event.dataTransfer.dropEffect = 'copy';
42723 .attr('dropzone', 'copy')
42724 .on('drop.localgpx', function() {
42725 event.stopPropagation();
42726 event.preventDefault();
42727 if (!detected.filedrop) return;
42728 drawGpx.files(event.dataTransfer.files);
42730 .on('dragenter.localgpx', over)
42731 .on('dragexit.localgpx', over)
42732 .on('dragover.localgpx', over);
42734 svgGpx.initialized = true;
42738 function drawGpx(selection$$1) {
42739 var geojson = svgGpx.geojson,
42740 enabled = svgGpx.enabled;
42742 layer = selection$$1.selectAll('.layer-gpx')
42743 .data(enabled ? [0] : []);
42748 layer = layer.enter()
42750 .attr('class', 'layer-gpx')
42761 paths = paths.enter()
42763 .attr('class', 'gpx')
42767 var path$$1 = index$4(projection);
42770 .attr('d', path$$1);
42773 var labels = layer.selectAll('text')
42774 .data(showLabels && geojson.features ? geojson.features : []);
42779 labels = labels.enter()
42781 .attr('class', 'gpx')
42785 .text(function(d) {
42786 return d.properties.desc || d.properties.name;
42788 .attr('x', function(d) {
42789 var centroid = path$$1.centroid(d);
42790 return centroid[0] + 7;
42792 .attr('y', function(d) {
42793 var centroid = path$$1.centroid(d);
42794 return centroid[1];
42800 function toDom(x) {
42801 return (new DOMParser()).parseFromString(x, 'text/xml');
42805 function getExtension(fileName) {
42806 if (lodash.isUndefined(fileName)) {
42810 var lastDotIndex = fileName.lastIndexOf('.');
42811 if (lastDotIndex < 0) {
42815 return fileName.substr(lastDotIndex);
42819 function parseSaveAndZoom(extension, data) {
42820 switch (extension) {
42822 drawGpx.geojson(togeojson.gpx(toDom(data))).fitZoom();
42825 drawGpx.geojson(togeojson.kml(toDom(data))).fitZoom();
42829 drawGpx.geojson(JSON.parse(data)).fitZoom();
42835 drawGpx.showLabels = function(_) {
42836 if (!arguments.length) return showLabels;
42842 drawGpx.enabled = function(_) {
42843 if (!arguments.length) return svgGpx.enabled;
42844 svgGpx.enabled = _;
42845 dispatch$$1.call('change');
42850 drawGpx.hasGpx = function() {
42851 var geojson = svgGpx.geojson;
42852 return (!(lodash.isEmpty(geojson) || lodash.isEmpty(geojson.features)));
42856 drawGpx.geojson = function(gj) {
42857 if (!arguments.length) return svgGpx.geojson;
42858 if (lodash.isEmpty(gj) || lodash.isEmpty(gj.features)) return this;
42859 svgGpx.geojson = gj;
42860 dispatch$$1.call('change');
42865 drawGpx.url = function(url) {
42866 text(url, function(err, data) {
42868 var extension = getExtension(url);
42869 parseSaveAndZoom(extension, data);
42876 drawGpx.files = function(fileList) {
42877 if (!fileList.length) return this;
42878 var f = fileList[0],
42879 reader = new FileReader();
42881 reader.onload = (function(file) {
42882 var extension = getExtension(file.name);
42884 return function (e) {
42885 parseSaveAndZoom(extension, e.target.result);
42889 reader.readAsText(f);
42894 drawGpx.fitZoom = function() {
42895 if (!this.hasGpx()) return this;
42896 var geojson = svgGpx.geojson;
42898 var map$$1 = context.map(),
42899 viewport = map$$1.trimmedExtent().polygon(),
42900 coords = lodash.reduce(geojson.features, function(coords, feature) {
42901 var c = feature.geometry.coordinates;
42903 /* eslint-disable no-fallthrough */
42904 switch (feature.geometry.type) {
42911 case 'MultiPolygon':
42912 c = lodash.flatten(c);
42914 case 'MultiLineString':
42915 c = lodash.flatten(c);
42918 /* eslint-enable no-fallthrough */
42920 return lodash.union(coords, c);
42923 if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
42924 var extent$$1 = geoExtent$$1(bounds({ type: 'LineString', coordinates: coords }));
42925 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
42936 function svgIcon(name, svgklass, useklass) {
42937 return function drawIcon(selection) {
42938 selection.selectAll('svg')
42942 .attr('class', 'icon ' + (svgklass || ''))
42944 .attr('xlink:href', name)
42945 .attr('class', useklass);
42949 function svgLabels(projection, context) {
42950 var path$$1 = index$4(projection),
42951 detected = utilDetect(),
42952 baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge'),
42953 rdrawn = index$9(),
42954 rskipped = index$9(),
42955 textWidthCache = {},
42958 // Listed from highest to lowest priority
42960 ['line', 'aeroway', '*', 12],
42961 ['line', 'highway', 'motorway', 12],
42962 ['line', 'highway', 'trunk', 12],
42963 ['line', 'highway', 'primary', 12],
42964 ['line', 'highway', 'secondary', 12],
42965 ['line', 'highway', 'tertiary', 12],
42966 ['line', 'highway', '*', 12],
42967 ['line', 'railway', '*', 12],
42968 ['line', 'waterway', '*', 12],
42969 ['area', 'aeroway', '*', 12],
42970 ['area', 'amenity', '*', 12],
42971 ['area', 'building', '*', 12],
42972 ['area', 'historic', '*', 12],
42973 ['area', 'leisure', '*', 12],
42974 ['area', 'man_made', '*', 12],
42975 ['area', 'natural', '*', 12],
42976 ['area', 'shop', '*', 12],
42977 ['area', 'tourism', '*', 12],
42978 ['area', 'camp_site', '*', 12],
42979 ['point', 'aeroway', '*', 10],
42980 ['point', 'amenity', '*', 10],
42981 ['point', 'building', '*', 10],
42982 ['point', 'historic', '*', 10],
42983 ['point', 'leisure', '*', 10],
42984 ['point', 'man_made', '*', 10],
42985 ['point', 'natural', '*', 10],
42986 ['point', 'shop', '*', 10],
42987 ['point', 'tourism', '*', 10],
42988 ['point', 'camp_site', '*', 10],
42989 ['line', 'name', '*', 12],
42990 ['area', 'name', '*', 12],
42991 ['point', 'name', '*', 10]
42995 function blacklisted(preset) {
42996 var noIcons = ['building', 'landuse', 'natural'];
42997 return lodash.some(noIcons, function(s) {
42998 return preset.id.indexOf(s) >= 0;
43003 function get(array, prop) {
43004 return function(d, i) { return array[i][prop]; };
43008 function textWidth(text$$1, size, elem) {
43009 var c = textWidthCache[size];
43010 if (!c) c = textWidthCache[size] = {};
43016 c[text$$1] = elem.getComputedTextLength();
43020 var str = encodeURIComponent(text$$1).match(/%[CDEFcdef]/g);
43021 if (str === null) {
43022 return size / 3 * 2 * text$$1.length;
43024 return size / 3 * (2 * text$$1.length + str.length);
43030 function drawLinePaths(selection$$1, entities, filter, classes, labels) {
43031 var paths = selection$$1.selectAll('path')
43033 .data(entities, osmEntity$$1.key);
43040 .style('stroke-width', get(labels, 'font-size'))
43041 .attr('id', function(d) { return 'labelpath-' + d.id; })
43042 .attr('class', classes)
43044 .attr('d', get(labels, 'lineString'));
43048 function drawLineLabels(selection$$1, entities, filter, classes, labels) {
43049 var texts = selection$$1.selectAll('text.' + classes)
43051 .data(entities, osmEntity$$1.key);
43058 .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
43059 .attr('dy', baselineHack ? '0.35em' : null)
43060 .append('textPath')
43061 .attr('class', 'textpath');
43063 texts = selection$$1.selectAll('text.' + classes);
43065 texts.selectAll('.textpath')
43067 .data(entities, osmEntity$$1.key)
43068 .attr('startOffset', '50%')
43069 .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
43070 .text(utilDisplayNameForPath);
43074 function drawPointLabels(selection$$1, entities, filter, classes, labels) {
43075 var texts = selection$$1.selectAll('text.' + classes)
43077 .data(entities, osmEntity$$1.key);
43082 texts = texts.enter()
43084 .attr('class', function(d, i) {
43085 return classes + ' ' + labels[i].classes + ' ' + d.id;
43090 .attr('x', get(labels, 'x'))
43091 .attr('y', get(labels, 'y'))
43092 .style('text-anchor', get(labels, 'textAnchor'))
43093 .text(utilDisplayName)
43094 .each(function(d, i) {
43095 textWidth(utilDisplayName(d), labels[i].height, this);
43100 function drawAreaLabels(selection$$1, entities, filter, classes, labels) {
43101 entities = entities.filter(hasText);
43102 labels = labels.filter(hasText);
43103 drawPointLabels(selection$$1, entities, filter, classes, labels);
43105 function hasText(d, i) {
43106 return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
43111 function drawAreaIcons(selection$$1, entities, filter, classes, labels) {
43112 var icons = selection$$1.selectAll('use.' + classes)
43114 .data(entities, osmEntity$$1.key);
43119 icons = icons.enter()
43121 .attr('class', 'icon ' + classes)
43122 .attr('width', '17px')
43123 .attr('height', '17px')
43127 .attr('transform', get(labels, 'transform'))
43128 .attr('xlink:href', function(d) {
43129 var icon = context.presets().match(d, context.graph()).icon;
43130 return '#' + icon + '-15';
43135 function drawCollisionBoxes(selection$$1, rtree, which) {
43136 var showDebug = context.getDebug('collision'),
43137 classes = 'debug ' + which + ' ' +
43138 (which === 'debug-skipped' ? 'orange' : 'yellow');
43140 var debug = selection$$1.selectAll('.layer-label-debug')
43141 .data(showDebug ? [true] : []);
43146 debug = debug.enter()
43148 .attr('class', 'layer-label-debug')
43152 var gj = rtree.all().map(function(d) {
43153 return { type: 'Polygon', coordinates: [[
43162 var debugboxes = debug.selectAll('.' + which)
43168 debugboxes = debugboxes.enter()
43170 .attr('class', classes)
43171 .merge(debugboxes);
43174 .attr('d', index$4());
43179 function drawLabels(selection$$1, graph, entities, filter, dimensions, fullRedraw) {
43180 var lowZoom = context.surface().classed('low-zoom');
43182 var labelable = [], i, j, k, entity, geometry;
43183 for (i = 0; i < labelStack.length; i++) {
43184 labelable.push([]);
43192 for (i = 0; i < entities.length; i++) {
43193 entity = entities[i];
43195 .concat(entitybboxes[entity.id] || [])
43196 .concat(entitybboxes[entity.id + 'I'] || []);
43198 for (j = 0; j < toRemove.length; j++) {
43199 rdrawn.remove(toRemove[j]);
43200 rskipped.remove(toRemove[j]);
43205 // Split entities into groups specified by labelStack
43206 for (i = 0; i < entities.length; i++) {
43207 entity = entities[i];
43208 geometry = entity.geometry(graph);
43209 if (geometry === 'vertex') { geometry = 'point'; } // treat vertex like point
43211 var preset = geometry === 'area' && context.presets().match(entity, graph),
43212 icon = preset && !blacklisted(preset) && preset.icon;
43214 if (!icon && !utilDisplayName(entity))
43217 for (k = 0; k < labelStack.length; k++) {
43218 var matchGeom = labelStack[k][0],
43219 matchKey = labelStack[k][1],
43220 matchVal = labelStack[k][2],
43221 hasVal = entity.tags[matchKey];
43223 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
43224 labelable[k].push(entity);
43242 // Try and find a valid label for labellable entities
43243 for (k = 0; k < labelable.length; k++) {
43244 var fontSize = labelStack[k][3];
43245 for (i = 0; i < labelable[k].length; i++) {
43246 entity = labelable[k][i];
43247 geometry = entity.geometry(graph);
43249 var getName = (geometry === 'line') ? utilDisplayNameForPath : utilDisplayName,
43250 name = getName(entity),
43251 width = name && textWidth(name, fontSize),
43254 if (geometry === 'point') {
43255 p = getPointLabel(entity, width, fontSize, geometry);
43256 } else if (geometry === 'vertex' && !lowZoom) {
43257 // don't label vertices at low zoom because they don't have icons
43258 p = getPointLabel(entity, width, fontSize, geometry);
43259 } else if (geometry === 'line') {
43260 p = getLineLabel(entity, width, fontSize);
43261 } else if (geometry === 'area') {
43262 p = getAreaLabel(entity, width, fontSize);
43266 if (geometry === 'vertex') { geometry = 'point'; } // treat vertex like point
43267 p.classes = geometry + ' tag-' + labelStack[k][1];
43268 positions[geometry].push(p);
43269 labelled[geometry].push(entity);
43275 function getPointLabel(entity, width, height, geometry) {
43276 var y = (geometry === 'point' ? -12 : 0),
43278 ltr: [15, y, 'start'],
43279 rtl: [-15, y, 'end']
43282 var coord = projection(entity.loc),
43284 offset = pointOffsets[textDirection],
43288 x: coord[0] + offset[0],
43289 y: coord[1] + offset[1],
43290 textAnchor: offset[2]
43294 if (textDirection === 'rtl') {
43296 minX: p.x - width - margin,
43297 minY: p.y - (height / 2) - margin,
43298 maxX: p.x + margin,
43299 maxY: p.y + (height / 2) + margin
43303 minX: p.x - margin,
43304 minY: p.y - (height / 2) - margin,
43305 maxX: p.x + width + margin,
43306 maxY: p.y + (height / 2) + margin
43310 if (tryInsert([bbox], entity.id, true)) {
43316 function getLineLabel(entity, width, height) {
43317 var viewport = geoExtent$$1(context.projection.clipExtent()).polygon(),
43318 nodes = lodash.map(graph.childNodes(entity), 'loc').map(projection),
43319 length = geoPathLength(nodes);
43321 if (length < width + 20) return;
43323 // % along the line to attempt to place the label
43324 var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
43325 25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
43328 for (var i = 0; i < lineOffsets.length; i++) {
43329 var offset = lineOffsets[i],
43330 middle = offset / 100 * length,
43331 start = middle - width / 2;
43333 if (start < 0 || start + width > length) continue;
43335 // generate subpath and ignore paths that are invalid or don't cross viewport.
43336 var sub = subpath(nodes, start, start + width);
43337 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
43341 var isReverse = reverse(sub);
43343 sub = sub.reverse();
43347 boxsize = (height + 2) / 2;
43349 for (var j = 0; j < sub.length - 1; j++) {
43351 var b = sub[j + 1];
43352 var num = Math.max(1, Math.floor(geoEuclideanDistance(a, b) / boxsize / 2));
43354 for (var box = 0; box < num; box++) {
43355 var p = geoInterp(a, b, box / num);
43356 var x0 = p[0] - boxsize - margin;
43357 var y0 = p[1] - boxsize - margin;
43358 var x1 = p[0] + boxsize + margin;
43359 var y1 = p[1] + boxsize + margin;
43362 minX: Math.min(x0, x1),
43363 minY: Math.min(y0, y1),
43364 maxX: Math.max(x0, x1),
43365 maxY: Math.max(y0, y1)
43370 if (tryInsert(bboxes, entity.id, false)) {
43372 'font-size': height + 2,
43373 lineString: lineString(sub),
43374 startOffset: offset + '%'
43379 function reverse(p) {
43380 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
43381 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
43384 function lineString(nodes) {
43385 return 'M' + nodes.join('L');
43388 function subpath(nodes, from, to) {
43390 start, end, i0, i1;
43392 for (var i = 0; i < nodes.length - 1; i++) {
43395 var current = geoEuclideanDistance(a, b);
43397 if (!start && sofar + current >= from) {
43398 portion = (from - sofar) / current;
43400 a[0] + portion * (b[0] - a[0]),
43401 a[1] + portion * (b[1] - a[1])
43405 if (!end && sofar + current >= to) {
43406 portion = (to - sofar) / current;
43408 a[0] + portion * (b[0] - a[0]),
43409 a[1] + portion * (b[1] - a[1])
43416 var ret = nodes.slice(i0, i1);
43417 ret.unshift(start);
43424 function getAreaLabel(entity, width, height) {
43425 var centroid = path$$1.centroid(entity.asGeoJSON(graph, true)),
43426 extent$$1 = entity.extent(graph),
43427 entitywidth = projection(extent$$1[1])[0] - projection(extent$$1[0])[0];
43429 if (isNaN(centroid[0]) || entitywidth < 20) return;
43432 iconX = centroid[0] - (iconSize / 2),
43433 iconY = centroid[1] - (iconSize / 2),
43435 textOffset = iconSize + margin,
43436 p = { transform: 'translate(' + iconX + ',' + iconY + ')' };
43441 maxX: iconX + iconSize,
43442 maxY: iconY + iconSize
43446 if (tryInsert([bbox], entity.id + 'I', true)) {
43447 if (width && entitywidth >= width + 20) {
43448 var labelX = centroid[0],
43449 labelY = centroid[1] + textOffset;
43452 minX: labelX - (width / 2) - margin,
43453 minY: labelY - (height / 2) - margin,
43454 maxX: labelX + (width / 2) + margin,
43455 maxY: labelY + (height / 2) + margin
43458 // try to add label
43459 if (tryInsert([bbox], entity.id, true)) {
43462 p.textAnchor = 'middle';
43472 function tryInsert(bboxes, id, saveSkipped) {
43473 var skipped = false,
43476 for (var i = 0; i < bboxes.length; i++) {
43480 // Check that label is visible
43481 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
43485 if (rdrawn.collides(bbox)) {
43491 entitybboxes[id] = bboxes;
43495 rskipped.load(bboxes);
43498 rdrawn.load(bboxes);
43505 var label = selection$$1.selectAll('.layer-label'),
43506 halo = selection$$1.selectAll('.layer-halo');
43509 drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
43510 drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
43513 drawLinePaths(halo, labelled.line, filter, '', positions.line);
43514 drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
43515 drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
43518 drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
43519 drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
43520 drawAreaIcons(label, labelled.area, filter, 'areaicon', positions.area);
43521 drawAreaIcons(halo, labelled.area, filter, 'areaicon-halo', positions.area);
43524 drawCollisionBoxes(label, rskipped, 'debug-skipped');
43525 drawCollisionBoxes(label, rdrawn, 'debug-drawn');
43527 selection$$1.call(filterLabels);
43531 function filterLabels(selection$$1) {
43532 var layers = selection$$1
43533 .selectAll('.layer-label, .layer-halo');
43535 layers.selectAll('.proximate')
43536 .classed('proximate', false);
43538 var mouse$$1 = context.mouse(),
43539 graph = context.graph(),
43540 selectedIDs = context.selectedIDs(),
43544 // hide labels near the mouse
43547 bbox = { minX: mouse$$1[0] - pad, minY: mouse$$1[1] - pad, maxX: mouse$$1[0] + pad, maxY: mouse$$1[1] + pad };
43548 ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
43551 // hide labels along selected ways, or near selected vertices
43552 for (var i = 0; i < selectedIDs.length; i++) {
43553 var entity = graph.hasEntity(selectedIDs[i]);
43554 if (!entity) continue;
43555 var geometry = entity.geometry(graph);
43557 if (geometry === 'line') {
43558 ids.push(selectedIDs[i]);
43559 } else if (geometry === 'vertex') {
43560 var point = context.projection(entity.loc);
43562 bbox = { minX: point[0] - pad, minY: point[1] - pad, maxX: point[0] + pad, maxY: point[1] + pad };
43563 ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
43567 layers.selectAll(utilEntitySelector(ids))
43568 .classed('proximate', true);
43572 var throttleFilterLabels = lodash.throttle(filterLabels, 100);
43575 drawLabels.observe = function(selection$$1) {
43576 var listener = function() { throttleFilterLabels(selection$$1); };
43577 selection$$1.on('mousemove.hidelabels', listener);
43578 context.on('enter.hidelabels', listener);
43582 drawLabels.off = function(selection$$1) {
43583 throttleFilterLabels.cancel();
43584 selection$$1.on('mousemove.hidelabels', null);
43585 context.on('enter.hidelabels', null);
43592 // Copies a variable number of methods from source to target.
43593 function utilRebind(target, source) {
43594 var i = 1, n = arguments.length, method;
43596 target[method = arguments[i]] = d3_rebind(target, source, source[method]);
43601 // Method is assumed to be a standard D3 getter-setter:
43602 // If passed with no arguments, gets the value.
43603 // If passed with arguments, sets the value and returns the target.
43604 function d3_rebind(target, source, method) {
43605 return function() {
43606 var value = method.apply(source, arguments);
43607 return value === source ? target : value;
43611 function refresh(selection, node) {
43612 var cr = node.getBoundingClientRect();
43613 var prop = [cr.width, cr.height];
43614 selection.property('__dimensions__', prop);
43618 function utilGetDimensions(selection, force) {
43619 if (!selection || selection.empty()) {
43622 var node = selection.node(),
43623 cached = selection.property('__dimensions__');
43624 return (!cached || force) ? refresh(selection, node) : cached;
43628 function utilSetDimensions(selection, dimensions) {
43629 if (!selection || selection.empty()) {
43632 var node = selection.node();
43633 if (dimensions === null) {
43634 refresh(selection, node);
43638 .property('__dimensions__', [dimensions[0], dimensions[1]])
43639 .attr('width', dimensions[0])
43640 .attr('height', dimensions[1]);
43643 function svgPointTransform(projection) {
43644 return function(entity) {
43645 // http://jsperf.com/short-array-join
43646 var pt = projection(entity.loc);
43647 return 'translate(' + pt[0] + ',' + pt[1] + ')';
43651 function d3geoTile() {
43652 var size = [960, 500],
43654 scaleExtent = [0, 20],
43655 translate = [size[0] / 2, size[1] / 2],
43658 function bound(_) {
43659 return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
43663 var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
43664 z0 = bound(Math.round(z + zoomDelta)),
43665 k = Math.pow(2, z - z0 + 8),
43666 origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
43668 cols = sequence(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
43669 rows = sequence(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
43671 rows.forEach(function(y) {
43672 cols.forEach(function(x) {
43673 tiles.push([x, y, z0]);
43677 tiles.translate = origin;
43683 tile.scaleExtent = function(_) {
43684 if (!arguments.length) return scaleExtent;
43689 tile.size = function(_) {
43690 if (!arguments.length) return size;
43695 tile.scale = function(_) {
43696 if (!arguments.length) return scale;
43701 tile.translate = function(_) {
43702 if (!arguments.length) return translate;
43707 tile.zoomDelta = function(_) {
43708 if (!arguments.length) return zoomDelta;
43716 /* global Mapillary:false */
43717 var apibase = 'https://a.mapillary.com/v2/';
43718 var viewercss = 'mapillary-js/mapillary.min.css';
43719 var viewerjs = 'mapillary-js/mapillary.min.js';
43720 var trafficocss = 'traffico/stylesheets/traffico.css';
43721 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
43722 var maxResults = 1000;
43724 var dispatch$2 = dispatch('loadedImages', 'loadedSigns');
43725 var mapillaryCache;
43726 var mapillaryClicks;
43727 var mapillaryImage;
43728 var mapillarySignDefs;
43729 var mapillaryViewer;
43732 function abortRequest(i) {
43737 function nearNullIsland(x, y, z) {
43739 var center = Math.pow(2, z - 1),
43740 width = Math.pow(2, z - 6),
43741 min$$1 = center - (width / 2),
43742 max$$1 = center + (width / 2) - 1;
43743 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
43749 function maxPageAtZoom(z) {
43750 if (z < 15) return 2;
43751 if (z === 15) return 5;
43752 if (z === 16) return 10;
43753 if (z === 17) return 20;
43754 if (z === 18) return 40;
43755 if (z > 18) return 80;
43759 function getTiles(projection) {
43760 var s = projection.scale() * 2 * Math.PI,
43761 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
43762 ts = 256 * Math.pow(2, z - tileZoom),
43764 s / 2 - projection.translate()[0],
43765 s / 2 - projection.translate()[1]];
43768 .scaleExtent([tileZoom, tileZoom])
43770 .size(projection.clipExtent()[1])
43771 .translate(projection.translate())()
43772 .map(function(tile) {
43773 var x = tile[0] * ts - origin[0],
43774 y = tile[1] * ts - origin[1];
43777 id: tile.toString(),
43779 extent: geoExtent$$1(
43780 projection.invert([x, y + ts]),
43781 projection.invert([x + ts, y])
43788 function loadTiles(which, url, projection) {
43789 var s = projection.scale() * 2 * Math.PI,
43790 currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
43792 var tiles = getTiles(projection).filter(function(t) {
43793 return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
43796 lodash.filter(which.inflight, function(v, k) {
43797 var wanted = lodash.find(tiles, function(tile) { return k === (tile.id + ',0'); });
43798 if (!wanted) delete which.inflight[k];
43800 }).map(abortRequest);
43802 tiles.forEach(function(tile) {
43803 loadNextTilePage(which, currZoom, url, tile);
43808 function loadNextTilePage(which, currZoom, url, tile) {
43809 var cache = mapillaryCache[which],
43810 rect = tile.extent.rectangle(),
43811 maxPages = maxPageAtZoom(currZoom),
43812 nextPage = cache.nextPage[tile.id] || 0;
43814 if (nextPage > maxPages) return;
43816 var id = tile.id + ',' + String(nextPage);
43817 if (cache.loaded[id] || cache.inflight[id]) return;
43819 cache.inflight[id] = json(url +
43824 client_id: clientId,
43829 }), function(err, data) {
43830 cache.loaded[id] = true;
43831 delete cache.inflight[id];
43832 if (err || !data.features || !data.features.length) return;
43837 for (var i = 0; i < data.features.length; i++) {
43838 feature = data.features[i];
43839 loc = feature.geometry.coordinates;
43840 d = { key: feature.properties.key, loc: loc };
43841 if (which === 'images') d.ca = feature.properties.ca;
43842 if (which === 'signs') d.signs = feature.properties.rects;
43844 features.push({minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d});
43847 cache.rtree.load(features);
43849 if (which === 'images') dispatch$2.call('loadedImages');
43850 if (which === 'signs') dispatch$2.call('loadedSigns');
43852 if (data.features.length === maxResults) { // more pages to load
43853 cache.nextPage[tile.id] = nextPage + 1;
43854 loadNextTilePage(which, currZoom, url, tile);
43856 cache.nextPage[tile.id] = Infinity; // no more pages to load
43863 // partition viewport into `psize` x `psize` regions
43864 function partitionViewport(psize, projection) {
43865 var dimensions = projection.clipExtent()[1];
43866 psize = psize || 16;
43867 var cols = sequence(0, dimensions[0], psize),
43868 rows = sequence(0, dimensions[1], psize),
43871 rows.forEach(function(y) {
43872 cols.forEach(function(x) {
43873 var min$$1 = [x, y + psize],
43874 max$$1 = [x + psize, y];
43876 geoExtent$$1(projection.invert(min$$1), projection.invert(max$$1)));
43884 // no more than `limit` results per partition.
43885 function searchLimited(psize, limit, projection, rtree) {
43886 limit = limit || 3;
43888 var partitions = partitionViewport(psize, projection);
43889 return lodash.flatten(lodash.compact(lodash.map(partitions, function(extent$$1) {
43890 return rtree.search(extent$$1.bbox())
43892 .map(function(d) { return d.data; });
43898 var serviceMapillary = {
43901 if (!mapillaryCache) {
43905 this.event = utilRebind(this, dispatch$2, 'on');
43908 reset: function() {
43909 var cache = mapillaryCache;
43912 if (cache.images && cache.images.inflight) {
43913 lodash.forEach(cache.images.inflight, abortRequest);
43915 if (cache.signs && cache.signs.inflight) {
43916 lodash.forEach(cache.signs.inflight, abortRequest);
43921 images: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$9() },
43922 signs: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$9() }
43925 mapillaryImage = null;
43926 mapillaryClicks = [];
43930 images: function(projection) {
43931 var psize = 16, limit = 3;
43932 return searchLimited(psize, limit, projection, mapillaryCache.images.rtree);
43936 signs: function(projection) {
43937 var psize = 32, limit = 3;
43938 return searchLimited(psize, limit, projection, mapillaryCache.signs.rtree);
43942 signsSupported: function() {
43943 var detected = utilDetect();
43944 if (detected.ie) return false;
43945 if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
43950 signHTML: function(d) {
43951 if (!mapillarySignDefs) return;
43953 var detectionPackage = d.signs[0].package,
43954 type = d.signs[0].type,
43955 country = detectionPackage.split('_')[1];
43957 return mapillarySignDefs[country][type];
43961 loadImages: function(projection) {
43962 var url = apibase + 'search/im/geojson?';
43963 loadTiles('images', url, projection);
43967 loadSigns: function(context, projection) {
43968 var url = apibase + 'search/im/geojson/or?';
43969 loadTiles('signs', url, projection);
43971 // load traffico css
43972 select('head').selectAll('#traffico')
43976 .attr('id', 'traffico')
43977 .attr('rel', 'stylesheet')
43978 .attr('href', context.asset(trafficocss));
43980 // load traffico sign defs
43981 if (!mapillarySignDefs) {
43982 mapillarySignDefs = {};
43983 lodash.each(['au', 'br', 'ca', 'de', 'us'], function(region) {
43984 json(context.asset('traffico/string-maps/' + region + '-map.json'), function(err, data) {
43986 if (region === 'de') region = 'eu';
43987 mapillarySignDefs[region] = data;
43994 loadViewer: function(context) {
43996 var wrap = select('#content').selectAll('.mapillary-wrap')
43999 var enter = wrap.enter()
44001 .attr('class', 'mapillary-wrap')
44002 .classed('al', true) // 'al'=left, 'ar'=right
44003 .classed('hidden', true);
44007 .attr('class', 'thumb-hide')
44008 .on('click', function () { that.hideViewer(); })
44010 .call(svgIcon('#icon-close'));
44015 .attr('class', 'mly-wrapper')
44016 .classed('active', false);
44018 // load mapillary-viewercss
44019 select('head').selectAll('#mapillary-viewercss')
44023 .attr('id', 'mapillary-viewercss')
44024 .attr('rel', 'stylesheet')
44025 .attr('href', context.asset(viewercss));
44027 // load mapillary-viewerjs
44028 select('head').selectAll('#mapillary-viewerjs')
44032 .attr('id', 'mapillary-viewerjs')
44033 .attr('src', context.asset(viewerjs));
44037 showViewer: function() {
44039 .selectAll('.mapillary-wrap')
44040 .classed('hidden', false)
44041 .selectAll('.mly-wrapper')
44042 .classed('active', true);
44048 hideViewer: function() {
44050 .selectAll('.mapillary-wrap')
44051 .classed('hidden', true)
44052 .selectAll('.mly-wrapper')
44053 .classed('active', false);
44055 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
44056 .classed('selected', false);
44058 mapillaryImage = null;
44063 updateViewer: function(imageKey, context) {
44064 if (!imageKey) return;
44066 if (!mapillaryViewer) {
44067 this.initViewer(imageKey, context);
44069 mapillaryViewer.moveToKey(imageKey);
44076 initViewer: function(imageKey, context) {
44078 if (Mapillary && imageKey) {
44080 baseImageSize: 320,
44087 mapillaryViewer = new Mapillary.Viewer('mly', clientId, imageKey, opts);
44088 mapillaryViewer.on('nodechanged', nodeChanged);
44091 function nodeChanged(node) {
44092 var clicks = mapillaryClicks;
44093 var index = clicks.indexOf(node.key);
44094 if (index > -1) { // nodechange initiated from clicking on a marker..
44095 clicks.splice(index, 1);
44096 } else { // nodechange initiated from the Mapillary viewer controls..
44097 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
44098 context.map().centerEase(loc);
44099 that.selectedImage(node.key, false);
44105 selectedImage: function(imageKey, fromClick) {
44106 if (!arguments.length) return mapillaryImage;
44108 mapillaryImage = imageKey;
44110 mapillaryClicks.push(imageKey);
44113 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
44114 .classed('selected', function(d) { return d.key === imageKey; });
44120 cache: function(_) {
44121 if (!arguments.length) return mapillaryCache;
44122 mapillaryCache = _;
44127 signDefs: function(_) {
44128 if (!arguments.length) return mapillarySignDefs;
44129 mapillarySignDefs = _;
44135 var apibase$1 = 'https://nominatim.openstreetmap.org/';
44136 var nominatimCache;
44139 var serviceNominatim = {
44141 init: function() { nominatimCache = index$9(); },
44142 reset: function() { nominatimCache = index$9(); },
44145 countryCode: function (location, callback) {
44146 var countryCodes = nominatimCache.search(
44147 { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
44150 if (countryCodes.length > 0) {
44151 return callback(null, countryCodes[0].data);
44154 json(apibase$1 + 'reverse?' +
44160 }), function(err, result) {
44162 return callback(err);
44163 else if (result && result.error)
44164 return callback(result.error);
44166 var extent$$1 = geoExtent$$1(location).padByMeters(1000);
44167 nominatimCache.insert(lodash.assign(extent$$1.bbox(),
44168 { data: result.address.country_code }
44171 callback(null, result.address.country_code);
44177 search: function (val, callback) {
44178 var searchVal = encodeURIComponent(val);
44179 json(apibase$1 + 'search/' + searchVal + '?limit=10&format=json', callback);
44184 var hashes$1 = createCommonjsModule(function (module, exports) {
44186 * jshashes - https://github.com/h2non/jshashes
44187 * Released under the "New BSD" license
44189 * Algorithms specification:
44191 * MD5 - http://www.ietf.org/rfc/rfc1321.txt
44192 * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
44193 * SHA1 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
44194 * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
44195 * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
44196 * HMAC - http://www.ietf.org/rfc/rfc2104.txt
44201 function utf8Encode(str) {
44202 var x, y, output = '',
44206 if (str && str.length) {
44208 while ((i += 1) < l) {
44209 /* Decode utf-16 surrogate pairs */
44210 x = str.charCodeAt(i);
44211 y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
44212 if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
44213 x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
44216 /* Encode output as utf-8 */
44218 output += String.fromCharCode(x);
44219 } else if (x <= 0x7FF) {
44220 output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
44221 0x80 | (x & 0x3F));
44222 } else if (x <= 0xFFFF) {
44223 output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
44224 0x80 | ((x >>> 6) & 0x3F),
44225 0x80 | (x & 0x3F));
44226 } else if (x <= 0x1FFFFF) {
44227 output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
44228 0x80 | ((x >>> 12) & 0x3F),
44229 0x80 | ((x >>> 6) & 0x3F),
44230 0x80 | (x & 0x3F));
44237 function utf8Decode(str) {
44238 var i, ac, c1, c2, c3, arr = [],
44240 i = ac = c1 = c2 = c3 = 0;
44242 if (str && str.length) {
44247 c1 = str.charCodeAt(i);
44250 arr[ac] = String.fromCharCode(c1);
44252 } else if (c1 > 191 && c1 < 224) {
44253 c2 = str.charCodeAt(i + 1);
44254 arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
44257 c2 = str.charCodeAt(i + 1);
44258 c3 = str.charCodeAt(i + 2);
44259 arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
44264 return arr.join('');
44268 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
44269 * to work around bugs in some JS interpreters.
44272 function safe_add(x, y) {
44273 var lsw = (x & 0xFFFF) + (y & 0xFFFF),
44274 msw = (x >> 16) + (y >> 16) + (lsw >> 16);
44275 return (msw << 16) | (lsw & 0xFFFF);
44279 * Bitwise rotate a 32-bit number to the left.
44282 function bit_rol(num, cnt) {
44283 return (num << cnt) | (num >>> (32 - cnt));
44287 * Convert a raw string to a hex string
44290 function rstr2hex(input, hexcase) {
44291 var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
44295 for (; i < l; i += 1) {
44296 x = input.charCodeAt(i);
44297 output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
44303 * Encode a string as utf-16
44306 function binb2rstr(input) {
44307 var i, l = input.length * 32,
44309 for (i = 0; i < l; i += 8) {
44310 output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
44316 * Convert an array of little-endian words to a string
44319 function binl2rstr(input) {
44320 var i, l = input.length * 32,
44322 for (i = 0; i < l; i += 8) {
44323 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
44329 * Convert a raw string to an array of little-endian words
44330 * Characters >255 have their high-byte silently ignored.
44333 function rstr2binl(input) {
44334 var i, l = input.length * 8,
44335 output = Array(input.length >> 2),
44336 lo = output.length;
44337 for (i = 0; i < lo; i += 1) {
44340 for (i = 0; i < l; i += 8) {
44341 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
44347 * Convert a raw string to an array of big-endian words
44348 * Characters >255 have their high-byte silently ignored.
44351 function rstr2binb(input) {
44352 var i, l = input.length * 8,
44353 output = Array(input.length >> 2),
44354 lo = output.length;
44355 for (i = 0; i < lo; i += 1) {
44358 for (i = 0; i < l; i += 8) {
44359 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
44365 * Convert a raw string to an arbitrary string encoding
44368 function rstr2any(input, encoding) {
44369 var divisor = encoding.length,
44370 remainders = Array(),
44371 i, q, x, ld, quotient, dividend, output, full_length;
44373 /* Convert to an array of 16-bit big-endian values, forming the dividend */
44374 dividend = Array(Math.ceil(input.length / 2));
44375 ld = dividend.length;
44376 for (i = 0; i < ld; i += 1) {
44377 dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
44381 * Repeatedly perform a long division. The binary array forms the dividend,
44382 * the length of the encoding is the divisor. Once computed, the quotient
44383 * forms the dividend for the next step. We stop when the dividend is zerHashes.
44384 * All remainders are stored for later use.
44386 while (dividend.length > 0) {
44387 quotient = Array();
44389 for (i = 0; i < dividend.length; i += 1) {
44390 x = (x << 16) + dividend[i];
44391 q = Math.floor(x / divisor);
44393 if (quotient.length > 0 || q > 0) {
44394 quotient[quotient.length] = q;
44397 remainders[remainders.length] = x;
44398 dividend = quotient;
44401 /* Convert the remainders to the output string */
44403 for (i = remainders.length - 1; i >= 0; i--) {
44404 output += encoding.charAt(remainders[i]);
44407 /* Append leading zero equivalents */
44408 full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
44409 for (i = output.length; i < full_length; i += 1) {
44410 output = encoding[0] + output;
44416 * Convert a raw string to a base-64 string
44419 function rstr2b64(input, b64pad) {
44420 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
44422 len = input.length,
44424 b64pad = b64pad || '=';
44425 for (i = 0; i < len; i += 3) {
44426 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
44427 for (j = 0; j < 4; j += 1) {
44428 if (i * 8 + j * 6 > input.length * 8) {
44431 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
44440 * @property {String} version
44449 Base64: function() {
44450 // private properties
44451 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
44452 pad = '=', // default pad according with the RFC standard
44453 url = false, // URL encoding support @todo
44454 utf8 = true; // by default enable UTF-8 support encoding
44456 // public method for encoding
44457 this.encode = function(input) {
44460 len = input.length;
44463 input = (utf8) ? utf8Encode(input) : input;
44465 for (i = 0; i < len; i += 3) {
44466 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
44467 for (j = 0; j < 4; j += 1) {
44468 if (i * 8 + j * 6 > len * 8) {
44471 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
44478 // public method for decoding
44479 this.decode = function(input) {
44480 // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
44481 var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
44489 input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
44492 do { // unpack four hexets into three octets using index points in b64
44493 h1 = tab.indexOf(input.charAt(i += 1));
44494 h2 = tab.indexOf(input.charAt(i += 1));
44495 h3 = tab.indexOf(input.charAt(i += 1));
44496 h4 = tab.indexOf(input.charAt(i += 1));
44498 bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
44500 o1 = bits >> 16 & 0xff;
44501 o2 = bits >> 8 & 0xff;
44506 arr[ac] = String.fromCharCode(o1);
44507 } else if (h4 === 64) {
44508 arr[ac] = String.fromCharCode(o1, o2);
44510 arr[ac] = String.fromCharCode(o1, o2, o3);
44512 } while (i < input.length);
44514 dec = arr.join('');
44515 dec = (utf8) ? utf8Decode(dec) : dec;
44520 // set custom pad string
44521 this.setPad = function(str) {
44525 // set custom tab string characters
44526 this.setTab = function(str) {
44530 this.setUTF8 = function(bool) {
44531 if (typeof bool === 'boolean') {
44539 * CRC-32 calculation
44543 * @param {String} str Input String
44546 CRC32: function(str) {
44551 str = utf8Encode(str);
44554 '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
44555 '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
44556 '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
44557 '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
44558 'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
44559 '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
44560 'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
44561 '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
44562 'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
44563 '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
44564 'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
44565 '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
44566 'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
44567 '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
44568 '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
44569 '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
44570 '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
44571 'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
44572 '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
44573 'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
44574 '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
44575 'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
44576 '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
44577 'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
44578 '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
44579 'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
44583 for (i = 0, iTop = str.length; i < iTop; i += 1) {
44584 y = (crc ^ str.charCodeAt(i)) & 0xFF;
44585 x = '0x' + table.substr(y * 9, 8);
44586 crc = (crc >>> 8) ^ x;
44588 // always return a positive number (that's what >>> 0 does)
44589 return (crc ^ (-1)) >>> 0;
44595 * @param {Object} [config]
44597 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
44598 * Digest Algorithm, as defined in RFC 1321.
44599 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
44600 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44601 * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
44603 MD5: function(options) {
44605 * Private config properties. You may need to tweak these to be compatible with
44606 * the server-side, but the defaults work in most cases.
44607 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44609 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44610 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44611 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44613 // privileged (public) methods
44614 this.hex = function(s) {
44615 return rstr2hex(rstr(s, utf8), hexcase);
44617 this.b64 = function(s) {
44618 return rstr2b64(rstr(s), b64pad);
44620 this.any = function(s, e) {
44621 return rstr2any(rstr(s, utf8), e);
44623 this.raw = function(s) {
44624 return rstr(s, utf8);
44626 this.hex_hmac = function(k, d) {
44627 return rstr2hex(rstr_hmac(k, d), hexcase);
44629 this.b64_hmac = function(k, d) {
44630 return rstr2b64(rstr_hmac(k, d), b64pad);
44632 this.any_hmac = function(k, d, e) {
44633 return rstr2any(rstr_hmac(k, d), e);
44636 * Perform a simple self-test to see if the VM is working
44637 * @return {String} Hexadecimal hash sample
44639 this.vm_test = function() {
44640 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44643 * Enable/disable uppercase hexadecimal returned string
44645 * @return {Object} this
44647 this.setUpperCase = function(a) {
44648 if (typeof a === 'boolean') {
44654 * Defines a base64 pad string
44655 * @param {String} Pad
44656 * @return {Object} this
44658 this.setPad = function(a) {
44659 b64pad = a || b64pad;
44663 * Defines a base64 pad string
44665 * @return {Object} [this]
44667 this.setUTF8 = function(a) {
44668 if (typeof a === 'boolean') {
44677 * Calculate the MD5 of a raw string
44681 s = (utf8) ? utf8Encode(s) : s;
44682 return binl2rstr(binl(rstr2binl(s), s.length * 8));
44686 * Calculate the HMAC-MD5, of a key and some data (raw strings)
44689 function rstr_hmac(key, data) {
44690 var bkey, ipad, opad, hash, i;
44692 key = (utf8) ? utf8Encode(key) : key;
44693 data = (utf8) ? utf8Encode(data) : data;
44694 bkey = rstr2binl(key);
44695 if (bkey.length > 16) {
44696 bkey = binl(bkey, key.length * 8);
44699 ipad = Array(16), opad = Array(16);
44700 for (i = 0; i < 16; i += 1) {
44701 ipad[i] = bkey[i] ^ 0x36363636;
44702 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44704 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
44705 return binl2rstr(binl(opad.concat(hash), 512 + 128));
44709 * Calculate the MD5 of an array of little-endian words, and a bit length.
44712 function binl(x, len) {
44713 var i, olda, oldb, oldc, oldd,
44719 /* append padding */
44720 x[len >> 5] |= 0x80 << ((len) % 32);
44721 x[(((len + 64) >>> 9) << 4) + 14] = len;
44723 for (i = 0; i < x.length; i += 16) {
44729 a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
44730 d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
44731 c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
44732 b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
44733 a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
44734 d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
44735 c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
44736 b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
44737 a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
44738 d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
44739 c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
44740 b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
44741 a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
44742 d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
44743 c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
44744 b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
44746 a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
44747 d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
44748 c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
44749 b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
44750 a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
44751 d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
44752 c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
44753 b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
44754 a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
44755 d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
44756 c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
44757 b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
44758 a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
44759 d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
44760 c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
44761 b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
44763 a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
44764 d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
44765 c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
44766 b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
44767 a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
44768 d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
44769 c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
44770 b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
44771 a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
44772 d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
44773 c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
44774 b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
44775 a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
44776 d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
44777 c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
44778 b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
44780 a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
44781 d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
44782 c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
44783 b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
44784 a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
44785 d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
44786 c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
44787 b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
44788 a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
44789 d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
44790 c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
44791 b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
44792 a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
44793 d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
44794 c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
44795 b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
44797 a = safe_add(a, olda);
44798 b = safe_add(b, oldb);
44799 c = safe_add(c, oldc);
44800 d = safe_add(d, oldd);
44802 return Array(a, b, c, d);
44806 * These functions implement the four basic operations the algorithm uses.
44809 function md5_cmn(q, a, b, x, s, t) {
44810 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
44813 function md5_ff(a, b, c, d, x, s, t) {
44814 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
44817 function md5_gg(a, b, c, d, x, s, t) {
44818 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
44821 function md5_hh(a, b, c, d, x, s, t) {
44822 return md5_cmn(b ^ c ^ d, a, b, x, s, t);
44825 function md5_ii(a, b, c, d, x, s, t) {
44826 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
44831 * @class Hashes.SHA1
44832 * @param {Object} [config]
44835 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
44836 * Version 2.2 Copyright Paul Johnston 2000 - 2009.
44837 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44838 * See http://pajhome.org.uk/crypt/md5 for details.
44840 SHA1: function(options) {
44842 * Private config properties. You may need to tweak these to be compatible with
44843 * the server-side, but the defaults work in most cases.
44844 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44846 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44847 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44848 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44851 this.hex = function(s) {
44852 return rstr2hex(rstr(s, utf8), hexcase);
44854 this.b64 = function(s) {
44855 return rstr2b64(rstr(s, utf8), b64pad);
44857 this.any = function(s, e) {
44858 return rstr2any(rstr(s, utf8), e);
44860 this.raw = function(s) {
44861 return rstr(s, utf8);
44863 this.hex_hmac = function(k, d) {
44864 return rstr2hex(rstr_hmac(k, d));
44866 this.b64_hmac = function(k, d) {
44867 return rstr2b64(rstr_hmac(k, d), b64pad);
44869 this.any_hmac = function(k, d, e) {
44870 return rstr2any(rstr_hmac(k, d), e);
44873 * Perform a simple self-test to see if the VM is working
44874 * @return {String} Hexadecimal hash sample
44877 this.vm_test = function() {
44878 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44881 * @description Enable/disable uppercase hexadecimal returned string
44883 * @return {Object} this
44886 this.setUpperCase = function(a) {
44887 if (typeof a === 'boolean') {
44893 * @description Defines a base64 pad string
44894 * @param {string} Pad
44895 * @return {Object} this
44898 this.setPad = function(a) {
44899 b64pad = a || b64pad;
44903 * @description Defines a base64 pad string
44905 * @return {Object} this
44908 this.setUTF8 = function(a) {
44909 if (typeof a === 'boolean') {
44918 * Calculate the SHA-512 of a raw string
44922 s = (utf8) ? utf8Encode(s) : s;
44923 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44927 * Calculate the HMAC-SHA1 of a key and some data (raw strings)
44930 function rstr_hmac(key, data) {
44931 var bkey, ipad, opad, i, hash;
44932 key = (utf8) ? utf8Encode(key) : key;
44933 data = (utf8) ? utf8Encode(data) : data;
44934 bkey = rstr2binb(key);
44936 if (bkey.length > 16) {
44937 bkey = binb(bkey, key.length * 8);
44939 ipad = Array(16), opad = Array(16);
44940 for (i = 0; i < 16; i += 1) {
44941 ipad[i] = bkey[i] ^ 0x36363636;
44942 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44944 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
44945 return binb2rstr(binb(opad.concat(hash), 512 + 160));
44949 * Calculate the SHA-1 of an array of big-endian words, and a bit length
44952 function binb(x, len) {
44953 var i, j, t, olda, oldb, oldc, oldd, olde,
44961 /* append padding */
44962 x[len >> 5] |= 0x80 << (24 - len % 32);
44963 x[((len + 64 >> 9) << 4) + 15] = len;
44965 for (i = 0; i < x.length; i += 16) {
44972 for (j = 0; j < 80; j += 1) {
44976 w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
44978 t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
44979 safe_add(safe_add(e, w[j]), sha1_kt(j)));
44982 c = bit_rol(b, 30);
44987 a = safe_add(a, olda);
44988 b = safe_add(b, oldb);
44989 c = safe_add(c, oldc);
44990 d = safe_add(d, oldd);
44991 e = safe_add(e, olde);
44993 return Array(a, b, c, d, e);
44997 * Perform the appropriate triplet combination function for the current
45001 function sha1_ft(t, b, c, d) {
45003 return (b & c) | ((~b) & d);
45009 return (b & c) | (b & d) | (c & d);
45015 * Determine the appropriate additive constant for the current iteration
45018 function sha1_kt(t) {
45019 return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
45020 (t < 60) ? -1894007588 : -899497514;
45024 * @class Hashes.SHA256
45027 * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
45028 * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
45029 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45030 * See http://pajhome.org.uk/crypt/md5 for details.
45031 * Also http://anmar.eu.org/projects/jssha2/
45033 SHA256: function(options) {
45035 * Private properties configuration variables. You may need to tweak these to be compatible with
45036 * the server-side, but the defaults work in most cases.
45037 * @see this.setUpperCase() method
45038 * @see this.setPad() method
45040 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase */
45041 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45042 /* base-64 pad character. Default '=' for strict RFC compliance */
45043 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45044 /* enable/disable utf8 encoding */
45047 /* privileged (public) methods */
45048 this.hex = function(s) {
45049 return rstr2hex(rstr(s, utf8));
45051 this.b64 = function(s) {
45052 return rstr2b64(rstr(s, utf8), b64pad);
45054 this.any = function(s, e) {
45055 return rstr2any(rstr(s, utf8), e);
45057 this.raw = function(s) {
45058 return rstr(s, utf8);
45060 this.hex_hmac = function(k, d) {
45061 return rstr2hex(rstr_hmac(k, d));
45063 this.b64_hmac = function(k, d) {
45064 return rstr2b64(rstr_hmac(k, d), b64pad);
45066 this.any_hmac = function(k, d, e) {
45067 return rstr2any(rstr_hmac(k, d), e);
45070 * Perform a simple self-test to see if the VM is working
45071 * @return {String} Hexadecimal hash sample
45074 this.vm_test = function() {
45075 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45078 * Enable/disable uppercase hexadecimal returned string
45080 * @return {Object} this
45083 this.setUpperCase = function(a) {
45084 if (typeof a === 'boolean') {
45090 * @description Defines a base64 pad string
45091 * @param {string} Pad
45092 * @return {Object} this
45095 this.setPad = function(a) {
45096 b64pad = a || b64pad;
45100 * Defines a base64 pad string
45102 * @return {Object} this
45105 this.setUTF8 = function(a) {
45106 if (typeof a === 'boolean') {
45115 * Calculate the SHA-512 of a raw string
45118 function rstr(s, utf8) {
45119 s = (utf8) ? utf8Encode(s) : s;
45120 return binb2rstr(binb(rstr2binb(s), s.length * 8));
45124 * Calculate the HMAC-sha256 of a key and some data (raw strings)
45127 function rstr_hmac(key, data) {
45128 key = (utf8) ? utf8Encode(key) : key;
45129 data = (utf8) ? utf8Encode(data) : data;
45131 bkey = rstr2binb(key),
45135 if (bkey.length > 16) {
45136 bkey = binb(bkey, key.length * 8);
45139 for (; i < 16; i += 1) {
45140 ipad[i] = bkey[i] ^ 0x36363636;
45141 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45144 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
45145 return binb2rstr(binb(opad.concat(hash), 512 + 256));
45149 * Main sha256 function, with its support functions
45152 function sha256_S(X, n) {
45153 return (X >>> n) | (X << (32 - n));
45156 function sha256_R(X, n) {
45160 function sha256_Ch(x, y, z) {
45161 return ((x & y) ^ ((~x) & z));
45164 function sha256_Maj(x, y, z) {
45165 return ((x & y) ^ (x & z) ^ (y & z));
45168 function sha256_Sigma0256(x) {
45169 return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
45172 function sha256_Sigma1256(x) {
45173 return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
45176 function sha256_Gamma0256(x) {
45177 return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
45180 function sha256_Gamma1256(x) {
45181 return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
45185 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
45186 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
45187 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
45188 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
45189 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
45190 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
45191 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
45194 function binb(m, l) {
45195 var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
45196 1359893119, -1694144372, 528734635, 1541459225
45198 var W = new Array(64);
45199 var a, b, c, d, e, f, g, h;
45202 /* append padding */
45203 m[l >> 5] |= 0x80 << (24 - l % 32);
45204 m[((l + 64 >> 9) << 4) + 15] = l;
45206 for (i = 0; i < m.length; i += 16) {
45216 for (j = 0; j < 64; j += 1) {
45220 W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
45221 sha256_Gamma0256(W[j - 15])), W[j - 16]);
45224 T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
45225 sha256_K[j]), W[j]);
45226 T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
45230 e = safe_add(d, T1);
45234 a = safe_add(T1, T2);
45237 HASH[0] = safe_add(a, HASH[0]);
45238 HASH[1] = safe_add(b, HASH[1]);
45239 HASH[2] = safe_add(c, HASH[2]);
45240 HASH[3] = safe_add(d, HASH[3]);
45241 HASH[4] = safe_add(e, HASH[4]);
45242 HASH[5] = safe_add(f, HASH[5]);
45243 HASH[6] = safe_add(g, HASH[6]);
45244 HASH[7] = safe_add(h, HASH[7]);
45252 * @class Hashes.SHA512
45255 * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
45256 * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
45257 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45258 * See http://pajhome.org.uk/crypt/md5 for details.
45260 SHA512: function(options) {
45262 * Private properties configuration variables. You may need to tweak these to be compatible with
45263 * the server-side, but the defaults work in most cases.
45264 * @see this.setUpperCase() method
45265 * @see this.setPad() method
45267 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
45268 /* hexadecimal output case format. false - lowercase; true - uppercase */
45269 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45270 /* base-64 pad character. Default '=' for strict RFC compliance */
45271 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45272 /* enable/disable utf8 encoding */
45275 /* privileged (public) methods */
45276 this.hex = function(s) {
45277 return rstr2hex(rstr(s));
45279 this.b64 = function(s) {
45280 return rstr2b64(rstr(s), b64pad);
45282 this.any = function(s, e) {
45283 return rstr2any(rstr(s), e);
45285 this.raw = function(s) {
45286 return rstr(s, utf8);
45288 this.hex_hmac = function(k, d) {
45289 return rstr2hex(rstr_hmac(k, d));
45291 this.b64_hmac = function(k, d) {
45292 return rstr2b64(rstr_hmac(k, d), b64pad);
45294 this.any_hmac = function(k, d, e) {
45295 return rstr2any(rstr_hmac(k, d), e);
45298 * Perform a simple self-test to see if the VM is working
45299 * @return {String} Hexadecimal hash sample
45302 this.vm_test = function() {
45303 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45306 * @description Enable/disable uppercase hexadecimal returned string
45308 * @return {Object} this
45311 this.setUpperCase = function(a) {
45312 if (typeof a === 'boolean') {
45318 * @description Defines a base64 pad string
45319 * @param {string} Pad
45320 * @return {Object} this
45323 this.setPad = function(a) {
45324 b64pad = a || b64pad;
45328 * @description Defines a base64 pad string
45330 * @return {Object} this
45333 this.setUTF8 = function(a) {
45334 if (typeof a === 'boolean') {
45340 /* private methods */
45343 * Calculate the SHA-512 of a raw string
45347 s = (utf8) ? utf8Encode(s) : s;
45348 return binb2rstr(binb(rstr2binb(s), s.length * 8));
45351 * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
45354 function rstr_hmac(key, data) {
45355 key = (utf8) ? utf8Encode(key) : key;
45356 data = (utf8) ? utf8Encode(data) : data;
45359 bkey = rstr2binb(key),
45363 if (bkey.length > 32) {
45364 bkey = binb(bkey, key.length * 8);
45367 for (; i < 32; i += 1) {
45368 ipad[i] = bkey[i] ^ 0x36363636;
45369 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45372 hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
45373 return binb2rstr(binb(opad.concat(hash), 1024 + 512));
45377 * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
45380 function binb(x, len) {
45383 hash = new Array(16),
45384 //Initial hash values
45386 new int64(0x6a09e667, -205731576),
45387 new int64(-1150833019, -2067093701),
45388 new int64(0x3c6ef372, -23791573),
45389 new int64(-1521486534, 0x5f1d36f1),
45390 new int64(0x510e527f, -1377402159),
45391 new int64(-1694144372, 0x2b3e6c1f),
45392 new int64(0x1f83d9ab, -79577749),
45393 new int64(0x5be0cd19, 0x137e2179)
45395 T1 = new int64(0, 0),
45396 T2 = new int64(0, 0),
45397 a = new int64(0, 0),
45398 b = new int64(0, 0),
45399 c = new int64(0, 0),
45400 d = new int64(0, 0),
45401 e = new int64(0, 0),
45402 f = new int64(0, 0),
45403 g = new int64(0, 0),
45404 h = new int64(0, 0),
45405 //Temporary variables not specified by the document
45406 s0 = new int64(0, 0),
45407 s1 = new int64(0, 0),
45408 Ch = new int64(0, 0),
45409 Maj = new int64(0, 0),
45410 r1 = new int64(0, 0),
45411 r2 = new int64(0, 0),
45412 r3 = new int64(0, 0);
45414 if (sha512_k === undefined) {
45417 new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
45418 new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
45419 new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
45420 new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
45421 new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
45422 new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
45423 new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
45424 new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
45425 new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
45426 new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
45427 new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
45428 new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
45429 new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
45430 new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
45431 new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
45432 new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
45433 new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
45434 new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
45435 new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
45436 new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
45437 new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
45438 new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
45439 new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
45440 new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
45441 new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
45442 new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
45443 new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
45444 new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
45445 new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
45446 new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
45447 new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
45448 new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
45449 new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
45450 new int64(-354779690, -840897762), new int64(-176337025, -294727304),
45451 new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
45452 new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
45453 new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
45454 new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
45455 new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
45456 new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
45460 for (i = 0; i < 80; i += 1) {
45461 W[i] = new int64(0, 0);
45464 // append padding to the source string. The format is described in the FIPS.
45465 x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
45466 x[((len + 128 >> 10) << 5) + 31] = len;
45468 for (i = 0; i < l; i += 32) { //32 dwords is the block size
45469 int64copy(a, H[0]);
45470 int64copy(b, H[1]);
45471 int64copy(c, H[2]);
45472 int64copy(d, H[3]);
45473 int64copy(e, H[4]);
45474 int64copy(f, H[5]);
45475 int64copy(g, H[6]);
45476 int64copy(h, H[7]);
45478 for (j = 0; j < 16; j += 1) {
45479 W[j].h = x[i + 2 * j];
45480 W[j].l = x[i + 2 * j + 1];
45483 for (j = 16; j < 80; j += 1) {
45485 int64rrot(r1, W[j - 2], 19);
45486 int64revrrot(r2, W[j - 2], 29);
45487 int64shr(r3, W[j - 2], 6);
45488 s1.l = r1.l ^ r2.l ^ r3.l;
45489 s1.h = r1.h ^ r2.h ^ r3.h;
45491 int64rrot(r1, W[j - 15], 1);
45492 int64rrot(r2, W[j - 15], 8);
45493 int64shr(r3, W[j - 15], 7);
45494 s0.l = r1.l ^ r2.l ^ r3.l;
45495 s0.h = r1.h ^ r2.h ^ r3.h;
45497 int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
45500 for (j = 0; j < 80; j += 1) {
45502 Ch.l = (e.l & f.l) ^ (~e.l & g.l);
45503 Ch.h = (e.h & f.h) ^ (~e.h & g.h);
45506 int64rrot(r1, e, 14);
45507 int64rrot(r2, e, 18);
45508 int64revrrot(r3, e, 9);
45509 s1.l = r1.l ^ r2.l ^ r3.l;
45510 s1.h = r1.h ^ r2.h ^ r3.h;
45513 int64rrot(r1, a, 28);
45514 int64revrrot(r2, a, 2);
45515 int64revrrot(r3, a, 7);
45516 s0.l = r1.l ^ r2.l ^ r3.l;
45517 s0.h = r1.h ^ r2.h ^ r3.h;
45520 Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
45521 Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
45523 int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
45524 int64add(T2, s0, Maj);
45529 int64add(e, d, T1);
45533 int64add(a, T1, T2);
45535 int64add(H[0], H[0], a);
45536 int64add(H[1], H[1], b);
45537 int64add(H[2], H[2], c);
45538 int64add(H[3], H[3], d);
45539 int64add(H[4], H[4], e);
45540 int64add(H[5], H[5], f);
45541 int64add(H[6], H[6], g);
45542 int64add(H[7], H[7], h);
45545 //represent the hash as an array of 32-bit dwords
45546 for (i = 0; i < 8; i += 1) {
45547 hash[2 * i] = H[i].h;
45548 hash[2 * i + 1] = H[i].l;
45553 //A constructor for 64-bit numbers
45555 function int64(h, l) {
45558 //this.toString = int64toString;
45561 //Copies src into dst, assuming both are 64-bit numbers
45563 function int64copy(dst, src) {
45568 //Right-rotates a 64-bit number by shift
45569 //Won't handle cases of shift>=32
45570 //The function revrrot() is for that
45572 function int64rrot(dst, x, shift) {
45573 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45574 dst.h = (x.h >>> shift) | (x.l << (32 - shift));
45577 //Reverses the dwords of the source and then rotates right by shift.
45578 //This is equivalent to rotation by 32+shift
45580 function int64revrrot(dst, x, shift) {
45581 dst.l = (x.h >>> shift) | (x.l << (32 - shift));
45582 dst.h = (x.l >>> shift) | (x.h << (32 - shift));
45585 //Bitwise-shifts right a 64-bit number by shift
45586 //Won't handle shift>=32, but it's never needed in SHA512
45588 function int64shr(dst, x, shift) {
45589 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45590 dst.h = (x.h >>> shift);
45593 //Adds two 64-bit numbers
45594 //Like the original implementation, does not rely on 32-bit operations
45596 function int64add(dst, x, y) {
45597 var w0 = (x.l & 0xffff) + (y.l & 0xffff);
45598 var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
45599 var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
45600 var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
45601 dst.l = (w0 & 0xffff) | (w1 << 16);
45602 dst.h = (w2 & 0xffff) | (w3 << 16);
45605 //Same, except with 4 addends. Works faster than adding them one by one.
45607 function int64add4(dst, a, b, c, d) {
45608 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
45609 var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
45610 var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
45611 var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
45612 dst.l = (w0 & 0xffff) | (w1 << 16);
45613 dst.h = (w2 & 0xffff) | (w3 << 16);
45616 //Same, except with 5 addends
45618 function int64add5(dst, a, b, c, d, e) {
45619 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
45620 w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
45621 w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
45622 w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
45623 dst.l = (w0 & 0xffff) | (w1 << 16);
45624 dst.h = (w2 & 0xffff) | (w3 << 16);
45628 * @class Hashes.RMD160
45630 * @param {Object} [config]
45632 * A JavaScript implementation of the RIPEMD-160 Algorithm
45633 * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
45634 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45635 * See http://pajhome.org.uk/crypt/md5 for details.
45636 * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
45638 RMD160: function(options) {
45640 * Private properties configuration variables. You may need to tweak these to be compatible with
45641 * the server-side, but the defaults work in most cases.
45642 * @see this.setUpperCase() method
45643 * @see this.setPad() method
45645 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
45646 /* hexadecimal output case format. false - lowercase; true - uppercase */
45647 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45648 /* base-64 pad character. Default '=' for strict RFC compliance */
45649 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45650 /* enable/disable utf8 encoding */
45652 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
45653 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
45654 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
45655 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
45656 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
45659 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
45660 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
45661 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
45662 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
45663 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
45666 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
45667 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
45668 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
45669 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
45670 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
45673 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
45674 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
45675 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
45676 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
45677 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
45680 /* privileged (public) methods */
45681 this.hex = function(s) {
45682 return rstr2hex(rstr(s, utf8));
45684 this.b64 = function(s) {
45685 return rstr2b64(rstr(s, utf8), b64pad);
45687 this.any = function(s, e) {
45688 return rstr2any(rstr(s, utf8), e);
45690 this.raw = function(s) {
45691 return rstr(s, utf8);
45693 this.hex_hmac = function(k, d) {
45694 return rstr2hex(rstr_hmac(k, d));
45696 this.b64_hmac = function(k, d) {
45697 return rstr2b64(rstr_hmac(k, d), b64pad);
45699 this.any_hmac = function(k, d, e) {
45700 return rstr2any(rstr_hmac(k, d), e);
45703 * Perform a simple self-test to see if the VM is working
45704 * @return {String} Hexadecimal hash sample
45707 this.vm_test = function() {
45708 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45711 * @description Enable/disable uppercase hexadecimal returned string
45713 * @return {Object} this
45716 this.setUpperCase = function(a) {
45717 if (typeof a === 'boolean') {
45723 * @description Defines a base64 pad string
45724 * @param {string} Pad
45725 * @return {Object} this
45728 this.setPad = function(a) {
45729 if (typeof a !== 'undefined') {
45735 * @description Defines a base64 pad string
45737 * @return {Object} this
45740 this.setUTF8 = function(a) {
45741 if (typeof a === 'boolean') {
45747 /* private methods */
45750 * Calculate the rmd160 of a raw string
45754 s = (utf8) ? utf8Encode(s) : s;
45755 return binl2rstr(binl(rstr2binl(s), s.length * 8));
45759 * Calculate the HMAC-rmd160 of a key and some data (raw strings)
45762 function rstr_hmac(key, data) {
45763 key = (utf8) ? utf8Encode(key) : key;
45764 data = (utf8) ? utf8Encode(data) : data;
45766 bkey = rstr2binl(key),
45770 if (bkey.length > 16) {
45771 bkey = binl(bkey, key.length * 8);
45774 for (i = 0; i < 16; i += 1) {
45775 ipad[i] = bkey[i] ^ 0x36363636;
45776 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45778 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
45779 return binl2rstr(binl(opad.concat(hash), 512 + 160));
45783 * Convert an array of little-endian words to a string
45786 function binl2rstr(input) {
45787 var i, output = '',
45788 l = input.length * 32;
45789 for (i = 0; i < l; i += 8) {
45790 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
45796 * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
45799 function binl(x, len) {
45806 A1, B1, C1, D1, E1,
45807 A2, B2, C2, D2, E2;
45809 /* append padding */
45810 x[len >> 5] |= 0x80 << (len % 32);
45811 x[(((len + 64) >>> 9) << 4) + 14] = len;
45814 for (i = 0; i < l; i += 16) {
45820 for (j = 0; j <= 79; j += 1) {
45821 T = safe_add(A1, rmd160_f(j, B1, C1, D1));
45822 T = safe_add(T, x[i + rmd160_r1[j]]);
45823 T = safe_add(T, rmd160_K1(j));
45824 T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
45827 D1 = bit_rol(C1, 10);
45830 T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
45831 T = safe_add(T, x[i + rmd160_r2[j]]);
45832 T = safe_add(T, rmd160_K2(j));
45833 T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
45836 D2 = bit_rol(C2, 10);
45841 T = safe_add(h1, safe_add(C1, D2));
45842 h1 = safe_add(h2, safe_add(D1, E2));
45843 h2 = safe_add(h3, safe_add(E1, A2));
45844 h3 = safe_add(h4, safe_add(A1, B2));
45845 h4 = safe_add(h0, safe_add(B1, C2));
45848 return [h0, h1, h2, h3, h4];
45851 // specific algorithm methods
45853 function rmd160_f(j, x, y, z) {
45854 return (0 <= j && j <= 15) ? (x ^ y ^ z) :
45855 (16 <= j && j <= 31) ? (x & y) | (~x & z) :
45856 (32 <= j && j <= 47) ? (x | ~y) ^ z :
45857 (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
45858 (64 <= j && j <= 79) ? x ^ (y | ~z) :
45859 'rmd160_f: j out of range';
45862 function rmd160_K1(j) {
45863 return (0 <= j && j <= 15) ? 0x00000000 :
45864 (16 <= j && j <= 31) ? 0x5a827999 :
45865 (32 <= j && j <= 47) ? 0x6ed9eba1 :
45866 (48 <= j && j <= 63) ? 0x8f1bbcdc :
45867 (64 <= j && j <= 79) ? 0xa953fd4e :
45868 'rmd160_K1: j out of range';
45871 function rmd160_K2(j) {
45872 return (0 <= j && j <= 15) ? 0x50a28be6 :
45873 (16 <= j && j <= 31) ? 0x5c4dd124 :
45874 (32 <= j && j <= 47) ? 0x6d703ef3 :
45875 (48 <= j && j <= 63) ? 0x7a6d76e9 :
45876 (64 <= j && j <= 79) ? 0x00000000 :
45877 'rmd160_K2: j out of range';
45883 (function(window, undefined) {
45884 var freeExports = false;
45886 freeExports = exports;
45887 if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
45888 window = commonjsGlobal;
45892 if (typeof undefined === 'function' && typeof undefined.amd === 'object' && undefined.amd) {
45893 // define as an anonymous module, so, through path mapping, it can be aliased
45894 undefined(function() {
45897 } else if (freeExports) {
45898 // in Node.js or RingoJS v0.8.0+
45899 if ('object' === 'object' && module && module.exports === freeExports) {
45900 module.exports = Hashes;
45902 // in Narwhal or RingoJS v0.7.0-
45904 freeExports.Hashes = Hashes;
45907 // in a browser or Rhino
45908 window.Hashes = Hashes;
45914 var immutable = extend$2;
45916 var hasOwnProperty = Object.prototype.hasOwnProperty;
45918 function extend$2() {
45921 for (var i = 0; i < arguments.length; i++) {
45922 var source = arguments[i];
45924 for (var key in source) {
45925 if (hasOwnProperty.call(source, key)) {
45926 target[key] = source[key];
45934 var hashes = hashes$1;
45935 var xtend$1 = immutable;
45936 var sha1 = new hashes.SHA1();
45940 ohauth$1.qsString = function(obj) {
45941 return Object.keys(obj).sort().map(function(key) {
45942 return ohauth$1.percentEncode(key) + '=' +
45943 ohauth$1.percentEncode(obj[key]);
45947 ohauth$1.stringQs = function(str) {
45948 return str.split('&').filter(function (pair) {
45949 return pair !== '';
45950 }).reduce(function(obj, pair){
45951 var parts = pair.split('=');
45952 obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
45953 '' : decodeURIComponent(parts[1]);
45958 ohauth$1.rawxhr = function(method, url, data, headers, callback) {
45959 var xhr = new XMLHttpRequest(),
45960 twoHundred = /^20\d$/;
45961 xhr.onreadystatechange = function() {
45962 if (4 === xhr.readyState && 0 !== xhr.status) {
45963 if (twoHundred.test(xhr.status)) callback(null, xhr);
45964 else return callback(xhr, null);
45967 xhr.onerror = function(e) { return callback(e, null); };
45968 xhr.open(method, url, true);
45969 for (var h in headers) xhr.setRequestHeader(h, headers[h]);
45974 ohauth$1.xhr = function(method, url, auth, data, options, callback) {
45975 var headers = (options && options.header) || {
45976 'Content-Type': 'application/x-www-form-urlencoded'
45978 headers.Authorization = 'OAuth ' + ohauth$1.authHeader(auth);
45979 return ohauth$1.rawxhr(method, url, data, headers, callback);
45982 ohauth$1.nonce = function() {
45983 for (var o = ''; o.length < 6;) {
45984 o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
45989 ohauth$1.authHeader = function(obj) {
45990 return Object.keys(obj).sort().map(function(key) {
45991 return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
45995 ohauth$1.timestamp = function() { return ~~((+new Date()) / 1000); };
45997 ohauth$1.percentEncode = function(s) {
45998 return encodeURIComponent(s)
45999 .replace(/\!/g, '%21').replace(/\'/g, '%27')
46000 .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
46003 ohauth$1.baseString = function(method, url, params) {
46004 if (params.oauth_signature) delete params.oauth_signature;
46007 ohauth$1.percentEncode(url),
46008 ohauth$1.percentEncode(ohauth$1.qsString(params))].join('&');
46011 ohauth$1.signature = function(oauth_secret, token_secret, baseString) {
46012 return sha1.b64_hmac(
46013 ohauth$1.percentEncode(oauth_secret) + '&' +
46014 ohauth$1.percentEncode(token_secret),
46019 * Takes an options object for configuration (consumer_key,
46020 * consumer_secret, version, signature_method, token, token_secret)
46021 * and returns a function that generates the Authorization header
46024 * The returned function takes these parameters:
46025 * - method: GET/POST/...
46026 * - uri: full URI with protocol, port, path and query string
46027 * - extra_params: any extra parameters (that are passed in the POST data),
46028 * can be an object or a from-urlencoded string.
46030 * Returned function returns full OAuth header with "OAuth" string in it.
46033 ohauth$1.headerGenerator = function(options) {
46034 options = options || {};
46035 var consumer_key = options.consumer_key || '',
46036 consumer_secret = options.consumer_secret || '',
46037 signature_method = options.signature_method || 'HMAC-SHA1',
46038 version = options.version || '1.0',
46039 token = options.token || '',
46040 token_secret = options.token_secret || '';
46042 return function(method, uri, extra_params) {
46043 method = method.toUpperCase();
46044 if (typeof extra_params === 'string' && extra_params.length > 0) {
46045 extra_params = ohauth$1.stringQs(extra_params);
46048 var uri_parts = uri.split('?', 2),
46049 base_uri = uri_parts[0];
46051 var query_params = uri_parts.length === 2 ?
46052 ohauth$1.stringQs(uri_parts[1]) : {};
46054 var oauth_params = {
46055 oauth_consumer_key: consumer_key,
46056 oauth_signature_method: signature_method,
46057 oauth_version: version,
46058 oauth_timestamp: ohauth$1.timestamp(),
46059 oauth_nonce: ohauth$1.nonce()
46062 if (token) oauth_params.oauth_token = token;
46064 var all_params = xtend$1({}, oauth_params, query_params, extra_params),
46065 base_str = ohauth$1.baseString(method, base_uri, all_params);
46067 oauth_params.oauth_signature = ohauth$1.signature(consumer_secret, token_secret, base_str);
46069 return 'OAuth ' + ohauth$1.authHeader(oauth_params);
46073 var index$13 = ohauth$1;
46075 var store$1 = createCommonjsModule(function (module, exports) {
46077 // Module export pattern from
46078 // https://github.com/umdjs/umd/blob/master/returnExports.js
46079 ;(function (root, factory) {
46080 if (typeof undefined === 'function' && undefined.amd) {
46081 // AMD. Register as an anonymous module.
46082 undefined([], factory);
46084 // Node. Does not work with strict CommonJS, but
46085 // only CommonJS-like environments that support module.exports,
46087 module.exports = factory();
46089 }(commonjsGlobal, function () {
46093 win = (typeof window != 'undefined' ? window : commonjsGlobal),
46094 doc = win.document,
46095 localStorageName = 'localStorage',
46096 scriptTag = 'script',
46099 store.disabled = false;
46100 store.version = '1.3.20';
46101 store.set = function(key, value) {};
46102 store.get = function(key, defaultVal) {};
46103 store.has = function(key) { return store.get(key) !== undefined };
46104 store.remove = function(key) {};
46105 store.clear = function() {};
46106 store.transact = function(key, defaultVal, transactionFn) {
46107 if (transactionFn == null) {
46108 transactionFn = defaultVal;
46111 if (defaultVal == null) {
46114 var val = store.get(key, defaultVal);
46115 transactionFn(val);
46116 store.set(key, val);
46118 store.getAll = function() {};
46119 store.forEach = function() {};
46121 store.serialize = function(value) {
46122 return JSON.stringify(value)
46124 store.deserialize = function(value) {
46125 if (typeof value != 'string') { return undefined }
46126 try { return JSON.parse(value) }
46127 catch(e) { return value || undefined }
46130 // Functions to encapsulate questionable FireFox 3.6.13 behavior
46131 // when about.config::dom.storage.enabled === false
46132 // See https://github.com/marcuswestin/store.js/issues#issue/13
46133 function isLocalStorageNameSupported() {
46134 try { return (localStorageName in win && win[localStorageName]) }
46135 catch(err) { return false }
46138 if (isLocalStorageNameSupported()) {
46139 storage = win[localStorageName];
46140 store.set = function(key, val) {
46141 if (val === undefined) { return store.remove(key) }
46142 storage.setItem(key, store.serialize(val));
46145 store.get = function(key, defaultVal) {
46146 var val = store.deserialize(storage.getItem(key));
46147 return (val === undefined ? defaultVal : val)
46149 store.remove = function(key) { storage.removeItem(key); };
46150 store.clear = function() { storage.clear(); };
46151 store.getAll = function() {
46153 store.forEach(function(key, val) {
46158 store.forEach = function(callback) {
46159 for (var i=0; i<storage.length; i++) {
46160 var key = storage.key(i);
46161 callback(key, store.get(key));
46164 } else if (doc && doc.documentElement.addBehavior) {
46167 // Since #userData storage applies only to specific paths, we need to
46168 // somehow link our data to a specific path. We choose /favicon.ico
46169 // as a pretty safe option, since all browsers already make a request to
46170 // this URL anyway and being a 404 will not hurt us here. We wrap an
46171 // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
46172 // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
46173 // since the iframe access rules appear to allow direct access and
46174 // manipulation of the document element, even for a 404 page. This
46175 // document can be used instead of the current document (which would
46176 // have been limited to the current path) to perform #userData storage.
46178 storageContainer = new ActiveXObject('htmlfile');
46179 storageContainer.open();
46180 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
46181 storageContainer.close();
46182 storageOwner = storageContainer.w.frames[0].document;
46183 storage = storageOwner.createElement('div');
46185 // somehow ActiveXObject instantiation failed (perhaps some special
46186 // security settings or otherwse), fall back to per-path storage
46187 storage = doc.createElement('div');
46188 storageOwner = doc.body;
46190 var withIEStorage = function(storeFunction) {
46191 return function() {
46192 var args = Array.prototype.slice.call(arguments, 0);
46193 args.unshift(storage);
46194 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
46195 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
46196 storageOwner.appendChild(storage);
46197 storage.addBehavior('#default#userData');
46198 storage.load(localStorageName);
46199 var result = storeFunction.apply(store, args);
46200 storageOwner.removeChild(storage);
46205 // In IE7, keys cannot start with a digit or contain certain chars.
46206 // See https://github.com/marcuswestin/store.js/issues/40
46207 // See https://github.com/marcuswestin/store.js/issues/83
46208 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
46209 var ieKeyFix = function(key) {
46210 return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')
46212 store.set = withIEStorage(function(storage, key, val) {
46213 key = ieKeyFix(key);
46214 if (val === undefined) { return store.remove(key) }
46215 storage.setAttribute(key, store.serialize(val));
46216 storage.save(localStorageName);
46219 store.get = withIEStorage(function(storage, key, defaultVal) {
46220 key = ieKeyFix(key);
46221 var val = store.deserialize(storage.getAttribute(key));
46222 return (val === undefined ? defaultVal : val)
46224 store.remove = withIEStorage(function(storage, key) {
46225 key = ieKeyFix(key);
46226 storage.removeAttribute(key);
46227 storage.save(localStorageName);
46229 store.clear = withIEStorage(function(storage) {
46230 var attributes = storage.XMLDocument.documentElement.attributes;
46231 storage.load(localStorageName);
46232 for (var i=attributes.length-1; i>=0; i--) {
46233 storage.removeAttribute(attributes[i].name);
46235 storage.save(localStorageName);
46237 store.getAll = function(storage) {
46239 store.forEach(function(key, val) {
46244 store.forEach = withIEStorage(function(storage, callback) {
46245 var attributes = storage.XMLDocument.documentElement.attributes;
46246 for (var i=0, attr; attr=attributes[i]; ++i) {
46247 callback(attr.name, store.deserialize(storage.getAttribute(attr.name)));
46253 var testKey = '__storejs__';
46254 store.set(testKey, testKey);
46255 if (store.get(testKey) != testKey) { store.disabled = true; }
46256 store.remove(testKey);
46258 store.disabled = true;
46260 store.enabled = !store.disabled;
46266 var ohauth = index$13;
46267 var xtend = immutable;
46268 var store = store$1;
46272 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
46273 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
46274 // does not support custom headers, which this uses everywhere.
46275 var index$12 = function(o) {
46279 // authenticated users will also have a request token secret, but it's
46280 // not used in transactions with the server
46281 oauth.authenticated = function() {
46282 return !!(token('oauth_token') && token('oauth_token_secret'));
46285 oauth.logout = function() {
46286 token('oauth_token', '');
46287 token('oauth_token_secret', '');
46288 token('oauth_request_token_secret', '');
46292 // TODO: detect lack of click event
46293 oauth.authenticate = function(callback) {
46294 if (oauth.authenticated()) return callback();
46298 // ## Getting a request token
46299 var params = timenonce(getAuth(o)),
46300 url = o.url + '/oauth/request_token';
46302 params.oauth_signature = ohauth.signature(
46303 o.oauth_secret, '',
46304 ohauth.baseString('POST', url, params));
46306 if (!o.singlepage) {
46307 // Create a 600x550 popup window in the center of the screen
46308 var w = 600, h = 550,
46310 ['width', w], ['height', h],
46311 ['left', screen.width / 2 - w / 2],
46312 ['top', screen.height / 2 - h / 2]].map(function(x) {
46313 return x.join('=');
46315 popup = window.open('about:blank', 'oauth_window', settings);
46318 // Request a request token. When this is complete, the popup
46319 // window is redirected to OSM's authorization page.
46320 ohauth.xhr('POST', url, params, null, {}, reqTokenDone);
46323 function reqTokenDone(err, xhr) {
46325 if (err) return callback(err);
46326 var resp = ohauth.stringQs(xhr.response);
46327 token('oauth_request_token_secret', resp.oauth_token_secret);
46328 var authorize_url = o.url + '/oauth/authorize?' + ohauth.qsString({
46329 oauth_token: resp.oauth_token,
46330 oauth_callback: location.href.replace('index.html', '')
46331 .replace(/#.*/, '').replace(location.search, '') + o.landing
46334 if (o.singlepage) {
46335 location.href = authorize_url;
46337 popup.location = authorize_url;
46341 // Called by a function in a landing page, in the popup window. The
46342 // window closes itself.
46343 window.authComplete = function(token) {
46344 var oauth_token = ohauth.stringQs(token.split('?')[1]);
46345 get_access_token(oauth_token.oauth_token);
46346 delete window.authComplete;
46349 // ## Getting an request token
46351 // At this point we have an `oauth_token`, brought in from a function
46352 // call on a landing page popup.
46353 function get_access_token(oauth_token) {
46354 var url = o.url + '/oauth/access_token',
46355 params = timenonce(getAuth(o)),
46356 request_token_secret = token('oauth_request_token_secret');
46357 params.oauth_token = oauth_token;
46358 params.oauth_signature = ohauth.signature(
46360 request_token_secret,
46361 ohauth.baseString('POST', url, params));
46363 // ## Getting an access token
46365 // The final token required for authentication. At this point
46366 // we have a `request token secret`
46367 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
46371 function accessTokenDone(err, xhr) {
46373 if (err) return callback(err);
46374 var access_token = ohauth.stringQs(xhr.response);
46375 token('oauth_token', access_token.oauth_token);
46376 token('oauth_token_secret', access_token.oauth_token_secret);
46377 callback(null, oauth);
46381 oauth.bootstrapToken = function(oauth_token, callback) {
46382 // ## Getting an request token
46383 // At this point we have an `oauth_token`, brought in from a function
46384 // call on a landing page popup.
46385 function get_access_token(oauth_token) {
46386 var url = o.url + '/oauth/access_token',
46387 params = timenonce(getAuth(o)),
46388 request_token_secret = token('oauth_request_token_secret');
46389 params.oauth_token = oauth_token;
46390 params.oauth_signature = ohauth.signature(
46392 request_token_secret,
46393 ohauth.baseString('POST', url, params));
46395 // ## Getting an access token
46396 // The final token required for authentication. At this point
46397 // we have a `request token secret`
46398 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
46402 function accessTokenDone(err, xhr) {
46404 if (err) return callback(err);
46405 var access_token = ohauth.stringQs(xhr.response);
46406 token('oauth_token', access_token.oauth_token);
46407 token('oauth_token_secret', access_token.oauth_token_secret);
46408 callback(null, oauth);
46411 get_access_token(oauth_token);
46416 // A single XMLHttpRequest wrapper that does authenticated calls if the
46417 // user has logged in.
46418 oauth.xhr = function(options, callback) {
46419 if (!oauth.authenticated()) {
46421 return oauth.authenticate(run);
46423 callback('not authenticated', null);
46431 var params = timenonce(getAuth(o)),
46432 oauth_token_secret = token('oauth_token_secret'),
46433 url = (options.prefix !== false) ? o.url + options.path : options.path,
46434 url_parts = url.replace(/#.*$/, '').split('?', 2),
46435 base_url = url_parts[0],
46436 query = (url_parts.length === 2) ? url_parts[1] : '';
46438 // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
46439 if ((!options.options || !options.options.header ||
46440 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
46442 params = xtend(params, ohauth.stringQs(options.content));
46445 params.oauth_token = token('oauth_token');
46446 params.oauth_signature = ohauth.signature(
46448 oauth_token_secret,
46449 ohauth.baseString(options.method, base_url, xtend(params, ohauth.stringQs(query)))
46452 return ohauth.xhr(options.method, url, params, options.content, options.options, done);
46455 function done(err, xhr) {
46456 if (err) return callback(err);
46457 else if (xhr.responseXML) return callback(err, xhr.responseXML);
46458 else return callback(err, xhr.response);
46462 // pre-authorize this object, if we can just get a token and token_secret
46464 oauth.preauth = function(c) {
46466 if (c.oauth_token) token('oauth_token', c.oauth_token);
46467 if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
46471 oauth.options = function(_) {
46472 if (!arguments.length) return o;
46475 o.url = o.url || 'http://www.openstreetmap.org';
46476 o.landing = o.landing || 'land.html';
46477 o.singlepage = o.singlepage || false;
46479 // Optional loading and loading-done functions for nice UI feedback.
46480 // by default, no-ops
46481 o.loading = o.loading || function() {};
46482 o.done = o.done || function() {};
46484 return oauth.preauth(o);
46487 // 'stamp' an authentication object from `getAuth()`
46488 // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
46490 function timenonce(o) {
46491 o.oauth_timestamp = ohauth.timestamp();
46492 o.oauth_nonce = ohauth.nonce();
46496 // get/set tokens. These are prefixed with the base URL so that `osm-auth`
46497 // can be used with multiple APIs and the keys in `localStorage`
46501 if (store.enabled) {
46502 token = function (x, y) {
46503 if (arguments.length === 1) return store.get(o.url + x);
46504 else if (arguments.length === 2) return store.set(o.url + x, y);
46508 token = function (x, y) {
46509 if (arguments.length === 1) return storage[o.url + x];
46510 else if (arguments.length === 2) return storage[o.url + x] = y;
46514 // Get an authentication object. If you just add and remove properties
46515 // from a single object, you'll need to use `delete` to make sure that
46516 // it doesn't contain undesired properties for authentication
46517 function getAuth(o) {
46519 oauth_consumer_key: o.oauth_consumer_key,
46520 oauth_signature_method: 'HMAC-SHA1'
46524 // potentially pre-authorize
46530 var JXON = new (function () {
46532 sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
46533 aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
46535 function parseText (sValue) {
46536 if (rIsNull.test(sValue)) { return null; }
46537 if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
46538 if (isFinite(sValue)) { return parseFloat(sValue); }
46539 if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
46543 function EmptyTree () { }
46544 EmptyTree.prototype.toString = function () { return 'null'; };
46545 EmptyTree.prototype.valueOf = function () { return null; };
46547 function objectify (vValue) {
46548 return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
46551 function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
46553 nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
46554 bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
46557 sProp, vContent, nLength = 0, sCollectedTxt = '',
46558 vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
46561 for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
46562 oNode = oParentNode.childNodes.item(nItem);
46563 if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
46564 else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
46565 else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
46569 var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
46571 if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
46573 for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
46574 sProp = aCache[nElId].nodeName.toLowerCase();
46575 vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
46576 if (vResult.hasOwnProperty(sProp)) {
46577 if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
46578 vResult[sProp].push(vContent);
46580 vResult[sProp] = vContent;
46587 nAttrLen = oParentNode.attributes.length,
46588 sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
46590 for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
46591 oAttrib = oParentNode.attributes.item(nAttrib);
46592 oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
46596 if (bFreeze) { Object.freeze(oAttrParent); }
46597 vResult[sAttributesProp] = oAttrParent;
46598 nLength -= nAttrLen - 1;
46602 if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
46603 vResult[sValueProp] = vBuiltVal;
46604 } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
46605 vResult = vBuiltVal;
46608 if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
46610 aCache.length = nLevelStart;
46615 function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
46616 var vValue, oChild;
46618 if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
46619 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
46620 } else if (oParentObj.constructor === Date) {
46621 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
46624 for (var sName in oParentObj) {
46625 vValue = oParentObj[sName];
46626 if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
46627 if (sName === sValueProp) {
46628 if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
46629 } else if (sName === sAttributesProp) { /* verbosity level is 3 */
46630 for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
46631 } else if (sName.charAt(0) === sAttrPref) {
46632 oParentEl.setAttribute(sName.slice(1), vValue);
46633 } else if (vValue.constructor === Array) {
46634 for (var nItem = 0; nItem < vValue.length; nItem++) {
46635 oChild = oXMLDoc.createElement(sName);
46636 loadObjTree(oXMLDoc, oChild, vValue[nItem]);
46637 oParentEl.appendChild(oChild);
46640 oChild = oXMLDoc.createElement(sName);
46641 if (vValue instanceof Object) {
46642 loadObjTree(oXMLDoc, oChild, vValue);
46643 } else if (vValue !== null && vValue !== true) {
46644 oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
46646 oParentEl.appendChild(oChild);
46651 this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
46652 var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
46653 return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);
46656 this.unbuild = function (oObjTree) {
46657 var oNewDoc = document.implementation.createDocument('', '', null);
46658 loadObjTree(oNewDoc, oNewDoc, oObjTree);
46662 this.stringify = function (oObjTree) {
46663 return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
46667 // var myObject = JXON.build(doc);
46668 // we got our javascript object! try: alert(JSON.stringify(myObject));
46670 // var newDoc = JXON.unbuild(myObject);
46671 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
46673 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
46674 var useHttps = window.location.protocol === 'https:';
46675 var protocol = useHttps ? 'https:' : 'http:';
46676 var urlroot = protocol + '//www.openstreetmap.org';
46677 var blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
46679 var loadedTiles = {};
46680 var tileZoom$1 = 16;
46681 var oauth = index$12({
46683 oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
46684 oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
46685 loading: authLoading,
46688 var rateLimitError;
46689 var userChangesets;
46694 function authLoading() {
46695 dispatch$3.call('authLoading');
46699 function authDone() {
46700 dispatch$3.call('authDone');
46704 function abortRequest$1(i) {
46711 function getLoc(attrs) {
46712 var lon = attrs.lon && attrs.lon.value,
46713 lat = attrs.lat && attrs.lat.value;
46714 return [parseFloat(lon), parseFloat(lat)];
46718 function getNodes(obj) {
46719 var elems = obj.getElementsByTagName('nd'),
46720 nodes = new Array(elems.length);
46721 for (var i = 0, l = elems.length; i < l; i++) {
46722 nodes[i] = 'n' + elems[i].attributes.ref.value;
46728 function getTags(obj) {
46729 var elems = obj.getElementsByTagName('tag'),
46731 for (var i = 0, l = elems.length; i < l; i++) {
46732 var attrs = elems[i].attributes;
46733 tags[attrs.k.value] = attrs.v.value;
46740 function getMembers(obj) {
46741 var elems = obj.getElementsByTagName('member'),
46742 members = new Array(elems.length);
46743 for (var i = 0, l = elems.length; i < l; i++) {
46744 var attrs = elems[i].attributes;
46746 id: attrs.type.value[0] + attrs.ref.value,
46747 type: attrs.type.value,
46748 role: attrs.role.value
46755 function getVisible(attrs) {
46756 return (!attrs.visible || attrs.visible.value !== 'false');
46761 node: function nodeData(obj) {
46762 var attrs = obj.attributes;
46763 return new osmNode({
46764 id: osmEntity$$1.id.fromOSM('node', attrs.id.value),
46765 loc: getLoc(attrs),
46766 version: attrs.version.value,
46767 user: attrs.user && attrs.user.value,
46768 tags: getTags(obj),
46769 visible: getVisible(attrs)
46773 way: function wayData(obj) {
46774 var attrs = obj.attributes;
46775 return new osmWay({
46776 id: osmEntity$$1.id.fromOSM('way', attrs.id.value),
46777 version: attrs.version.value,
46778 user: attrs.user && attrs.user.value,
46779 tags: getTags(obj),
46780 nodes: getNodes(obj),
46781 visible: getVisible(attrs)
46785 relation: function relationData(obj) {
46786 var attrs = obj.attributes;
46787 return new osmRelation({
46788 id: osmEntity$$1.id.fromOSM('relation', attrs.id.value),
46789 version: attrs.version.value,
46790 user: attrs.user && attrs.user.value,
46791 tags: getTags(obj),
46792 members: getMembers(obj),
46793 visible: getVisible(attrs)
46799 function parse(xml$$1) {
46800 if (!xml$$1 || !xml$$1.childNodes) return;
46802 var root = xml$$1.childNodes[0],
46803 children = root.childNodes,
46806 for (var i = 0, l = children.length; i < l; i++) {
46807 var child = children[i],
46808 parser = parsers[child.nodeName];
46810 entities.push(parser(child));
46821 utilRebind(this, dispatch$3, 'on');
46825 reset: function() {
46826 userChangesets = undefined;
46827 userDetails = undefined;
46828 rateLimitError = undefined;
46829 lodash.forEach(inflight, abortRequest$1);
46836 changesetURL: function(changesetId) {
46837 return urlroot + '/changeset/' + changesetId;
46841 changesetsURL: function(center, zoom$$1) {
46842 var precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2));
46843 return urlroot + '/history#map=' +
46844 Math.floor(zoom$$1) + '/' +
46845 center[1].toFixed(precision) + '/' +
46846 center[0].toFixed(precision);
46850 entityURL: function(entity) {
46851 return urlroot + '/' + entity.type + '/' + entity.osmId();
46855 userURL: function(username) {
46856 return urlroot + '/user/' + username;
46860 loadFromAPI: function(path$$1, callback) {
46863 function done(err, xml$$1) {
46864 var isAuthenticated = that.authenticated();
46866 // 400 Bad Request, 401 Unauthorized, 403 Forbidden
46867 // Logout and retry the request..
46868 if (isAuthenticated && err &&
46869 (err.status === 400 || err.status === 401 || err.status === 403)) {
46871 that.loadFromAPI(path$$1, callback);
46873 // else, no retry..
46875 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
46876 // Set the rateLimitError flag and trigger a warning..
46877 if (!isAuthenticated && !rateLimitError && err &&
46878 (err.status === 509 || err.status === 429)) {
46879 rateLimitError = err;
46880 dispatch$3.call('change');
46884 callback(err, parse(xml$$1));
46889 if (this.authenticated()) {
46890 return oauth.xhr({ method: 'GET', path: path$$1 }, done);
46892 var url = urlroot + path$$1;
46893 return xml(url).get(done);
46898 loadEntity: function(id, callback) {
46899 var type = osmEntity$$1.id.type(id),
46900 osmID = osmEntity$$1.id.toOSM(id);
46903 '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
46904 function(err, entities) {
46905 if (callback) callback(err, { data: entities });
46911 loadEntityVersion: function(id, version$$1, callback) {
46912 var type = osmEntity$$1.id.type(id),
46913 osmID = osmEntity$$1.id.toOSM(id);
46916 '/api/0.6/' + type + '/' + osmID + '/' + version$$1,
46917 function(err, entities) {
46918 if (callback) callback(err, { data: entities });
46924 loadMultiple: function(ids, callback) {
46926 lodash.each(lodash.groupBy(lodash.uniq(ids), osmEntity$$1.id.type), function(v, k) {
46927 var type = k + 's',
46928 osmIDs = lodash.map(v, osmEntity$$1.id.toOSM);
46930 lodash.each(lodash.chunk(osmIDs, 150), function(arr) {
46932 '/api/0.6/' + type + '?' + type + '=' + arr.join(),
46933 function(err, entities) {
46934 if (callback) callback(err, { data: entities });
46942 authenticated: function() {
46943 return oauth.authenticated();
46947 // Generate Changeset XML. Returns a string.
46948 changesetJXON: function(tags) {
46952 tag: lodash.map(tags, function(value, key) {
46953 return { '@k': key, '@v': value };
46963 // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
46964 // XML. Returns a string.
46965 osmChangeJXON: function(changeset_id, changes) {
46966 function nest$$1(x, order) {
46968 for (var i = 0; i < x.length; i++) {
46969 var tagName = Object.keys(x[i])[0];
46970 if (!groups[tagName]) groups[tagName] = [];
46971 groups[tagName].push(x[i][tagName]);
46974 order.forEach(function(o) {
46975 if (groups[o]) ordered[o] = groups[o];
46980 function rep(entity) {
46981 return entity.asJXON(changeset_id);
46987 '@generator': 'iD',
46988 'create': nest$$1(changes.created.map(rep), ['node', 'way', 'relation']),
46989 'modify': nest$$1(changes.modified.map(rep), ['node', 'way', 'relation']),
46990 'delete': lodash.extend(nest$$1(changes.deleted.map(rep), ['relation', 'way', 'node']), {'@if-unused': true})
46996 changesetTags: function(version$$1, comment, imageryUsed) {
46997 var detected = utilDetect(),
46999 created_by: ('iD ' + version$$1).substr(0, 255),
47000 imagery_used: imageryUsed.join(';').substr(0, 255),
47001 host: detected.host.substr(0, 255),
47002 locale: detected.locale.substr(0, 255)
47006 tags.comment = comment.substr(0, 255);
47013 putChangeset: function(changes, version$$1, comment, imageryUsed, callback) {
47017 path: '/api/0.6/changeset/create',
47018 options: { header: { 'Content-Type': 'text/xml' } },
47019 content: JXON.stringify(that.changesetJXON(that.changesetTags(version$$1, comment, imageryUsed)))
47020 }, function(err, changeset_id) {
47021 if (err) return callback(err);
47024 path: '/api/0.6/changeset/' + changeset_id + '/upload',
47025 options: { header: { 'Content-Type': 'text/xml' } },
47026 content: JXON.stringify(that.osmChangeJXON(changeset_id, changes))
47028 if (err) return callback(err);
47029 // POST was successful, safe to call the callback.
47030 // Still attempt to close changeset, but ignore response because #2667
47031 // Add delay to allow for postgres replication #1646 #2678
47032 window.setTimeout(function() { callback(null, changeset_id); }, 2500);
47035 path: '/api/0.6/changeset/' + changeset_id + '/close',
47036 options: { header: { 'Content-Type': 'text/xml' } }
47037 }, function() { return true; });
47043 userDetails: function(callback) {
47045 callback(undefined, userDetails);
47049 function done(err, user_details) {
47050 if (err) return callback(err);
47052 var u = user_details.getElementsByTagName('user')[0],
47053 img = u.getElementsByTagName('img'),
47056 if (img && img[0] && img[0].getAttribute('href')) {
47057 image_url = img[0].getAttribute('href');
47061 display_name: u.attributes.display_name.value,
47062 image_url: image_url,
47063 id: u.attributes.id.value
47066 callback(undefined, userDetails);
47069 oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
47073 userChangesets: function(callback) {
47074 if (userChangesets) {
47075 callback(undefined, userChangesets);
47079 this.userDetails(function(err, user) {
47085 function done(err, changesets) {
47089 userChangesets = Array.prototype.map.call(
47090 changesets.getElementsByTagName('changeset'),
47091 function (changeset) {
47092 return { tags: getTags(changeset) };
47095 callback(undefined, userChangesets);
47099 oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
47104 status: function(callback) {
47105 function done(xml$$1) {
47106 // update blacklists
47107 var elements = xml$$1.getElementsByTagName('blacklist'),
47109 for (var i = 0; i < elements.length; i++) {
47110 var regex = elements[i].getAttribute('regex'); // needs unencode?
47112 regexes.push(regex);
47115 if (regexes.length) {
47116 blacklists = regexes;
47120 if (rateLimitError) {
47121 callback(rateLimitError, 'rateLimited');
47123 var apiStatus = xml$$1.getElementsByTagName('status'),
47124 val = apiStatus[0].getAttribute('api');
47126 callback(undefined, val);
47130 xml(urlroot + '/api/capabilities').get()
47132 .on('error', callback);
47136 imageryBlacklists: function() {
47141 tileZoom: function(_) {
47142 if (!arguments.length) return tileZoom$1;
47148 loadTiles: function(projection, dimensions, callback) {
47152 s = projection.scale() * 2 * Math.PI,
47153 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
47154 ts = 256 * Math.pow(2, z - tileZoom$1),
47156 s / 2 - projection.translate()[0],
47157 s / 2 - projection.translate()[1]
47160 var tiles = d3geoTile()
47161 .scaleExtent([tileZoom$1, tileZoom$1])
47164 .translate(projection.translate())()
47165 .map(function(tile) {
47166 var x = tile[0] * ts - origin[0],
47167 y = tile[1] * ts - origin[1];
47170 id: tile.toString(),
47171 extent: geoExtent$$1(
47172 projection.invert([x, y + ts]),
47173 projection.invert([x + ts, y]))
47177 lodash.filter(inflight, function(v, i) {
47178 var wanted = lodash.find(tiles, function(tile) {
47179 return i === tile.id;
47181 if (!wanted) delete inflight[i];
47183 }).map(abortRequest$1);
47185 tiles.forEach(function(tile) {
47188 if (loadedTiles[id] || inflight[id]) return;
47190 if (lodash.isEmpty(inflight)) {
47191 dispatch$3.call('loading');
47194 inflight[id] = that.loadFromAPI(
47195 '/api/0.6/map?bbox=' + tile.extent.toParam(),
47196 function(err, parsed) {
47197 delete inflight[id];
47199 loadedTiles[id] = true;
47203 callback(err, lodash.extend({ data: parsed }, tile));
47206 if (lodash.isEmpty(inflight)) {
47207 dispatch$3.call('loaded');
47215 switch: function(options) {
47216 urlroot = options.urlroot;
47218 oauth.options(lodash.extend({
47220 loading: authLoading,
47224 dispatch$3.call('change');
47226 this.userChangesets(function() {}); // eagerly load user details/changesets
47231 toggle: function(_) {
47237 loadedTiles: function(_) {
47238 if (!arguments.length) return loadedTiles;
47244 logout: function() {
47245 userChangesets = undefined;
47246 userDetails = undefined;
47248 dispatch$3.call('change');
47253 authenticate: function(callback) {
47255 userChangesets = undefined;
47256 userDetails = undefined;
47258 function done(err, res) {
47259 rateLimitError = undefined;
47260 dispatch$3.call('change');
47261 if (callback) callback(err, res);
47262 that.userChangesets(function() {}); // eagerly load user details/changesets
47265 return oauth.authenticate(done);
47269 var endpoint = 'https://taginfo.openstreetmap.org/api/4/';
47270 var taginfoCache = {};
47272 point: 'count_nodes',
47273 vertex: 'count_nodes',
47274 area: 'count_ways',
47277 var tag_sort_members = {
47278 point: 'count_node_members',
47279 vertex: 'count_node_members',
47280 area: 'count_way_members',
47281 line: 'count_way_members',
47282 relation: 'count_relation_members'
47284 var tag_filters = {
47290 var tag_members_fractions = {
47291 point: 'count_node_members_fraction',
47292 vertex: 'count_node_members_fraction',
47293 area: 'count_way_members_fraction',
47294 line: 'count_way_members_fraction',
47295 relation: 'count_relation_members_fraction'
47299 function sets(parameters, n, o) {
47300 if (parameters.geometry && o[parameters.geometry]) {
47301 parameters[n] = o[parameters.geometry];
47307 function setFilter(parameters) {
47308 return sets(parameters, 'filter', tag_filters);
47312 function setSort(parameters) {
47313 return sets(parameters, 'sortname', tag_sorts);
47317 function setSortMembers(parameters) {
47318 return sets(parameters, 'sortname', tag_sort_members);
47322 function clean(parameters) {
47323 return lodash.omit(parameters, 'geometry', 'debounce');
47327 function filterKeys(type) {
47328 var count_type = type ? 'count_' + type : 'count_all';
47329 return function(d) {
47330 return parseFloat(d[count_type]) > 2500 || d.in_wiki;
47335 function filterMultikeys(prefix) {
47336 return function(d) {
47337 // d.key begins with prefix, and d.key contains no additional ':'s
47338 var re = new RegExp('^' + prefix + '(.*)$');
47339 var matches = d.key.match(re) || [];
47340 return (matches.length === 2 && matches[1].indexOf(':') === -1);
47345 function filterValues(allowUpperCase) {
47346 return function(d) {
47347 if (d.value.match(/[;,]/) !== null) return false; // exclude some punctuation
47348 if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false; // exclude uppercase letters
47349 return parseFloat(d.fraction) > 0.0 || d.in_wiki;
47354 function filterRoles(geometry) {
47355 return function(d) {
47356 if (d.role === '') return false; // exclude empty role
47357 if (d.role.match(/[A-Z*;,]/) !== null) return false; // exclude uppercase letters and some punctuation
47358 return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
47363 function valKey(d) {
47371 function valKeyDescription(d) {
47374 title: d.description || d.value
47379 function roleKey(d) {
47387 // sort keys with ':' lower than keys without ':'
47388 function sortKeys(a, b) {
47389 return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
47390 : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
47395 var debounced = lodash.debounce(json, 100, true);
47398 function request$1(url, debounce, callback) {
47399 if (taginfoCache[url]) {
47400 callback(null, taginfoCache[url]);
47401 } else if (debounce) {
47402 debounced(url, done);
47407 function done(err, data) {
47409 taginfoCache[url] = data;
47411 callback(err, data);
47416 var serviceTaginfo = {
47418 init: function() { taginfoCache = {}; },
47419 reset: function() { taginfoCache = {}; },
47422 keys: function(parameters, callback) {
47423 var debounce = parameters.debounce;
47424 parameters = clean(setSort(parameters));
47425 request$1(endpoint + 'keys/all?' +
47426 utilQsString(lodash.extend({
47428 sortname: 'count_all',
47431 }, parameters)), debounce, function(err, d) {
47435 var f = filterKeys(parameters.filter);
47436 callback(null, d.data.filter(f).sort(sortKeys).map(valKey));
47443 multikeys: function(parameters, callback) {
47444 var debounce = parameters.debounce;
47445 parameters = clean(setSort(parameters));
47446 var prefix = parameters.query;
47447 request$1(endpoint + 'keys/all?' +
47448 utilQsString(lodash.extend({
47450 sortname: 'count_all',
47453 }, parameters)), debounce, function(err, d) {
47457 var f = filterMultikeys(prefix);
47458 callback(null, d.data.filter(f).map(valKey));
47465 values: function(parameters, callback) {
47466 var debounce = parameters.debounce;
47467 parameters = clean(setSort(setFilter(parameters)));
47468 request$1(endpoint + 'key/values?' +
47469 utilQsString(lodash.extend({
47471 sortname: 'count_all',
47474 }, parameters)), debounce, function(err, d) {
47478 // In most cases we prefer taginfo value results with lowercase letters.
47479 // A few OSM keys expect values to contain uppercase values (see #3377).
47480 // This is not an exhaustive list (e.g. `name` also has uppercase values)
47481 // but these are the fields where taginfo value lookup is most useful.
47482 var re = /network|taxon|genus|species/;
47483 var allowUpperCase = (parameters.key.match(re) !== null);
47484 var f = filterValues(allowUpperCase);
47485 callback(null, d.data.filter(f).map(valKeyDescription));
47492 roles: function(parameters, callback) {
47493 var debounce = parameters.debounce;
47494 var geometry = parameters.geometry;
47495 parameters = clean(setSortMembers(parameters));
47496 request$1(endpoint + 'relation/roles?' +
47497 utilQsString(lodash.extend({
47499 sortname: 'count_all_members',
47502 }, parameters)), debounce, function(err, d) {
47506 var f = filterRoles(geometry);
47507 callback(null, d.data.filter(f).map(roleKey));
47514 docs: function(parameters, callback) {
47515 var debounce = parameters.debounce;
47516 parameters = clean(setSort(parameters));
47518 var path$$1 = 'key/wiki_pages?';
47519 if (parameters.value) path$$1 = 'tag/wiki_pages?';
47520 else if (parameters.rtype) path$$1 = 'relation/wiki_pages?';
47522 request$1(endpoint + path$$1 + utilQsString(parameters), debounce, function(err, d) {
47526 callback(null, d.data);
47532 endpoint: function(_) {
47533 if (!arguments.length) return endpoint;
47540 var jsonpCache = {};
47541 window.jsonpCache = jsonpCache;
47543 function jsonpRequest(url, callback) {
47545 if (window.JSONP_FIX) {
47546 if (window.JSONP_DELAY === 0) {
47547 callback(window.JSONP_FIX);
47549 setTimeout(function() {
47550 callback(window.JSONP_FIX);
47551 }, window.JSONP_DELAY || 0);
47557 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
47559 while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
47563 function create(url) {
47564 var e = url.match(/callback=(\w+)/),
47565 c = e ? e[1] : rand();
47566 jsonpCache[c] = function(data) {
47568 delete jsonpCache[c];
47571 return 'jsonpCache.' + c;
47574 var cb = create(url),
47575 script = select('head')
47577 .attr('type', 'text/javascript')
47578 .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
47581 var endpoint$1 = 'https://www.wikidata.org/w/api.php?';
47583 var serviceWikidata = {
47585 init: function() {},
47586 reset: function() {},
47589 // Given a Wikipedia language and article title, return an array of
47590 // corresponding Wikidata entities.
47591 itemsByTitle: function(lang, title, callback) {
47597 lang = lang || 'en';
47598 jsonpRequest(endpoint$1 + utilQsString({
47599 action: 'wbgetentities',
47601 sites: lang.replace(/-/g, '_') + 'wiki',
47603 languages: 'en', // shrink response by filtering to one language
47604 callback: '{callback}'
47605 }), function(data) {
47606 if (!data || data.error) {
47609 callback(title, data.entities || {});
47616 var endpoint$2 = 'https://en.wikipedia.org/w/api.php?';
47618 var serviceWikipedia = {
47620 init: function() {},
47621 reset: function() {},
47624 search: function(lang, query, callback) {
47630 lang = lang || 'en';
47631 jsonpRequest(endpoint$2.replace('en', lang) +
47636 srinfo: 'suggestion',
47638 callback: '{callback}',
47640 }), function(data) {
47641 if (!data || !data.query || !data.query.search || data.error) {
47644 var results = data.query.search.map(function(d) { return d.title; });
47645 callback(query, results);
47652 suggestions: function(lang, query, callback) {
47658 lang = lang || 'en';
47659 jsonpRequest(endpoint$2.replace('en', lang) +
47661 action: 'opensearch',
47665 callback: '{callback}',
47667 }), function(data) {
47668 if (!data || data.error) {
47671 callback(data[0], data[1] || []);
47678 translations: function(lang, title, callback) {
47684 jsonpRequest(endpoint$2.replace('en', lang) +
47689 callback: '{callback}',
47692 }), function(data) {
47693 if (!data || !data.query || !data.query.pages || data.error) {
47696 var list = data.query.pages[Object.keys(data.query.pages)[0]],
47698 if (list && list.langlinks) {
47699 list.langlinks.forEach(function(d) {
47700 translations[d.lang] = d['*'];
47703 callback(translations);
47712 mapillary: serviceMapillary,
47713 geocoder: serviceNominatim,
47715 taginfo: serviceTaginfo,
47716 wikidata: serviceWikidata,
47717 wikipedia: serviceWikipedia
47720 function svgMapillaryImages(projection, context, dispatch$$1) {
47721 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47723 minViewfieldZoom = 17,
47724 layer = select(null),
47729 if (svgMapillaryImages.initialized) return; // run once
47730 svgMapillaryImages.enabled = false;
47731 svgMapillaryImages.initialized = true;
47735 function getMapillary() {
47736 if (services.mapillary && !_mapillary) {
47737 _mapillary = services.mapillary;
47738 _mapillary.event.on('loadedImages', throttledRedraw);
47739 } else if (!services.mapillary && _mapillary) {
47747 function showLayer() {
47748 var mapillary = getMapillary();
47749 if (!mapillary) return;
47751 mapillary.loadViewer(context);
47755 .style('opacity', 0)
47758 .style('opacity', 1)
47759 .on('end', function () { dispatch$$1.call('change'); });
47763 function hideLayer() {
47764 var mapillary = getMapillary();
47766 mapillary.hideViewer();
47769 throttledRedraw.cancel();
47774 .style('opacity', 0)
47775 .on('end', editOff);
47779 function editOn() {
47780 layer.style('display', 'block');
47784 function editOff() {
47785 layer.selectAll('.viewfield-group').remove();
47786 layer.style('display', 'none');
47790 function click(d) {
47791 var mapillary = getMapillary();
47792 if (!mapillary) return;
47794 context.map().centerEase(d.loc);
47797 .selectedImage(d.key, true)
47798 .updateViewer(d.key, context)
47803 function transform(d) {
47804 var t = svgPointTransform(projection)(d);
47805 if (d.ca) t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
47810 function update() {
47811 var mapillary = getMapillary(),
47812 data = (mapillary ? mapillary.images(projection) : []),
47813 imageKey = mapillary ? mapillary.selectedImage() : null;
47815 var markers = layer.selectAll('.viewfield-group')
47816 .data(data, function(d) { return d.key; });
47821 var enter = markers.enter()
47823 .attr('class', 'viewfield-group')
47824 .classed('selected', function(d) { return d.key === imageKey; })
47825 .on('click', click);
47829 .attr('transform', transform);
47832 var viewfields = markers.selectAll('.viewfield')
47833 .data(~~context.map().zoom() >= minViewfieldZoom ? [0] : []);
47840 .attr('class', 'viewfield')
47841 .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
47842 .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');
47844 markers.selectAll('circle')
47854 function drawImages(selection$$1) {
47855 var enabled = svgMapillaryImages.enabled,
47856 mapillary = getMapillary();
47858 layer = selection$$1.selectAll('.layer-mapillary-images')
47859 .data(mapillary ? [0] : []);
47864 layer = layer.enter()
47866 .attr('class', 'layer-mapillary-images')
47867 .style('display', enabled ? 'block' : 'none')
47871 if (mapillary && ~~context.map().zoom() >= minZoom) {
47874 mapillary.loadImages(projection);
47882 drawImages.enabled = function(_) {
47883 if (!arguments.length) return svgMapillaryImages.enabled;
47884 svgMapillaryImages.enabled = _;
47885 if (svgMapillaryImages.enabled) {
47890 dispatch$$1.call('change');
47895 drawImages.supported = function() {
47896 return !!getMapillary();
47904 function svgMapillarySigns(projection, context, dispatch$$1) {
47905 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47907 layer = select(null),
47912 if (svgMapillarySigns.initialized) return; // run once
47913 svgMapillarySigns.enabled = false;
47914 svgMapillarySigns.initialized = true;
47918 function getMapillary() {
47919 if (services.mapillary && !_mapillary) {
47920 _mapillary = services.mapillary;
47921 _mapillary.event.on('loadedSigns', throttledRedraw);
47922 } else if (!services.mapillary && _mapillary) {
47929 function showLayer() {
47934 function hideLayer() {
47935 throttledRedraw.cancel();
47940 function editOn() {
47941 layer.style('display', 'block');
47945 function editOff() {
47946 layer.selectAll('.icon-sign').remove();
47947 layer.style('display', 'none');
47951 function click(d) {
47952 var mapillary = getMapillary();
47953 if (!mapillary) return;
47955 context.map().centerEase(d.loc);
47958 .selectedImage(d.key, true)
47959 .updateViewer(d.key, context)
47964 function update() {
47965 var mapillary = getMapillary(),
47966 data = (mapillary ? mapillary.signs(projection) : []),
47967 imageKey = mapillary ? mapillary.selectedImage() : null;
47969 var signs = layer.selectAll('.icon-sign')
47970 .data(data, function(d) { return d.key; });
47975 var enter = signs.enter()
47976 .append('foreignObject')
47977 .attr('class', 'icon-sign')
47978 .attr('width', '32px') // for Firefox
47979 .attr('height', '32px') // for Firefox
47980 .classed('selected', function(d) { return d.key === imageKey; })
47981 .on('click', click);
47984 .append('xhtml:body')
47985 .attr('class', 'icon-sign-body')
47986 .html(mapillary.signHTML);
47990 .attr('x', function(d) { return projection(d.loc)[0] - 16; }) // offset by -16px to
47991 .attr('y', function(d) { return projection(d.loc)[1] - 16; }); // center signs on loc
47995 function drawSigns(selection$$1) {
47996 var enabled = svgMapillarySigns.enabled,
47997 mapillary = getMapillary();
47999 layer = selection$$1.selectAll('.layer-mapillary-signs')
48000 .data(mapillary ? [0] : []);
48005 layer = layer.enter()
48007 .attr('class', 'layer-mapillary-signs')
48008 .style('display', enabled ? 'block' : 'none')
48012 if (mapillary && ~~context.map().zoom() >= minZoom) {
48015 mapillary.loadSigns(context, projection);
48023 drawSigns.enabled = function(_) {
48024 if (!arguments.length) return svgMapillarySigns.enabled;
48025 svgMapillarySigns.enabled = _;
48026 if (svgMapillarySigns.enabled) {
48031 dispatch$$1.call('change');
48036 drawSigns.supported = function() {
48037 var mapillary = getMapillary();
48038 return (mapillary && mapillary.signsSupported());
48046 function svgOsm() {
48047 return function drawOsm(selection) {
48048 var layers = selection.selectAll('.layer-osm')
48049 .data(['areas', 'lines', 'hit', 'halo', 'label']);
48053 .attr('class', function(d) { return 'layer-osm layer-' + d; });
48057 function svgLayers(projection, context) {
48058 var dispatch$$1 = dispatch('change'),
48059 svg = select(null),
48061 { id: 'osm', layer: svgOsm(projection, context, dispatch$$1) },
48062 { id: 'gpx', layer: svgGpx(projection, context, dispatch$$1) },
48063 { id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch$$1) },
48064 { id: 'mapillary-signs', layer: svgMapillarySigns(projection, context, dispatch$$1) },
48065 { id: 'debug', layer: svgDebug(projection, context, dispatch$$1) }
48069 function drawLayers(selection$$1) {
48070 svg = selection$$1.selectAll('.surface')
48075 .attr('class', 'surface')
48078 var defs = svg.selectAll('.surface-defs')
48083 .attr('class', 'surface-defs');
48085 var groups = svg.selectAll('.data-layer')
48093 .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
48095 .each(function(d) { select(this).call(d.layer); });
48099 drawLayers.all = function() {
48104 drawLayers.layer = function(id) {
48105 var obj = lodash.find(layers, function(o) {return o.id === id;});
48106 return obj && obj.layer;
48110 drawLayers.only = function(what) {
48111 var arr = [].concat(what);
48112 drawLayers.remove(lodash.difference(lodash.map(layers, 'id'), arr));
48117 drawLayers.remove = function(what) {
48118 var arr = [].concat(what);
48119 arr.forEach(function(id) {
48120 layers = lodash.reject(layers, function(o) {return o.id === id;});
48122 dispatch$$1.call('change');
48127 drawLayers.add = function(what) {
48128 var arr = [].concat(what);
48129 arr.forEach(function(obj) {
48130 if ('id' in obj && 'layer' in obj) {
48134 dispatch$$1.call('change');
48139 drawLayers.dimensions = function(_) {
48140 if (!arguments.length) return utilGetDimensions(svg);
48141 utilSetDimensions(svg, _);
48146 return utilRebind(drawLayers, dispatch$$1, 'on');
48149 function svgLines$$1(projection) {
48150 var detected = utilDetect();
48152 var highway_stack = {
48167 function waystack(a, b) {
48168 var as = 0, bs = 0;
48169 if (a.tags.highway) { as -= highway_stack[a.tags.highway]; }
48170 if (b.tags.highway) { bs -= highway_stack[b.tags.highway]; }
48175 return function drawLines(selection$$1, graph, entities, filter) {
48176 var ways = [], pathdata = {}, onewaydata = {},
48177 getPath = svgPath(projection, graph);
48179 for (var i = 0; i < entities.length; i++) {
48180 var entity = entities[i],
48181 outer = osmSimpleMultipolygonOuterMember(entity, graph);
48183 ways.push(entity.mergeTags(outer.tags));
48184 } else if (entity.geometry(graph) === 'line') {
48189 ways = ways.filter(getPath);
48191 pathdata = lodash.groupBy(ways, function(way) { return way.layer(); });
48193 lodash.forOwn(pathdata, function(v, k) {
48194 onewaydata[k] = lodash(v)
48195 .filter(function(d) { return d.isOneWay(); })
48196 .map(svgOneWaySegments(projection, graph, 35))
48201 var layer = selection$$1.selectAll('.layer-lines');
48203 var layergroup = layer
48204 .selectAll('g.layergroup')
48205 .data(sequence(-10, 11));
48207 layergroup = layergroup.enter()
48209 .attr('class', function(d) { return 'layergroup layer' + String(d); })
48210 .merge(layergroup);
48213 var linegroup = layergroup
48214 .selectAll('g.linegroup')
48215 .data(['shadow', 'casing', 'stroke']);
48217 linegroup = linegroup.enter()
48219 .attr('class', function(d) { return 'linegroup line-' + d; })
48223 var lines = linegroup
48227 function() { return pathdata[this.parentNode.__data__] || []; },
48234 // Optimization: call simple TagClasses only on enter selection. This
48235 // works because osmEntity.key is defined to include the entity v attribute.
48238 .attr('class', function(d) { return 'way line ' + this.parentNode.__data__ + ' ' + d.id; })
48239 .call(svgTagClasses())
48242 .attr('d', getPath)
48243 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
48246 var onewaygroup = layergroup
48247 .selectAll('g.onewaygroup')
48250 onewaygroup = onewaygroup.enter()
48252 .attr('class', 'onewaygroup')
48253 .merge(onewaygroup);
48256 var oneways = onewaygroup
48260 function() { return onewaydata[this.parentNode.__data__] || []; },
48261 function(d) { return [d.id, d.index]; }
48267 oneways = oneways.enter()
48269 .attr('class', 'oneway')
48270 .attr('marker-mid', 'url(#oneway-marker)')
48272 .attr('d', function(d) { return d.d; });
48275 oneways.each(function() { this.parentNode.insertBefore(this, this); });
48280 function svgMidpoints$$1(projection, context) {
48282 return function drawMidpoints(selection, graph, entities, filter, extent) {
48283 var poly = extent.polygon(),
48286 for (var i = 0; i < entities.length; i++) {
48287 var entity = entities[i];
48289 if (entity.type !== 'way')
48291 if (!filter(entity))
48293 if (context.selectedIDs().indexOf(entity.id) < 0)
48296 var nodes = graph.childNodes(entity);
48297 for (var j = 0; j < nodes.length - 1; j++) {
48301 id = [a.id, b.id].sort().join('-');
48303 if (midpoints[id]) {
48304 midpoints[id].parents.push(entity);
48306 if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
48307 var point = geoInterp(a.loc, b.loc, 0.5),
48310 if (extent.intersects(point)) {
48313 for (var k = 0; k < 4; k++) {
48314 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
48316 geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
48317 geoEuclideanDistance(projection(b.loc), projection(point)) > 20)
48330 edge: [a.id, b.id],
48340 function midpointFilter(d) {
48341 if (midpoints[d.id])
48344 for (var i = 0; i < d.parents.length; i++) {
48345 if (filter(d.parents[i])) {
48354 var layer = selection.selectAll('.layer-hit');
48357 .selectAll('g.midpoint')
48358 .filter(midpointFilter)
48359 .data(lodash.values(midpoints), function(d) { return d.id; });
48364 var enter = groups.enter()
48365 .insert('g', ':first-child')
48366 .attr('class', 'midpoint');
48368 enter.append('polygon')
48369 .attr('points', '-6,8 10,0 -6,-8')
48370 .attr('class', 'shadow');
48372 enter.append('polygon')
48373 .attr('points', '-3,4 5,0 -3,-4')
48374 .attr('class', 'fill');
48378 .attr('transform', function(d) {
48379 var translate = svgPointTransform(projection),
48380 a = graph.entity(d.edge[0]),
48381 b = graph.entity(d.edge[1]),
48382 angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
48383 return translate(d) + ' rotate(' + angleVal + ')';
48385 .call(svgTagClasses().tags(
48386 function(d) { return d.parents[0].tags; }
48389 // Propagate data bindings.
48390 groups.select('polygon.shadow');
48391 groups.select('polygon.fill');
48396 function svgOneWaySegments(projection, graph, dt) {
48397 return function(entity) {
48403 clip = identity$5().clipExtent(projection.clipExtent()).stream,
48404 coordinates = graph.childNodes(entity).map(function(n) {
48408 if (entity.tags.oneway === '-1') coordinates.reverse();
48411 type: 'LineString',
48412 coordinates: coordinates
48413 }, projection.stream(clip({
48414 lineStart: function() {},
48415 lineEnd: function() {
48418 point: function(x, y) {
48422 var span = geoEuclideanDistance(a, b) - offset;
48425 var angle = Math.atan2(b[1] - a[1], b[0] - a[0]),
48426 dx = dt * Math.cos(angle),
48427 dy = dt * Math.sin(angle),
48428 p = [a[0] + offset * Math.cos(angle),
48429 a[1] + offset * Math.sin(angle)];
48431 var segment = 'M' + a[0] + ',' + a[1] +
48432 'L' + p[0] + ',' + p[1];
48434 for (span -= dt; span >= 0; span -= dt) {
48437 segment += 'L' + p[0] + ',' + p[1];
48440 segment += 'L' + b[0] + ',' + b[1];
48441 segments.push({id: entity.id, index: i, d: segment});
48456 function svgPath(projection, graph, isArea) {
48458 // Explanation of magic numbers:
48459 // "padding" here allows space for strokes to extend beyond the viewport,
48460 // so that the stroke isn't drawn along the edge of the viewport when
48461 // the shape is clipped.
48463 // When drawing lines, pad viewport by 5px.
48464 // When drawing areas, pad viewport by 65px in each direction to allow
48465 // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
48468 padding = isArea ? 65 : 5,
48469 viewport = projection.clipExtent(),
48471 [viewport[0][0] - padding, viewport[0][1] - padding],
48472 [viewport[1][0] + padding, viewport[1][1] + padding]
48474 clip = identity$5().clipExtent(paddedExtent).stream,
48475 project = projection.stream,
48476 path$$1 = index$4()
48477 .projection({stream: function(output) { return project(clip(output)); }});
48479 return function(entity) {
48480 if (entity.id in cache) {
48481 return cache[entity.id];
48483 return cache[entity.id] = path$$1(entity.asGeoJSON(graph));
48488 function svgPoints$$1(projection, context) {
48490 function markerPath(selection, klass) {
48492 .attr('class', klass)
48493 .attr('transform', 'translate(-8, -23)')
48494 .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');
48497 function sortY(a, b) {
48498 return b.loc[1] - a.loc[1];
48502 return function drawPoints(selection, graph, entities, filter) {
48503 var wireframe = context.surface().classed('fill-wireframe'),
48504 points = wireframe ? [] : lodash.filter(entities, function(e) {
48505 return e.geometry(graph) === 'point';
48508 points.sort(sortY);
48510 var layer = selection.selectAll('.layer-hit');
48512 var groups = layer.selectAll('g.point')
48514 .data(points, osmEntity$$1.key);
48519 var enter = groups.enter()
48521 .attr('class', function(d) { return 'node point ' + d.id; })
48524 enter.append('path')
48525 .call(markerPath, 'shadow');
48527 enter.append('path')
48528 .call(markerPath, 'stroke');
48530 enter.append('use')
48531 .attr('transform', 'translate(-5, -19)')
48532 .attr('class', 'icon')
48533 .attr('width', '11px')
48534 .attr('height', '11px');
48538 .attr('transform', svgPointTransform(projection))
48539 .call(svgTagClasses());
48541 // Selecting the following implicitly
48542 // sets the data (point entity) on the element
48543 groups.select('.shadow');
48544 groups.select('.stroke');
48545 groups.select('.icon')
48546 .attr('xlink:href', function(entity) {
48547 var preset = context.presets().match(entity, graph);
48548 return (preset && preset.icon) ? '#' + preset.icon + '-11' : '';
48553 function svgRelationMemberTags(graph) {
48554 return function(entity) {
48555 var tags = entity.tags;
48556 graph.parentRelations(entity).forEach(function(relation) {
48557 var type = relation.tags.type;
48558 if (type === 'multipolygon' || type === 'boundary') {
48559 tags = lodash.extend({}, relation.tags, tags);
48566 function svgTagClasses() {
48568 'building', 'highway', 'railway', 'waterway', 'aeroway',
48569 'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
48570 'leisure', 'military', 'place'
48573 'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
48574 'razed', 'demolished', 'obliterated'
48577 'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
48578 'surface', 'tracktype', 'crossing'
48580 tagClassRe = /^tag-/,
48581 tags = function(entity) { return entity.tags; };
48584 var tagClasses = function(selection$$1) {
48585 selection$$1.each(function tagClassesEach(entity) {
48586 var value = this.className,
48587 classes, primary, status;
48589 if (value.baseVal !== undefined) value = value.baseVal;
48591 classes = value.trim().split(/\s+/).filter(function(name) {
48592 return name.length && !tagClassRe.test(name);
48595 var t = tags(entity), i, k, v;
48597 // pick at most one primary classification tag..
48598 for (i = 0; i < primaries.length; i++) {
48601 if (!v || v === 'no') continue;
48604 if (statuses.indexOf(v) !== -1) { // e.g. `railway=abandoned`
48606 classes += ' tag-' + k;
48608 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48614 // add at most one status tag, only if relates to primary tag..
48616 for (i = 0; i < statuses.length; i++) {
48619 if (!v || v === 'no') continue;
48621 if (v === 'yes') { // e.g. `railway=rail + abandoned=yes`
48624 else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
48626 } else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway`
48629 classes += ' tag-' + v;
48630 } // else ignore e.g. `highway=path + abandoned=railway`
48637 classes += ' tag-status tag-status-' + status;
48640 // add any secondary (structure) tags
48641 for (i = 0; i < secondaries.length; i++) {
48642 k = secondaries[i];
48644 if (!v || v === 'no') continue;
48645 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48648 // For highways, look for surface tagging..
48649 if (primary === 'highway') {
48650 var paved = (t.highway !== 'track');
48653 if (k in osmPavedTags) {
48654 paved = !!osmPavedTags[k][v];
48659 classes += ' tag-unpaved';
48663 classes = classes.trim();
48665 if (classes !== value) {
48666 select(this).attr('class', classes);
48672 tagClasses.tags = function(_) {
48673 if (!arguments.length) return tags;
48681 function svgTurns(projection) {
48683 return function drawTurns(selection, graph, turns) {
48685 function key(turn) {
48686 return [turn.from.node + turn.via.node + turn.to.node].join('-');
48689 function icon(turn) {
48690 var u = turn.u ? '-u' : '';
48691 if (!turn.restriction)
48692 return '#turn-yes' + u;
48693 var restriction = graph.entity(turn.restriction).tags.restriction;
48695 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
48698 var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
48705 var enter = groups.enter()
48707 .attr('class', 'turn');
48710 .filter(function (turn) { return !turn.u; });
48712 nEnter.append('rect')
48713 .attr('transform', 'translate(-22, -12)')
48714 .attr('width', '44')
48715 .attr('height', '24');
48717 nEnter.append('use')
48718 .attr('transform', 'translate(-22, -12)')
48719 .attr('width', '44')
48720 .attr('height', '24');
48724 .filter(function (turn) { return turn.u; });
48726 uEnter.append('circle')
48729 uEnter.append('use')
48730 .attr('transform', 'translate(-16, -16)')
48731 .attr('width', '32')
48732 .attr('height', '32');
48739 .attr('transform', function (turn) {
48740 var v = graph.entity(turn.via.node),
48741 t = graph.entity(turn.to.node),
48742 a = geoAngle(v, t, projection),
48743 p = projection(v.loc),
48744 r = turn.u ? 0 : 60;
48746 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
48747 'rotate(' + a * 180 / Math.PI + ')';
48750 groups.select('use')
48751 .attr('xlink:href', icon);
48753 groups.select('rect');
48754 groups.select('circle');
48760 function svgVertices$$1(projection, context) {
48762 // z16-, z17, z18+, tagged
48763 shadow: [6, 7.5, 7.5, 11.5],
48764 stroke: [2.5, 3.5, 3.5, 7],
48765 fill: [1, 1.5, 1.5, 1.5]
48771 function siblingAndChildVertices(ids, graph, extent$$1) {
48774 function addChildVertices(entity) {
48775 if (!context.features().isHiddenFeature(entity, graph, entity.geometry(graph))) {
48777 if (entity.type === 'way') {
48778 for (i = 0; i < entity.nodes.length; i++) {
48779 addChildVertices(graph.entity(entity.nodes[i]));
48781 } else if (entity.type === 'relation') {
48782 for (i = 0; i < entity.members.length; i++) {
48783 var member = context.hasEntity(entity.members[i].id);
48785 addChildVertices(member);
48788 } else if (entity.intersects(extent$$1, graph)) {
48789 vertices[entity.id] = entity;
48794 ids.forEach(function(id) {
48795 var entity = context.hasEntity(id);
48796 if (entity && entity.type === 'node') {
48797 vertices[entity.id] = entity;
48798 context.graph().parentWays(entity).forEach(function(entity) {
48799 addChildVertices(entity);
48801 } else if (entity) {
48802 addChildVertices(entity);
48810 function draw(selection$$1, vertices, klass, graph, zoom$$1, siblings) {
48812 function icon(entity) {
48813 if (entity.id in icons) return icons[entity.id];
48815 entity.hasInterestingTags() &&
48816 context.presets().match(entity, graph).icon;
48817 return icons[entity.id];
48820 function setClass(klass) {
48821 return function(entity) {
48822 this.setAttribute('class', 'node vertex ' + klass + ' ' + entity.id);
48826 function setAttributes(selection$$1) {
48827 ['shadow','stroke','fill'].forEach(function(klass) {
48828 var rads = radiuses[klass];
48829 selection$$1.selectAll('.' + klass)
48830 .each(function(entity) {
48831 var i = z && icon(entity),
48833 r = rads[i ? 3 : z];
48835 // slightly increase the size of unconnected endpoints #3775
48836 if (entity.isEndpoint(graph) && !entity.isConnected(graph)) {
48840 this.setAttribute('cx', c);
48841 this.setAttribute('cy', -c);
48842 this.setAttribute('r', r);
48843 if (i && klass === 'fill') {
48844 this.setAttribute('visibility', 'hidden');
48846 this.removeAttribute('visibility');
48851 selection$$1.selectAll('use')
48854 this.removeAttribute('visibility');
48856 this.setAttribute('visibility', 'hidden');
48862 siblings = siblings || {};
48865 z = (zoom$$1 < 17 ? 0 : zoom$$1 < 18 ? 1 : 2);
48867 var groups = selection$$1
48868 .data(vertices, osmEntity$$1.key);
48873 var enter = groups.enter()
48875 .attr('class', function(d) { return 'node vertex ' + klass + ' ' + d.id; });
48877 enter.append('circle')
48878 .each(setClass('shadow'));
48880 enter.append('circle')
48881 .each(setClass('stroke'));
48883 // Vertices with icons get a `use`.
48884 enter.filter(function(d) { return icon(d); })
48886 .attr('transform', 'translate(-5, -6)')
48887 .attr('xlink:href', function(d) { return '#' + icon(d) + '-11'; })
48888 .attr('width', '11px')
48889 .attr('height', '11px')
48890 .each(setClass('icon'));
48892 // Vertices with tags get a fill.
48893 enter.filter(function(d) { return d.hasInterestingTags(); })
48895 .each(setClass('fill'));
48899 .attr('transform', svgPointTransform(projection))
48900 .classed('sibling', function(entity) { return entity.id in siblings; })
48901 .classed('shared', function(entity) { return graph.isShared(entity); })
48902 .classed('endpoint', function(entity) { return entity.isEndpoint(graph); })
48903 .call(setAttributes);
48907 function drawVertices(selection$$1, graph, entities, filter, extent$$1, zoom$$1) {
48908 var siblings = siblingAndChildVertices(context.selectedIDs(), graph, extent$$1),
48909 wireframe = context.surface().classed('fill-wireframe'),
48912 for (var i = 0; i < entities.length; i++) {
48913 var entity = entities[i],
48914 geometry = entity.geometry(graph);
48916 if (wireframe && geometry === 'point') {
48917 vertices.push(entity);
48921 if (geometry !== 'vertex')
48924 if (entity.id in siblings ||
48925 entity.hasInterestingTags() ||
48926 entity.isEndpoint(graph) ||
48927 entity.isConnected(graph)) {
48928 vertices.push(entity);
48932 var layer = selection$$1.selectAll('.layer-hit');
48933 layer.selectAll('g.vertex.vertex-persistent')
48935 .call(draw, vertices, 'vertex-persistent', graph, zoom$$1, siblings);
48937 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48941 function drawHover(selection$$1, graph, extent$$1, zoom$$1) {
48942 var hovered = hover ? siblingAndChildVertices([hover.id], graph, extent$$1) : {};
48943 var layer = selection$$1.selectAll('.layer-hit');
48945 layer.selectAll('g.vertex.vertex-hover')
48946 .call(draw, values(hovered), 'vertex-hover', graph, zoom$$1);
48950 drawVertices.drawHover = function(selection$$1, graph, target, extent$$1, zoom$$1) {
48951 if (target === hover) return;
48953 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48956 return drawVertices;
48959 function behaviorEdit(context) {
48963 .minzoom(context.minEditableZoom());
48967 edit.off = function() {
48977 The hover behavior adds the `.hover` class on mouseover to all elements to which
48978 the identical datum is bound, and removes it on mouseout.
48980 The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
48981 representation may consist of several elements scattered throughout the DOM hierarchy.
48982 Only one of these elements can have the :hover pseudo-class, but all of them will
48983 have the .hover class.
48985 function behaviorHover() {
48986 var dispatch$$1 = dispatch('hover'),
48987 selection$$1 = select(null),
48993 function keydown() {
48994 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
48995 dispatch$$1.call('hover', this, null);
48996 selection$$1.selectAll('.hover')
48997 .classed('hover-suppressed', true)
48998 .classed('hover', false);
49004 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
49005 dispatch$$1.call('hover', this, target ? target.id : null);
49006 selection$$1.selectAll('.hover-suppressed')
49007 .classed('hover-suppressed', false)
49008 .classed('hover', true);
49013 var hover = function(__) {
49017 .on('mouseover.hover', mouseover)
49018 .on('mouseout.hover', mouseout)
49019 .on('mousedown.hover', mousedown);
49022 .on('keydown.hover', keydown)
49023 .on('keyup.hover', keyup);
49026 function mouseover() {
49027 if (buttonDown) return;
49028 var target = event.target;
49029 enter(target ? target.__data__ : null);
49033 function mouseout() {
49034 if (buttonDown) return;
49035 var target = event.relatedTarget;
49036 enter(target ? target.__data__ : null);
49040 function mousedown() {
49043 .on('mouseup.hover', mouseup, true);
49047 function mouseup() {
49048 buttonDown = false;
49050 .on('mouseup.hover', null, true);
49054 function enter(d) {
49055 if (d === target) return;
49058 selection$$1.selectAll('.hover')
49059 .classed('hover', false);
49060 selection$$1.selectAll('.hover-suppressed')
49061 .classed('hover-suppressed', false);
49063 if (target instanceof osmEntity$$1) {
49064 var selector$$1 = '.' + target.id;
49066 if (target.type === 'relation') {
49067 target.members.forEach(function(member) {
49068 selector$$1 += ', .' + member.id;
49072 var suppressed = altDisables && event && event.altKey;
49074 selection$$1.selectAll(selector$$1)
49075 .classed(suppressed ? 'hover-suppressed' : 'hover', true);
49077 dispatch$$1.call('hover', this, target.id);
49079 dispatch$$1.call('hover', this, null);
49086 hover.off = function(selection$$1) {
49087 selection$$1.selectAll('.hover')
49088 .classed('hover', false);
49089 selection$$1.selectAll('.hover-suppressed')
49090 .classed('hover-suppressed', false);
49093 .on('mouseover.hover', null)
49094 .on('mouseout.hover', null)
49095 .on('mousedown.hover', null);
49098 .on('keydown.hover', null)
49099 .on('keyup.hover', null);
49103 hover.altDisables = function(_) {
49104 if (!arguments.length) return altDisables;
49110 return utilRebind(hover, dispatch$$1, 'on');
49113 function behaviorTail() {
49117 tooltipSize = [0, 0],
49118 selectionSize = [0, 0];
49121 function tail(selection$$1) {
49122 if (!text$$1) return;
49125 .on('resize.tail', function() { selectionSize = utilGetDimensions(selection$$1); });
49127 container = select(document.body)
49129 .style('display', 'none')
49130 .attr('class', 'tail tooltip-inner');
49132 container.append('div')
49136 .on('mousemove.tail', mousemove)
49137 .on('mouseenter.tail', mouseenter)
49138 .on('mouseleave.tail', mouseleave);
49141 .on('mousemove.tail', mousemove);
49143 tooltipSize = utilGetDimensions(container);
49144 selectionSize = utilGetDimensions(selection$$1);
49148 container.style('display', 'block');
49149 tooltipSize = utilGetDimensions(container);
49153 function mousemove() {
49154 if (container.style('display') === 'none') show();
49155 var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
49156 -tooltipSize[0] - xmargin : xmargin;
49157 container.classed('left', xoffset > 0);
49158 utilSetTransform(container, event.clientX + xoffset, event.clientY);
49162 function mouseleave() {
49163 if (event.relatedTarget !== container.node()) {
49164 container.style('display', 'none');
49169 function mouseenter() {
49170 if (event.relatedTarget !== container.node()) {
49177 tail.off = function(selection$$1) {
49178 if (!text$$1) return;
49181 .on('mousemove.tail', null)
49185 .on('mousemove.tail', null)
49186 .on('mouseenter.tail', null)
49187 .on('mouseleave.tail', null);
49190 .on('resize.tail', null);
49194 tail.text = function(_) {
49195 if (!arguments.length) return text$$1;
49204 behaviorDraw.usedTails = {};
49205 behaviorDraw.disableSpace = false;
49206 behaviorDraw.lastSpace = null;
49209 function behaviorDraw(context) {
49210 var dispatch$$1 = dispatch('move', 'click', 'clickWay',
49211 'clickNode', 'undo', 'cancel', 'finish'),
49212 keybinding = d3keybinding('draw'),
49213 hover = behaviorHover(context)
49215 .on('hover', context.ui().sidebar.hover),
49216 tail = behaviorTail(),
49217 edit = behaviorEdit(context),
49218 closeTolerance = 4,
49220 mouseLeave = false,
49222 cached = behaviorDraw;
49226 if (event.altKey) return {};
49228 if (event.type === 'keydown') {
49229 return (lastMouse && lastMouse.target.__data__) || {};
49231 return event.target.__data__ || {};
49236 function mousedown() {
49239 var p = context.container().node();
49240 return touchId !== null ? touches(p).filter(function(p) {
49241 return p.identifier === touchId;
49245 var element = select(this),
49246 touchId = event.touches ? event.changedTouches[0].identifier : null,
49250 element.on('mousemove.draw', null);
49252 select(window).on('mouseup.draw', function() {
49253 var t2 = +new Date(),
49255 dist = geoEuclideanDistance(p1, p2);
49257 element.on('mousemove.draw', mousemove);
49258 select(window).on('mouseup.draw', null);
49260 if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
49261 // Prevent a quick second click
49262 select(window).on('click.draw-block', function() {
49263 event.stopPropagation();
49266 context.map().dblclickEnable(false);
49268 window.setTimeout(function() {
49269 context.map().dblclickEnable(true);
49270 select(window).on('click.draw-block', null);
49279 function mousemove() {
49281 dispatch$$1.call('move', this, datum());
49285 function mouseenter() {
49286 mouseLeave = false;
49290 function mouseleave() {
49297 if (d.type === 'way') {
49298 var dims = context.map().dimensions(),
49299 mouse$$1 = context.mouse(),
49301 trySnap = mouse$$1[0] > pad && mouse$$1[0] < dims[0] - pad &&
49302 mouse$$1[1] > pad && mouse$$1[1] < dims[1] - pad;
49305 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection),
49306 edge = [d.nodes[choice.index - 1], d.nodes[choice.index]];
49307 dispatch$$1.call('clickWay', this, choice.loc, edge);
49309 dispatch$$1.call('click', this, context.map().mouseCoordinates());
49312 } else if (d.type === 'node') {
49313 dispatch$$1.call('clickNode', this, d);
49316 dispatch$$1.call('click', this, context.map().mouseCoordinates());
49322 var currSpace = context.mouse();
49323 if (cached.disableSpace && cached.lastSpace) {
49324 var dist = geoEuclideanDistance(cached.lastSpace, currSpace);
49325 if (dist > tolerance) {
49326 cached.disableSpace = false;
49330 if (cached.disableSpace || mouseLeave || !lastMouse) return;
49332 // user must move mouse or release space bar to allow another click
49333 cached.lastSpace = currSpace;
49334 cached.disableSpace = true;
49336 select(window).on('keyup.space-block', function() {
49337 cached.disableSpace = false;
49338 select(window).on('keyup.space-block', null);
49341 event.preventDefault();
49346 function backspace() {
49347 event.preventDefault();
49348 dispatch$$1.call('undo');
49353 event.preventDefault();
49354 dispatch$$1.call('cancel');
49359 event.preventDefault();
49360 dispatch$$1.call('finish');
49364 function draw(selection$$1) {
49365 context.install(hover);
49366 context.install(edit);
49368 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
49369 context.install(tail);
49373 .on('⌫', backspace)
49377 .on('space', space)
49378 .on('⌥space', space);
49381 .on('mouseenter.draw', mouseenter)
49382 .on('mouseleave.draw', mouseleave)
49383 .on('mousedown.draw', mousedown)
49384 .on('mousemove.draw', mousemove);
49393 draw.off = function(selection$$1) {
49394 context.ui().sidebar.hover.cancel();
49395 context.uninstall(hover);
49396 context.uninstall(edit);
49398 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
49399 context.uninstall(tail);
49400 cached.usedTails[tail.text()] = true;
49404 .on('mouseenter.draw', null)
49405 .on('mouseleave.draw', null)
49406 .on('mousedown.draw', null)
49407 .on('mousemove.draw', null);
49410 .on('mouseup.draw', null);
49411 // note: keyup.space-block, click.draw-block should remain
49414 .call(keybinding.off);
49418 draw.tail = function(_) {
49424 return utilRebind(draw, dispatch$$1, 'on');
49427 function behaviorAddWay(context) {
49428 var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
49429 draw = behaviorDraw(context);
49431 var addWay = function(surface) {
49432 draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
49433 .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
49434 .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
49435 .on('cancel', addWay.cancel)
49436 .on('finish', addWay.cancel);
49439 .dblclickEnable(false);
49441 surface.call(draw);
49445 addWay.off = function(surface) {
49446 surface.call(draw.off);
49450 addWay.cancel = function() {
49451 window.setTimeout(function() {
49452 context.map().dblclickEnable(true);
49455 context.enter(modeBrowse(context));
49459 addWay.tail = function(text$$1) {
49460 draw.tail(text$$1);
49465 return utilRebind(addWay, dispatch$$1, 'on');
49468 function behaviorBreathe() {
49469 var duration = 800,
49471 selector$$1 = '.selected.shadow, .selected .shadow',
49472 selected = select(null),
49479 function ratchetyInterpolator(a, b, steps, units) {
49482 var sample = quantize$2()
49484 .range(quantize$1(number$1(a, b), steps));
49486 return function(t) {
49487 return String(sample(t)) + (units || '');
49492 function reset(selection$$1) {
49494 .style('stroke-opacity', null)
49495 .style('stroke-width', null)
49496 .style('fill-opacity', null)
49501 function setAnimationParams(transition$$1, fromTo) {
49502 var toFrom = (fromTo === 'from' ? 'to' : 'from');
49505 .styleTween('stroke-opacity', function(d) {
49506 return ratchetyInterpolator(
49507 params[d.id][toFrom].opacity,
49508 params[d.id][fromTo].opacity,
49512 .styleTween('stroke-width', function(d) {
49513 return ratchetyInterpolator(
49514 params[d.id][toFrom].width,
49515 params[d.id][fromTo].width,
49520 .styleTween('fill-opacity', function(d) {
49521 return ratchetyInterpolator(
49522 params[d.id][toFrom].opacity,
49523 params[d.id][fromTo].opacity,
49527 .styleTween('r', function(d) {
49528 return ratchetyInterpolator(
49529 params[d.id][toFrom].width,
49530 params[d.id][fromTo].width,
49538 function calcAnimationParams(selection$$1) {
49541 .each(function(d) {
49542 var s = select(this),
49543 tag = s.node().tagName,
49544 p = {'from': {}, 'to': {}},
49547 // determine base opacity and width
49548 if (tag === 'circle') {
49549 opacity = parseFloat(s.style('fill-opacity') || 0.5);
49550 width = parseFloat(s.style('r') || 15.5);
49552 opacity = parseFloat(s.style('stroke-opacity') || 0.7);
49553 width = parseFloat(s.style('stroke-width') || 10);
49556 // calculate from/to interpolation params..
49558 p.from.opacity = opacity * 0.6;
49559 p.to.opacity = opacity * 1.25;
49560 p.from.width = width * 0.9;
49561 p.to.width = width * (tag === 'circle' ? 1.5 : 1.25);
49567 function run(surface, fromTo) {
49568 var toFrom = (fromTo === 'from' ? 'to' : 'from'),
49569 currSelected = surface.selectAll(selector$$1),
49570 currClassed = surface.attr('class');
49572 if (done || currSelected.empty()) {
49573 selected.call(reset);
49577 if (!lodash.isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
49578 selected.call(reset);
49579 classed = currClassed;
49580 selected = currSelected.call(calcAnimationParams);
49585 .duration(duration)
49586 .call(setAnimationParams, fromTo)
49587 .on('end', function() {
49588 surface.call(run, toFrom);
49593 var breathe = function(surface) {
49595 timer$$1 = timer$1(function() {
49596 // wait for elements to actually become selected
49597 if (surface.selectAll(selector$$1).empty()) {
49601 surface.call(run, 'from');
49608 breathe.off = function() {
49622 function behaviorCopy(context) {
49623 var keybinding = d3keybinding('copy');
49626 function groupEntities(ids, graph) {
49627 var entities = ids.map(function (id) { return graph.entity(id); });
49628 return lodash.extend({relation: [], way: [], node: []},
49629 lodash.groupBy(entities, function(entity) { return entity.type; }));
49633 function getDescendants(id, graph, descendants) {
49634 var entity = graph.entity(id),
49637 descendants = descendants || {};
49639 if (entity.type === 'relation') {
49640 children = lodash.map(entity.members, 'id');
49641 } else if (entity.type === 'way') {
49642 children = entity.nodes;
49647 for (i = 0; i < children.length; i++) {
49648 if (!descendants[children[i]]) {
49649 descendants[children[i]] = true;
49650 descendants = getDescendants(children[i], graph, descendants);
49654 return descendants;
49658 function doCopy() {
49659 event.preventDefault();
49660 if (context.inIntro()) return;
49662 var graph = context.graph(),
49663 selected = groupEntities(context.selectedIDs(), graph),
49668 for (i = 0; i < selected.relation.length; i++) {
49669 entity = selected.relation[i];
49670 if (!skip[entity.id] && entity.isComplete(graph)) {
49671 canCopy.push(entity.id);
49672 skip = getDescendants(entity.id, graph, skip);
49675 for (i = 0; i < selected.way.length; i++) {
49676 entity = selected.way[i];
49677 if (!skip[entity.id]) {
49678 canCopy.push(entity.id);
49679 skip = getDescendants(entity.id, graph, skip);
49682 for (i = 0; i < selected.node.length; i++) {
49683 entity = selected.node[i];
49684 if (!skip[entity.id]) {
49685 canCopy.push(entity.id);
49689 context.copyIDs(canCopy);
49694 keybinding.on(uiCmd('⌘C'), doCopy);
49695 select(document).call(keybinding);
49700 copy.off = function() {
49701 select(document).call(keybinding.off);
49709 `behaviorDrag` is like `d3.behavior.drag`, with the following differences:
49711 * The `origin` function is expected to return an [x, y] tuple rather than an
49713 * The events are `start`, `move`, and `end`.
49714 (https://github.com/mbostock/d3/issues/563)
49715 * The `start` event is not dispatched until the first cursor movement occurs.
49716 (https://github.com/mbostock/d3/pull/368)
49717 * The `move` event has a `point` and `delta` [x, y] tuple properties rather
49718 than `x`, `y`, `dx`, and `dy` properties.
49719 * The `end` event is not dispatched if no movement occurs.
49720 * An `off` function is available that unbinds the drag's internal event handlers.
49721 * Delegation is supported via the `delegate` function.
49724 function behaviorDrag() {
49725 var event$$1 = dispatch('start', 'move', 'end'),
49729 event_, target, surface;
49732 function d3_eventCancel() {
49733 event.stopPropagation();
49734 event.preventDefault();
49737 function eventOf(thiz, argumentz) {
49738 return function(e1) {
49739 e1.target = drag$$1;
49740 customEvent(e1, event$$1.apply, event$$1, [e1.type, thiz, argumentz]);
49744 var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect'),
49745 d3_event_userSelectSuppress = d3_event_userSelectProperty ?
49747 var selection$$1 = selection(),
49748 select$$1 = selection$$1.style(d3_event_userSelectProperty);
49749 selection$$1.style(d3_event_userSelectProperty, 'none');
49750 return function () {
49751 selection$$1.style(d3_event_userSelectProperty, select$$1);
49755 var w = select(window).on('selectstart.' + type, d3_eventCancel);
49756 return function () {
49757 w.on('selectstart.' + type, null);
49762 function dragstart() {
49764 event_ = eventOf(target, arguments);
49766 var eventTarget = event.target,
49767 touchId = event.touches ? event.changedTouches[0].identifier : null,
49771 selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
49773 var w = select(window)
49774 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
49775 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
49778 offset = origin.apply(target, arguments);
49779 offset = [offset[0] - origin_[0], offset[1] - origin_[1]];
49784 if (touchId === null) event.stopPropagation();
49788 var p = surface || target.parentNode;
49789 return touchId !== null ? touches(p).filter(function(p) {
49790 return p.identifier === touchId;
49795 function dragmove() {
49797 dx = p[0] - origin_[0],
49798 dy = p[1] - origin_[1];
49800 if (dx === 0 && dy === 0)
49815 point: [p[0] + offset[0], p[1] + offset[1]],
49821 function dragend() {
49828 if (event.target === eventTarget) w.on('click.drag', click, true);
49831 w.on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
49832 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
49839 w.on('click.drag', null);
49844 function drag$$1(selection$$1) {
49845 var matchesSelector = utilPrefixDOMProperty('matchesSelector'),
49846 delegate = dragstart;
49849 delegate = function() {
49851 target = event.target;
49852 for (; target && target !== root; target = target.parentNode) {
49853 if (target[matchesSelector](selector$$1) &&
49854 (!filter || filter(target.__data__))) {
49855 return dragstart.call(target, target.__data__);
49861 selection$$1.on('mousedown.drag' + selector$$1, delegate)
49862 .on('touchstart.drag' + selector$$1, delegate);
49866 drag$$1.off = function(selection$$1) {
49867 selection$$1.on('mousedown.drag' + selector$$1, null)
49868 .on('touchstart.drag' + selector$$1, null);
49872 drag$$1.delegate = function(_) {
49873 if (!arguments.length) return selector$$1;
49879 drag$$1.filter = function(_) {
49880 if (!arguments.length) return origin;
49886 drag$$1.origin = function (_) {
49887 if (!arguments.length) return origin;
49893 drag$$1.cancel = function() {
49895 .on('mousemove.drag', null)
49896 .on('mouseup.drag', null);
49901 drag$$1.target = function() {
49902 if (!arguments.length) return target;
49903 target = arguments[0];
49904 event_ = eventOf(target, Array.prototype.slice.call(arguments, 1));
49909 drag$$1.surface = function() {
49910 if (!arguments.length) return surface;
49911 surface = arguments[0];
49916 return utilRebind(drag$$1, event$$1, 'on');
49919 function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
49921 var way = context.entity(wayId),
49922 isArea = context.geometry(wayId) === 'area',
49924 annotation = t((way.isDegenerate() ?
49925 'operations.start.annotation.' :
49926 'operations.continue.annotation.') + context.geometry(wayId)),
49927 draw = behaviorDraw(context),
49928 startIndex, start, end, segment;
49932 startIndex = typeof index === 'undefined' ? way.nodes.length - 1 : 0;
49933 start = osmNode({ id: 'nStart', loc: context.entity(way.nodes[startIndex]).loc });
49934 end = osmNode({ id: 'nEnd', loc: context.map().mouseCoordinates() });
49935 segment = osmWay({ id: 'wTemp',
49936 nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
49937 tags: lodash.clone(way.tags)
49940 end = osmNode({ loc: context.map().mouseCoordinates() });
49944 var fn = context[way.isDegenerate() ? 'replace' : 'perform'];
49946 fn(actionAddEntity(end),
49947 actionAddVertex(wayId, end.id)
49950 fn(actionAddEntity(start),
49951 actionAddEntity(end),
49952 actionAddEntity(segment)
49957 function move(datum) {
49960 if (datum.type === 'node' && datum.id !== end.id) {
49963 } else if (datum.type === 'way') { // && (segment || datum.id !== segment.id)) {
49964 var dims = context.map().dimensions(),
49965 mouse = context.mouse(),
49967 trySnap = mouse[0] > pad && mouse[0] < dims[0] - pad &&
49968 mouse[1] > pad && mouse[1] < dims[1] - pad;
49971 loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
49976 loc = context.map().mouseCoordinates();
49979 context.replace(actionMoveNode(end.id, loc));
49983 function undone() {
49985 context.enter(modeBrowse(context));
49989 function setActiveElements() {
49990 var active = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
49991 context.surface().selectAll(utilEntitySelector(active))
49992 .classed('active', true);
49996 var drawWay = function(surface) {
49997 draw.on('move', move)
49998 .on('click', drawWay.add)
49999 .on('clickWay', drawWay.addWay)
50000 .on('clickNode', drawWay.addNode)
50001 .on('undo', context.undo)
50002 .on('cancel', drawWay.cancel)
50003 .on('finish', drawWay.finish);
50006 .dblclickEnable(false)
50007 .on('drawn.draw', setActiveElements);
50009 setActiveElements();
50011 surface.call(draw);
50014 .on('undone.draw', undone);
50018 drawWay.off = function(surface) {
50023 .on('drawn.draw', null);
50025 surface.call(draw.off)
50026 .selectAll('.active')
50027 .classed('active', false);
50030 .on('undone.draw', null);
50034 function ReplaceTemporaryNode(newNode) {
50035 return function(graph) {
50038 .replace(way.addNode(newNode.id))
50042 .replace(graph.entity(wayId).addNode(newNode.id, index))
50051 // Accept the current position of the temporary node and continue drawing.
50052 drawWay.add = function(loc) {
50053 // prevent duplicate nodes
50054 var last = context.hasEntity(way.nodes[way.nodes.length - (isArea ? 2 : 1)]);
50055 if (last && last.loc[0] === loc[0] && last.loc[1] === loc[1]) return;
50059 actionMoveNode(end.id, loc),
50063 var newNode = osmNode({loc: loc});
50065 actionAddEntity(newNode),
50066 ReplaceTemporaryNode(newNode),
50072 context.enter(mode);
50076 // Connect the way to an existing way.
50077 drawWay.addWay = function(loc, edge) {
50081 actionAddMidpoint({ loc: loc, edge: edge}, end),
50085 var previousEdge = startIndex ?
50086 [way.nodes[startIndex], way.nodes[startIndex - 1]] :
50087 [way.nodes[0], way.nodes[1]];
50089 // Avoid creating duplicate segments
50090 if (geoEdgeEqual(edge, previousEdge))
50093 var newNode = osmNode({ loc: loc });
50095 actionAddMidpoint({ loc: loc, edge: edge}, newNode),
50096 ReplaceTemporaryNode(newNode),
50102 context.enter(mode);
50106 // Connect the way to an existing node and continue drawing.
50107 drawWay.addNode = function(node) {
50108 // Avoid creating duplicate segments
50109 if (way.areAdjacent(node.id, way.nodes[way.nodes.length - 1])) return;
50112 ReplaceTemporaryNode(node),
50117 context.enter(mode);
50121 // Finish the draw operation, removing the temporary node. If the way has enough
50122 // nodes to be valid, it's selected. Otherwise, return to browse mode.
50123 drawWay.finish = function() {
50127 window.setTimeout(function() {
50128 context.map().dblclickEnable(true);
50131 if (context.hasEntity(wayId)) {
50133 modeSelect(context, [wayId]).suppressMenu(true).newFeature(true)
50136 context.enter(modeBrowse(context));
50141 // Cancel the draw operation and return to browse, deleting everything drawn.
50142 drawWay.cancel = function() {
50144 utilFunctor(baseGraph),
50145 t('operations.cancel_draw.annotation'));
50147 window.setTimeout(function() {
50148 context.map().dblclickEnable(true);
50152 context.enter(modeBrowse(context));
50156 drawWay.tail = function(text) {
50165 function behaviorHash(context) {
50166 var s0 = null, // cached window.location.hash
50167 lat = 90 - 1e-8; // allowable latitude range
50170 var parser = function(map$$1, s) {
50171 var q = utilStringQs(s);
50172 var args = (q.map || '').split('/').map(Number);
50173 if (args.length < 3 || args.some(isNaN)) {
50174 return true; // replace bogus hash
50175 } else if (s !== formatter(map$$1).slice(1)) {
50176 map$$1.centerZoom([args[2],
50177 Math.min(lat, Math.max(-lat, args[1]))], args[0]);
50182 var formatter = function(map$$1) {
50183 var mode = context.mode(),
50184 center = map$$1.center(),
50185 zoom$$1 = map$$1.zoom(),
50186 precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2)),
50187 q = lodash.omit(utilStringQs(window.location.hash.substring(1)), 'comment'),
50190 if (mode && mode.id === 'browse') {
50193 var selected = context.selectedIDs().filter(function(id) {
50194 return !context.entity(id).isNew();
50196 if (selected.length) {
50197 newParams.id = selected.join(',');
50201 newParams.map = zoom$$1.toFixed(2) +
50202 '/' + center[1].toFixed(precision) +
50203 '/' + center[0].toFixed(precision);
50205 return '#' + utilQsString(lodash.assign(q, newParams), true);
50209 function update() {
50210 if (context.inIntro()) return;
50211 var s1 = formatter(context.map());
50213 window.location.replace(s0 = s1); // don't recenter the map!
50218 var throttledUpdate = lodash.throttle(update, 500);
50221 function hashchange() {
50222 if (window.location.hash === s0) return; // ignore spurious hashchange events
50223 if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
50224 update(); // replace bogus hash
50231 .on('move.hash', throttledUpdate);
50234 .on('enter.hash', throttledUpdate);
50237 .on('hashchange.hash', hashchange);
50239 if (window.location.hash) {
50240 var q = utilStringQs(window.location.hash.substring(1));
50241 if (q.id) context.zoomToEntity(q.id.split(',')[0], !q.map);
50242 if (q.comment) context.storage('comment', q.comment);
50244 if (q.map) hash.hadHash = true;
50249 hash.off = function() {
50250 throttledUpdate.cancel();
50253 .on('move.hash', null);
50256 .on('enter.hash', null);
50259 .on('hashchange.hash', null);
50261 window.location.hash = '';
50268 function behaviorLasso(context) {
50270 var behavior = function(selection$$1) {
50274 function mousedown() {
50275 var button = 0; // left
50276 if (event.button === button && event.shiftKey === true) {
50280 .on('mousemove.lasso', mousemove)
50281 .on('mouseup.lasso', mouseup);
50283 event.stopPropagation();
50288 function mousemove() {
50290 lasso = uiLasso(context);
50291 context.surface().call(lasso);
50294 lasso.p(context.mouse());
50298 function normalize(a, b) {
50300 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
50301 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
50305 function lassoed() {
50306 if (!lasso) return [];
50308 var graph = context.graph(),
50309 bounds = lasso.extent().map(context.projection.invert),
50310 extent$$1 = geoExtent$$1(normalize(bounds[0], bounds[1]));
50312 return lodash.map(context.intersects(extent$$1).filter(function(entity) {
50313 return entity.type === 'node' &&
50314 geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
50315 !context.features().isHidden(entity, graph, entity.geometry(graph));
50320 function mouseup() {
50322 .on('mousemove.lasso', null)
50323 .on('mouseup.lasso', null);
50325 if (!lasso) return;
50327 var ids = lassoed();
50331 context.enter(modeSelect(context, ids));
50336 .on('mousedown.lasso', mousedown);
50340 behavior.off = function(selection$$1) {
50341 selection$$1.on('mousedown.lasso', null);
50348 /* Creates a keybinding behavior for an operation */
50349 function behaviorOperation(context) {
50350 var which, keybinding;
50353 var behavior = function () {
50355 keybinding = d3keybinding('behavior.key.' + which.id);
50356 keybinding.on(which.keys, function() {
50357 event.preventDefault();
50358 if (which.available() && !which.disabled() && !context.inIntro()) {
50362 select(document).call(keybinding);
50368 behavior.off = function() {
50370 select(document).call(keybinding.off);
50375 behavior.which = function (_) {
50376 if (!arguments.length) return which;
50385 function behaviorPaste(context) {
50386 var keybinding = d3keybinding('paste');
50388 function omitTag(v, k) {
50396 k === 'description' ||
50397 k.indexOf('name') !== -1 ||
50398 k.indexOf('wiki') === 0 ||
50399 k.indexOf('addr:') === 0 ||
50400 k.indexOf('contact:') === 0
50405 function doPaste() {
50406 event.preventDefault();
50407 if (context.inIntro()) return;
50409 var baseGraph = context.graph(),
50410 mouse$$1 = context.mouse(),
50411 projection = context.projection,
50412 viewport = geoExtent$$1(projection.clipExtent()).polygon();
50414 if (!geoPointInPolygon(mouse$$1, viewport)) return;
50416 var extent$$1 = geoExtent$$1(),
50417 oldIDs = context.copyIDs(),
50418 oldGraph = context.copyGraph(),
50421 if (!oldIDs.length) return;
50423 var action = actionCopyEntities(oldIDs, oldGraph);
50424 context.perform(action);
50426 var copies = action.copies();
50427 var originals = lodash.invert(lodash.mapValues(copies, 'id'));
50428 for (var id in copies) {
50429 var oldEntity = oldGraph.entity(id),
50430 newEntity = copies[id];
50432 extent$$1._extend(oldEntity.extent(oldGraph));
50434 actionChangeTags(newEntity.id, lodash.omit(newEntity.tags, omitTag))
50437 // Exclude child nodes from newIDs if their parent way was also copied.
50438 var parents = context.graph().parentWays(newEntity),
50439 parentCopied = false;
50440 for (var i = 0; i < parents.length; i++) {
50441 if (originals[parents[i].id]) {
50442 parentCopied = true;
50447 if (!parentCopied) {
50448 newIDs.push(newEntity.id);
50452 // Put pasted objects where mouse pointer is..
50453 var center = projection(extent$$1.center()),
50454 delta = [ mouse$$1[0] - center[0], mouse$$1[1] - center[1] ];
50456 context.perform(actionMove(newIDs, delta, projection));
50457 context.enter(modeMove$$1(context, newIDs, baseGraph));
50462 keybinding.on(uiCmd('⌘V'), doPaste);
50463 select(document).call(keybinding);
50468 paste.off = function() {
50469 select(document).call(keybinding.off);
50476 function behaviorSelect(context) {
50478 function keydown() {
50479 if (event && event.shiftKey) {
50481 .classed('behavior-multiselect', true);
50487 if (!event || !event.shiftKey) {
50489 .classed('behavior-multiselect', false);
50495 var datum = event.target.__data__,
50496 lasso = select('#surface .lasso').node(),
50497 mode = context.mode();
50499 if (datum.type === 'midpoint') {
50501 } else if (!(datum instanceof osmEntity$$1)) {
50502 if (!event.shiftKey && !lasso && mode.id !== 'browse')
50503 context.enter(modeBrowse(context));
50505 } else if (!event.shiftKey && !lasso) {
50506 // Avoid re-entering Select mode with same entity.
50507 if (context.selectedIDs().length !== 1 || context.selectedIDs()[0] !== datum.id) {
50508 context.enter(modeSelect(context, [datum.id]));
50510 mode.suppressMenu(false).reselect();
50512 } else if (context.selectedIDs().indexOf(datum.id) >= 0) {
50513 var selectedIDs = lodash.without(context.selectedIDs(), datum.id);
50514 context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
50517 context.enter(modeSelect(context, context.selectedIDs().concat([datum.id])));
50522 var behavior = function(selection$$1) {
50524 .on('keydown.select', keydown)
50525 .on('keyup.select', keyup);
50527 selection$$1.on('click.select', click);
50533 behavior.off = function(selection$$1) {
50535 .on('keydown.select', null)
50536 .on('keyup.select', null);
50538 selection$$1.on('click.select', null);
50547 function modeAddArea$$1(context) {
50551 title: t('modes.add_area.title'),
50552 description: t('modes.add_area.description'),
50556 var behavior = behaviorAddWay(context)
50557 .tail(t('modes.add_area.tail'))
50558 .on('start', start)
50559 .on('startFromWay', startFromWay)
50560 .on('startFromNode', startFromNode),
50561 defaultTags = { area: 'yes' };
50564 function actionClose(wayId) {
50565 return function (graph) {
50566 return graph.replace(graph.entity(wayId).close());
50571 function start(loc) {
50572 var graph = context.graph(),
50573 node = osmNode({ loc: loc }),
50574 way = osmWay({ tags: defaultTags });
50577 actionAddEntity(node),
50578 actionAddEntity(way),
50579 actionAddVertex(way.id, node.id),
50580 actionClose(way.id)
50583 context.enter(modeDrawArea(context, way.id, graph));
50587 function startFromWay(loc, edge) {
50588 var graph = context.graph(),
50589 node = osmNode({ loc: loc }),
50590 way = osmWay({ tags: defaultTags });
50593 actionAddEntity(node),
50594 actionAddEntity(way),
50595 actionAddVertex(way.id, node.id),
50596 actionClose(way.id),
50597 actionAddMidpoint({ loc: loc, edge: edge }, node)
50600 context.enter(modeDrawArea(context, way.id, graph));
50604 function startFromNode(node) {
50605 var graph = context.graph(),
50606 way = osmWay({ tags: defaultTags });
50609 actionAddEntity(way),
50610 actionAddVertex(way.id, node.id),
50611 actionClose(way.id)
50614 context.enter(modeDrawArea(context, way.id, graph));
50618 mode.enter = function() {
50619 context.install(behavior);
50623 mode.exit = function() {
50624 context.uninstall(behavior);
50631 function modeAddLine$$1(context) {
50635 title: t('modes.add_line.title'),
50636 description: t('modes.add_line.description'),
50640 var behavior = behaviorAddWay(context)
50641 .tail(t('modes.add_line.tail'))
50642 .on('start', start)
50643 .on('startFromWay', startFromWay)
50644 .on('startFromNode', startFromNode);
50647 function start(loc) {
50648 var baseGraph = context.graph(),
50649 node = osmNode({ loc: loc }),
50653 actionAddEntity(node),
50654 actionAddEntity(way),
50655 actionAddVertex(way.id, node.id)
50658 context.enter(modeDrawLine(context, way.id, baseGraph));
50662 function startFromWay(loc, edge) {
50663 var baseGraph = context.graph(),
50664 node = osmNode({ loc: loc }),
50668 actionAddEntity(node),
50669 actionAddEntity(way),
50670 actionAddVertex(way.id, node.id),
50671 actionAddMidpoint({ loc: loc, edge: edge }, node)
50674 context.enter(modeDrawLine(context, way.id, baseGraph));
50678 function startFromNode(node) {
50679 var baseGraph = context.graph(),
50683 actionAddEntity(way),
50684 actionAddVertex(way.id, node.id)
50687 context.enter(modeDrawLine(context, way.id, baseGraph));
50691 mode.enter = function() {
50692 context.install(behavior);
50696 mode.exit = function() {
50697 context.uninstall(behavior);
50703 function modeAddPoint$$1(context) {
50707 title: t('modes.add_point.title'),
50708 description: t('modes.add_point.description'),
50712 var behavior = behaviorDraw(context)
50713 .tail(t('modes.add_point.tail'))
50715 .on('clickWay', addWay)
50716 .on('clickNode', addNode)
50717 .on('cancel', cancel)
50718 .on('finish', cancel);
50721 function add(loc) {
50722 var node = osmNode({ loc: loc });
50725 actionAddEntity(node),
50726 t('operations.add.annotation.point')
50730 modeSelect(context, [node.id]).suppressMenu(true).newFeature(true)
50735 function addWay(loc) {
50740 function addNode(node) {
50745 function cancel() {
50746 context.enter(modeBrowse(context));
50750 mode.enter = function() {
50751 context.install(behavior);
50755 mode.exit = function() {
50756 context.uninstall(behavior);
50763 function modeBrowse(context) {
50767 title: t('modes.browse.title'),
50768 description: t('modes.browse.description')
50772 behaviorPaste(context),
50773 behaviorHover(context).on('hover', context.ui().sidebar.hover),
50774 behaviorSelect(context),
50775 behaviorLasso(context)
50779 mode.enter = function() {
50780 behaviors.forEach(function(behavior) {
50781 context.install(behavior);
50784 // Get focus on the body.
50785 if (document.activeElement && document.activeElement.blur) {
50786 document.activeElement.blur();
50790 context.ui().sidebar.show(sidebar);
50792 context.ui().sidebar.select(null);
50797 mode.exit = function() {
50798 context.ui().sidebar.hover.cancel();
50799 behaviors.forEach(function(behavior) {
50800 context.uninstall(behavior);
50804 context.ui().sidebar.hide();
50809 mode.sidebar = function(_) {
50810 if (!arguments.length) return sidebar;
50819 function modeDragNode$$1(context) {
50831 hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover),
50832 edit = behaviorEdit(context);
50835 function vecSub(a, b) {
50836 return [a[0] - b[0], a[1] - b[1]];
50839 function edge(point, size) {
50840 var pad = [30, 100, 30, 100],
50844 if (point[0] > size[0] - pad[0])
50846 if (point[0] < pad[2])
50848 if (point[1] > size[1] - pad[1])
50850 if (point[1] < pad[3])
50861 function startNudge(entity, nudge) {
50862 if (nudgeInterval) window.clearInterval(nudgeInterval);
50863 nudgeInterval = window.setInterval(function() {
50864 context.pan(nudge);
50865 doMove(entity, nudge);
50870 function stopNudge() {
50871 if (nudgeInterval) window.clearInterval(nudgeInterval);
50872 nudgeInterval = null;
50876 function moveAnnotation(entity) {
50877 return t('operations.move.annotation.' + entity.geometry(context.graph()));
50881 function connectAnnotation(entity) {
50882 return t('operations.connect.annotation.' + entity.geometry(context.graph()));
50886 function origin(entity) {
50887 return context.projection(entity.loc);
50891 function start(entity) {
50892 wasMidpoint = entity.type === 'midpoint';
50894 // Things allowed to be dragged include:
50896 // - nodes that are selected
50897 // - vertices that are selected
50898 // - vertices classed 'sibling' which includes (see svg/vertices.js)
50899 // - children of selected ways or multipolygons
50900 // - vertices sharing a way with selected vertices
50901 var selector$$1 = 'g.node.point.selected.' + entity.id +
50902 ', g.vertex-persistent.selected.' + entity.id +
50903 ', g.vertex-persistent.sibling.' + entity.id;
50905 var isDraggable = wasMidpoint || !select(selector$$1).empty();
50907 isCancelled = event.sourceEvent.shiftKey || !isDraggable ||
50908 context.features().hasHiddenConnections(entity, context.graph());
50911 return behavior.cancel();
50915 var midpoint = entity;
50916 entity = osmNode();
50917 context.perform(actionAddMidpoint(midpoint, entity));
50919 var vertex = context.surface().selectAll('.' + entity.id);
50920 behavior.target(vertex.node(), entity);
50923 context.perform(actionNoop());
50926 // activeIDs generate no pointer events. This prevents the node or vertex
50927 // being dragged from trying to connect to itself or its parent element.
50928 activeIDs = lodash.map(context.graph().parentWays(entity), 'id');
50929 activeIDs.push(entity.id);
50930 setActiveElements();
50932 context.enter(mode);
50937 var event$$1 = event && event.sourceEvent;
50938 if (!event$$1 || event$$1.altKey) {
50941 return event$$1.target.__data__ || {};
50946 function doMove(entity, nudge) {
50947 nudge = nudge || [0, 0];
50949 var currPoint = (event && event.point) || context.projection(lastLoc),
50950 currMouse = vecSub(currPoint, nudge),
50951 loc = context.projection.invert(currMouse),
50954 if (d.type === 'node' && d.id !== entity.id) {
50956 } else if (d.type === 'way' && !select(event.sourceEvent.target).classed('fill')) {
50957 loc = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection).loc;
50961 actionMoveNode(entity.id, loc),
50962 moveAnnotation(entity)
50969 function move(entity) {
50970 if (isCancelled) return;
50971 event.sourceEvent.stopPropagation();
50972 lastLoc = context.projection.invert(event.point);
50975 var nudge = edge(event.point, context.map().dimensions());
50976 if (nudge) startNudge(entity, nudge);
50981 function end(entity) {
50982 if (isCancelled) return;
50986 if (d.type === 'way') {
50987 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
50989 actionAddMidpoint({ loc: choice.loc, edge: [d.nodes[choice.index - 1], d.nodes[choice.index]] }, entity),
50990 connectAnnotation(d)
50993 } else if (d.type === 'node' && d.id !== entity.id) {
50995 actionConnect([d.id, entity.id]),
50996 connectAnnotation(d)
50999 } else if (wasMidpoint) {
51002 t('operations.add.annotation.vertex')
51008 moveAnnotation(entity)
51012 var reselection = selectedIDs.filter(function(id) {
51013 return context.graph().hasEntity(id);
51016 if (reselection.length) {
51017 context.enter(modeSelect(context, reselection).suppressMenu(true));
51019 context.enter(modeBrowse(context));
51024 function cancel() {
51026 context.enter(modeBrowse(context));
51030 function setActiveElements() {
51031 context.surface().selectAll(utilEntitySelector(activeIDs))
51032 .classed('active', true);
51036 var behavior = behaviorDrag()
51037 .delegate('g.node, g.point, g.midpoint')
51038 .surface(select('#map').node())
51040 .on('start', start)
51045 mode.enter = function() {
51046 context.install(hover);
51047 context.install(edit);
51050 .on('undone.drag-node', cancel);
51053 .on('drawn.drag-node', setActiveElements);
51055 setActiveElements();
51059 mode.exit = function() {
51060 context.ui().sidebar.hover.cancel();
51061 context.uninstall(hover);
51062 context.uninstall(edit);
51065 .on('undone.drag-node', null);
51068 .on('drawn.drag-node', null);
51071 .selectAll('.active')
51072 .classed('active', false);
51078 mode.selectedIDs = function(_) {
51079 if (!arguments.length) return selectedIDs;
51085 mode.behavior = behavior;
51091 function modeDrawArea(context, wayId, baseGraph) {
51100 mode.enter = function() {
51101 var way = context.entity(wayId);
51103 behavior = behaviorDrawWay(context, wayId, undefined, mode, baseGraph)
51104 .tail(t('modes.draw_area.tail'));
51106 var addNode = behavior.addNode;
51108 behavior.addNode = function(node) {
51109 var length = way.nodes.length,
51110 penultimate = length > 2 ? way.nodes[length - 2] : null;
51112 if (node.id === way.first() || node.id === penultimate) {
51119 context.install(behavior);
51123 mode.exit = function() {
51124 context.uninstall(behavior);
51128 mode.selectedIDs = function() {
51136 function modeDrawLine(context, wayId, baseGraph, affix) {
51145 mode.enter = function() {
51146 var way = context.entity(wayId),
51147 index = (affix === 'prefix') ? 0 : undefined,
51148 headId = (affix === 'prefix') ? way.first() : way.last();
51150 behavior = behaviorDrawWay(context, wayId, index, mode, baseGraph)
51151 .tail(t('modes.draw_line.tail'));
51153 var addNode = behavior.addNode;
51155 behavior.addNode = function(node) {
51156 if (node.id === headId) {
51163 context.install(behavior);
51167 mode.exit = function() {
51168 context.uninstall(behavior);
51172 mode.selectedIDs = function() {
51180 function operationCircularize(selectedIDs, context) {
51181 var entityId = selectedIDs[0],
51182 entity = context.entity(entityId),
51183 extent = entity.extent(context.graph()),
51184 geometry = context.geometry(entityId),
51185 action = actionCircularize(entityId, context.projection);
51188 var operation = function() {
51189 context.perform(action, t('operations.circularize.annotation.' + geometry));
51193 operation.available = function() {
51194 return selectedIDs.length === 1 &&
51195 entity.type === 'way' &&
51196 lodash.uniq(entity.nodes).length > 1;
51200 operation.disabled = function() {
51202 if (extent.percentContainedIn(context.extent()) < 0.8) {
51203 reason = 'too_large';
51204 } else if (context.hasHiddenConnections(entityId)) {
51205 reason = 'connected_to_hidden';
51207 return action.disabled(context.graph()) || reason;
51211 operation.tooltip = function() {
51212 var disable = operation.disabled();
51214 t('operations.circularize.' + disable) :
51215 t('operations.circularize.description.' + geometry);
51219 operation.id = 'circularize';
51220 operation.keys = [t('operations.circularize.key')];
51221 operation.title = t('operations.circularize.title');
51222 operation.behavior = behaviorOperation(context).which(operation);
51227 function operationContinue(selectedIDs, context) {
51228 var graph = context.graph(),
51229 entities = selectedIDs.map(function(id) { return graph.entity(id); }),
51230 geometries = lodash.extend({ line: [], vertex: [] },
51231 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); })),
51232 vertex = geometries.vertex[0];
51235 function candidateWays() {
51236 return graph.parentWays(vertex).filter(function(parent) {
51237 return parent.geometry(graph) === 'line' &&
51238 !parent.isClosed() &&
51239 parent.affix(vertex.id) &&
51240 (geometries.line.length === 0 || geometries.line[0] === parent);
51245 var operation = function() {
51246 var candidate = candidateWays()[0];
51248 modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
51253 operation.available = function() {
51254 return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
51255 !context.features().hasHiddenConnections(vertex, context.graph());
51259 operation.disabled = function() {
51260 var candidates = candidateWays();
51261 if (candidates.length === 0)
51262 return 'not_eligible';
51263 if (candidates.length > 1)
51268 operation.tooltip = function() {
51269 var disable = operation.disabled();
51271 t('operations.continue.' + disable) :
51272 t('operations.continue.description');
51276 operation.id = 'continue';
51277 operation.keys = [t('operations.continue.key')];
51278 operation.title = t('operations.continue.title');
51279 operation.behavior = behaviorOperation(context).which(operation);
51284 function operationDelete(selectedIDs, context) {
51285 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51286 action = actionDeleteMultiple(selectedIDs);
51289 var operation = function() {
51293 if (selectedIDs.length > 1) {
51294 annotation = t('operations.delete.annotation.multiple', { n: selectedIDs.length });
51297 var id = selectedIDs[0],
51298 entity = context.entity(id),
51299 geometry = context.geometry(id),
51300 parents = context.graph().parentWays(entity),
51301 parent = parents[0];
51303 annotation = t('operations.delete.annotation.' + geometry);
51305 // Select the next closest node in the way.
51306 if (geometry === 'vertex' && parent.nodes.length > 2) {
51307 var nodes = parent.nodes,
51308 i = nodes.indexOf(id);
51312 } else if (i === nodes.length - 1) {
51315 var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
51316 b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
51317 i = a < b ? i - 1 : i + 1;
51320 nextSelectedID = nodes[i];
51324 context.perform(action, annotation);
51326 if (nextSelectedID && context.hasEntity(nextSelectedID)) {
51328 modeSelect(context, [nextSelectedID]).follow(true).suppressMenu(true)
51331 context.enter(modeBrowse(context));
51337 operation.available = function() {
51342 operation.disabled = function() {
51344 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51345 reason = 'connected_to_hidden';
51346 } else if (lodash.some(selectedIDs, protectedMember)) {
51347 reason = 'part_of_relation';
51348 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51349 reason = 'incomplete_relation';
51353 function incompleteRelation(id) {
51354 var entity = context.entity(id);
51355 return entity.type === 'relation' && !entity.isComplete(context.graph());
51358 function protectedMember(id) {
51359 var entity = context.entity(id);
51360 if (entity.type !== 'way') return false;
51362 var parents = context.graph().parentRelations(entity);
51363 for (var i = 0; i < parents.length; i++) {
51364 var parent = parents[i],
51365 type = parent.tags.type,
51366 role = parent.memberById(id).role || 'outer';
51367 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
51377 operation.tooltip = function() {
51378 var disable = operation.disabled();
51380 t('operations.delete.' + disable + '.' + multi) :
51381 t('operations.delete.description' + '.' + multi);
51385 operation.id = 'delete';
51386 operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
51387 operation.title = t('operations.delete.title');
51388 operation.behavior = behaviorOperation(context).which(operation);
51393 function operationDisconnect(selectedIDs, context) {
51394 var vertices = lodash.filter(selectedIDs, function(entityId) {
51395 return context.geometry(entityId) === 'vertex';
51398 var entityId = vertices[0],
51399 action = actionDisconnect(entityId);
51401 if (selectedIDs.length > 1) {
51402 action.limitWays(lodash.without(selectedIDs, entityId));
51406 var operation = function() {
51407 context.perform(action, t('operations.disconnect.annotation'));
51411 operation.available = function() {
51412 return vertices.length === 1;
51416 operation.disabled = function() {
51418 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51419 reason = 'connected_to_hidden';
51421 return action.disabled(context.graph()) || reason;
51425 operation.tooltip = function() {
51426 var disable = operation.disabled();
51428 t('operations.disconnect.' + disable) :
51429 t('operations.disconnect.description');
51433 operation.id = 'disconnect';
51434 operation.keys = [t('operations.disconnect.key')];
51435 operation.title = t('operations.disconnect.title');
51436 operation.behavior = behaviorOperation(context).which(operation);
51441 function operationMerge(selectedIDs, context) {
51442 var join = actionJoin(selectedIDs),
51443 merge = actionMerge(selectedIDs),
51444 mergePolygon = actionMergePolygon(selectedIDs);
51446 var operation = function() {
51447 var annotation = t('operations.merge.annotation', {n: selectedIDs.length}),
51450 if (!join.disabled(context.graph())) {
51452 } else if (!merge.disabled(context.graph())) {
51455 action = mergePolygon;
51458 context.perform(action, annotation);
51459 var ids = selectedIDs.filter(function(id) {
51460 var entity = context.hasEntity(id);
51461 return entity && entity.type !== 'node';
51463 context.enter(modeSelect(context, ids).suppressMenu(true));
51467 operation.available = function() {
51468 return selectedIDs.length >= 2;
51472 operation.disabled = function() {
51473 return join.disabled(context.graph()) &&
51474 merge.disabled(context.graph()) &&
51475 mergePolygon.disabled(context.graph());
51479 operation.tooltip = function() {
51480 var j = join.disabled(context.graph()),
51481 m = merge.disabled(context.graph()),
51482 p = mergePolygon.disabled(context.graph());
51484 if (j === 'restriction' && m && p) {
51485 return t('operations.merge.restriction',
51486 { relation: context.presets().item('type/restriction').name() });
51489 if (p === 'incomplete_relation' && j && m) {
51490 return t('operations.merge.incomplete_relation');
51494 return t('operations.merge.' + j);
51497 return t('operations.merge.description');
51501 operation.id = 'merge';
51502 operation.keys = [t('operations.merge.key')];
51503 operation.title = t('operations.merge.title');
51504 operation.behavior = behaviorOperation(context).which(operation);
51509 function operationMove(selectedIDs, context) {
51510 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51511 extent = selectedIDs.reduce(function(extent, id) {
51512 return extent.extend(context.entity(id).extent(context.graph()));
51513 }, geoExtent$$1());
51516 var operation = function() {
51517 context.enter(modeMove$$1(context, selectedIDs));
51521 operation.available = function() {
51522 return selectedIDs.length > 1 ||
51523 context.entity(selectedIDs[0]).type !== 'node';
51527 operation.disabled = function() {
51529 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51530 reason = 'too_large';
51531 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51532 reason = 'connected_to_hidden';
51533 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51534 reason = 'incomplete_relation';
51538 function incompleteRelation(id) {
51539 var entity = context.entity(id);
51540 return entity.type === 'relation' && !entity.isComplete(context.graph());
51545 operation.tooltip = function() {
51546 var disable = operation.disabled();
51548 t('operations.move.' + disable + '.' + multi) :
51549 t('operations.move.description.' + multi);
51553 operation.id = 'move';
51554 operation.keys = [t('operations.move.key')];
51555 operation.title = t('operations.move.title');
51556 operation.behavior = behaviorOperation(context).which(operation);
51561 function operationOrthogonalize(selectedIDs, context) {
51562 var entityId = selectedIDs[0],
51563 entity = context.entity(entityId),
51564 extent = entity.extent(context.graph()),
51565 geometry = context.geometry(entityId),
51566 action = actionOrthogonalize(entityId, context.projection);
51569 var operation = function() {
51570 context.perform(action, t('operations.orthogonalize.annotation.' + geometry));
51574 operation.available = function() {
51575 return selectedIDs.length === 1 &&
51576 entity.type === 'way' &&
51577 entity.isClosed() &&
51578 lodash.uniq(entity.nodes).length > 2;
51582 operation.disabled = function() {
51584 if (extent.percentContainedIn(context.extent()) < 0.8) {
51585 reason = 'too_large';
51586 } else if (context.hasHiddenConnections(entityId)) {
51587 reason = 'connected_to_hidden';
51589 return action.disabled(context.graph()) || reason;
51593 operation.tooltip = function() {
51594 var disable = operation.disabled();
51596 t('operations.orthogonalize.' + disable) :
51597 t('operations.orthogonalize.description.' + geometry);
51601 operation.id = 'orthogonalize';
51602 operation.keys = [t('operations.orthogonalize.key')];
51603 operation.title = t('operations.orthogonalize.title');
51604 operation.behavior = behaviorOperation(context).which(operation);
51609 function operationReflectShort(selectedIDs, context) {
51610 return operationReflect(selectedIDs, context, 'short');
51614 function operationReflectLong(selectedIDs, context) {
51615 return operationReflect(selectedIDs, context, 'long');
51619 function operationReflect(selectedIDs, context, axis) {
51620 axis = axis || 'long';
51621 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51622 extent = selectedIDs.reduce(function(extent, id) {
51623 return extent.extend(context.entity(id).extent(context.graph()));
51624 }, geoExtent$$1());
51627 var operation = function() {
51628 var action = actionReflect(selectedIDs, context.projection)
51629 .useLongAxis(Boolean(axis === 'long'));
51630 context.perform(action, t('operations.reflect.annotation.' + axis + '.' + multi));
51634 operation.available = function() {
51635 return lodash.some(selectedIDs, hasArea);
51637 function hasArea(id) {
51638 var entity = context.entity(id);
51639 return (entity.type === 'way' && entity.isClosed()) ||
51640 (entity.type ==='relation' && entity.isMultipolygon());
51645 operation.disabled = function() {
51647 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51648 reason = 'too_large';
51649 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51650 reason = 'connected_to_hidden';
51651 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51652 reason = 'incomplete_relation';
51656 function incompleteRelation(id) {
51657 var entity = context.entity(id);
51658 return entity.type === 'relation' && !entity.isComplete(context.graph());
51663 operation.tooltip = function() {
51664 var disable = operation.disabled();
51666 t('operations.reflect.' + disable + '.' + multi) :
51667 t('operations.reflect.description.' + axis + '.' + multi);
51671 operation.id = 'reflect-' + axis;
51672 operation.keys = [t('operations.reflect.key.' + axis)];
51673 operation.title = t('operations.reflect.title');
51674 operation.behavior = behaviorOperation(context).which(operation);
51679 function operationReverse(selectedIDs, context) {
51680 var entityId = selectedIDs[0];
51682 var operation = function() {
51683 context.perform(actionReverse(entityId), t('operations.reverse.annotation'));
51687 operation.available = function() {
51688 return selectedIDs.length === 1 && context.geometry(entityId) === 'line';
51692 operation.disabled = function() {
51697 operation.tooltip = function() {
51698 return t('operations.reverse.description');
51702 operation.id = 'reverse';
51703 operation.keys = [t('operations.reverse.key')];
51704 operation.title = t('operations.reverse.title');
51705 operation.behavior = behaviorOperation(context).which(operation);
51710 function operationRotate(selectedIDs, context) {
51711 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51712 extent = selectedIDs.reduce(function(extent, id) {
51713 return extent.extend(context.entity(id).extent(context.graph()));
51714 }, geoExtent$$1());
51717 var operation = function() {
51718 context.enter(modeRotate$$1(context, selectedIDs));
51722 operation.available = function() {
51723 return lodash.some(selectedIDs, hasArea);
51725 function hasArea(id) {
51726 var entity = context.entity(id);
51727 return (entity.type === 'way' && entity.isClosed()) ||
51728 (entity.type ==='relation' && entity.isMultipolygon());
51733 operation.disabled = function() {
51735 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51736 reason = 'too_large';
51737 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51738 reason = 'connected_to_hidden';
51739 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51740 reason = 'incomplete_relation';
51744 function incompleteRelation(id) {
51745 var entity = context.entity(id);
51746 return entity.type === 'relation' && !entity.isComplete(context.graph());
51751 operation.tooltip = function() {
51752 var disable = operation.disabled();
51754 t('operations.rotate.' + disable + '.' + multi) :
51755 t('operations.rotate.description.' + multi);
51759 operation.id = 'rotate';
51760 operation.keys = [t('operations.rotate.key')];
51761 operation.title = t('operations.rotate.title');
51762 operation.behavior = behaviorOperation(context).which(operation);
51767 function operationSplit(selectedIDs, context) {
51768 var vertices = lodash.filter(selectedIDs, function(entityId) {
51769 return context.geometry(entityId) === 'vertex';
51772 var entityId = vertices[0],
51773 action = actionSplit(entityId);
51775 if (selectedIDs.length > 1) {
51776 action.limitWays(lodash.without(selectedIDs, entityId));
51780 var operation = function() {
51783 var ways = action.ways(context.graph());
51784 if (ways.length === 1) {
51785 annotation = t('operations.split.annotation.' + context.geometry(ways[0].id));
51787 annotation = t('operations.split.annotation.multiple', {n: ways.length});
51790 var difference = context.perform(action, annotation);
51791 context.enter(modeSelect(context, difference.extantIDs()));
51795 operation.available = function() {
51796 return vertices.length === 1;
51800 operation.disabled = function() {
51802 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51803 reason = 'connected_to_hidden';
51805 return action.disabled(context.graph()) || reason;
51809 operation.tooltip = function() {
51810 var disable = operation.disabled();
51812 return t('operations.split.' + disable);
51815 var ways = action.ways(context.graph());
51816 if (ways.length === 1) {
51817 return t('operations.split.description.' + context.geometry(ways[0].id));
51819 return t('operations.split.description.multiple');
51824 operation.id = 'split';
51825 operation.keys = [t('operations.split.key')];
51826 operation.title = t('operations.split.title');
51827 operation.behavior = behaviorOperation(context).which(operation);
51832 function operationStraighten(selectedIDs, context) {
51833 var entityId = selectedIDs[0],
51834 action = actionStraighten(entityId, context.projection);
51837 function operation() {
51838 context.perform(action, t('operations.straighten.annotation'));
51842 operation.available = function() {
51843 var entity = context.entity(entityId);
51844 return selectedIDs.length === 1 &&
51845 entity.type === 'way' &&
51846 !entity.isClosed() &&
51847 lodash.uniq(entity.nodes).length > 2;
51851 operation.disabled = function() {
51853 if (context.hasHiddenConnections(entityId)) {
51854 reason = 'connected_to_hidden';
51856 return action.disabled(context.graph()) || reason;
51860 operation.tooltip = function() {
51861 var disable = operation.disabled();
51863 t('operations.straighten.' + disable) :
51864 t('operations.straighten.description');
51868 operation.id = 'straighten';
51869 operation.keys = [t('operations.straighten.key')];
51870 operation.title = t('operations.straighten.title');
51871 operation.behavior = behaviorOperation(context).which(operation);
51878 var Operations = Object.freeze({
51879 operationCircularize: operationCircularize,
51880 operationContinue: operationContinue,
51881 operationDelete: operationDelete,
51882 operationDisconnect: operationDisconnect,
51883 operationMerge: operationMerge,
51884 operationMove: operationMove,
51885 operationOrthogonalize: operationOrthogonalize,
51886 operationReflectShort: operationReflectShort,
51887 operationReflectLong: operationReflectLong,
51888 operationReverse: operationReverse,
51889 operationRotate: operationRotate,
51890 operationSplit: operationSplit,
51891 operationStraighten: operationStraighten
51894 function modeMove$$1(context, entityIDs, baseGraph) {
51900 var keybinding = d3keybinding('move'),
51902 behaviorEdit(context),
51903 operationCircularize(entityIDs, context).behavior,
51904 operationDelete(entityIDs, context).behavior,
51905 operationOrthogonalize(entityIDs, context).behavior,
51906 operationReflectLong(entityIDs, context).behavior,
51907 operationReflectShort(entityIDs, context).behavior,
51908 operationRotate(entityIDs, context).behavior
51910 annotation = entityIDs.length === 1 ?
51911 t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
51912 t('operations.move.annotation.multiple'),
51919 function vecSub(a, b) {
51920 return [a[0] - b[0], a[1] - b[1]];
51924 function edge(point, size) {
51925 var pad = [30, 100, 30, 100],
51929 if (point[0] > size[0] - pad[0])
51931 if (point[0] < pad[2])
51933 if (point[1] > size[1] - pad[1])
51935 if (point[1] < pad[3])
51938 if (x || y) return [x, y];
51943 function doMove(nudge) {
51944 nudge = nudge || [0, 0];
51947 if (prevGraph !== context.graph()) {
51949 origin = context.map().mouseCoordinates();
51950 fn = context.perform;
51952 fn = context.overwrite;
51955 var currMouse = context.mouse(),
51956 origMouse = context.projection(origin),
51957 delta = vecSub(vecSub(currMouse, origMouse), nudge);
51959 fn(actionMove(entityIDs, delta, context.projection, cache), annotation);
51960 prevGraph = context.graph();
51964 function startNudge(nudge) {
51965 if (nudgeInterval) window.clearInterval(nudgeInterval);
51966 nudgeInterval = window.setInterval(function() {
51967 context.pan(nudge);
51973 function stopNudge() {
51974 if (nudgeInterval) window.clearInterval(nudgeInterval);
51975 nudgeInterval = null;
51981 var nudge = edge(context.mouse(), context.map().dimensions());
51982 if (nudge) startNudge(nudge);
51987 function finish() {
51988 event.stopPropagation();
51989 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
51994 function cancel() {
51996 while (context.graph() !== baseGraph) context.pop();
51997 context.enter(modeBrowse(context));
52000 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
52006 function undone() {
52007 context.enter(modeBrowse(context));
52011 mode.enter = function() {
52012 origin = context.map().mouseCoordinates();
52016 behaviors.forEach(function(behavior) {
52017 context.install(behavior);
52021 .on('mousemove.move', move)
52022 .on('click.move', finish);
52025 .on('undone.move', undone);
52036 mode.exit = function() {
52039 behaviors.forEach(function(behavior) {
52040 context.uninstall(behavior);
52044 .on('mousemove.move', null)
52045 .on('click.move', null);
52048 .on('undone.move', null);
52057 function modeRotate$$1(context, entityIDs) {
52063 var keybinding = d3keybinding('rotate'),
52065 behaviorEdit(context),
52066 operationCircularize(entityIDs, context).behavior,
52067 operationDelete(entityIDs, context).behavior,
52068 operationMove(entityIDs, context).behavior,
52069 operationOrthogonalize(entityIDs, context).behavior,
52070 operationReflectLong(entityIDs, context).behavior,
52071 operationReflectShort(entityIDs, context).behavior
52073 annotation = entityIDs.length === 1 ?
52074 t('operations.rotate.annotation.' + context.geometry(entityIDs[0])) :
52075 t('operations.rotate.annotation.multiple'),
52082 function doRotate() {
52084 if (context.graph() !== prevGraph) {
52085 fn = context.perform;
52087 fn = context.replace;
52090 // projection changed, recalculate pivot
52091 var projection = context.projection;
52092 var currTransform = projection.transform();
52093 if (!prevTransform ||
52094 currTransform.k !== prevTransform.k ||
52095 currTransform.x !== prevTransform.x ||
52096 currTransform.y !== prevTransform.y) {
52098 var nodes = utilGetAllNodes(entityIDs, context.graph()),
52099 points = nodes.map(function(n) { return projection(n.loc); });
52101 pivot = d3polygonCentroid(d3polygonHull(points));
52102 prevAngle = undefined;
52106 var currMouse = context.mouse(),
52107 currAngle = Math.atan2(currMouse[1] - pivot[1], currMouse[0] - pivot[0]);
52109 if (typeof prevAngle === 'undefined') prevAngle = currAngle;
52110 var delta = currAngle - prevAngle;
52112 fn(actionRotate(entityIDs, pivot, delta, projection), annotation);
52114 prevTransform = currTransform;
52115 prevAngle = currAngle;
52116 prevGraph = context.graph();
52120 function finish() {
52121 event.stopPropagation();
52122 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
52126 function cancel() {
52128 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
52132 function undone() {
52133 context.enter(modeBrowse(context));
52137 mode.enter = function() {
52138 behaviors.forEach(function(behavior) {
52139 context.install(behavior);
52143 .on('mousemove.rotate', doRotate)
52144 .on('click.rotate', finish);
52147 .on('undone.rotate', undone);
52158 mode.exit = function() {
52159 behaviors.forEach(function(behavior) {
52160 context.uninstall(behavior);
52164 .on('mousemove.rotate', null)
52165 .on('click.rotate', null);
52168 .on('undone.rotate', null);
52177 function modeSave$$1(context) {
52182 var ui = uiCommit(context)
52183 .on('cancel', cancel)
52187 function cancel() {
52188 context.enter(modeBrowse(context));
52192 function save(e, tryAgain) {
52193 function withChildNodes(ids, graph) {
52194 return lodash.uniq(lodash.reduce(ids, function(result, id) {
52195 var e = graph.entity(id);
52196 if (e.type === 'way') {
52198 var cn = graph.childNodes(e);
52199 result.push.apply(result, lodash.map(lodash.filter(cn, 'version'), 'id'));
52201 /* eslint-disable no-console */
52202 if (typeof console !== 'undefined') console.error(err);
52203 /* eslint-enable no-console */
52207 }, lodash.clone(ids)));
52210 var loading = uiLoading(context).message(t('save.uploading')).blocking(true),
52211 history = context.history(),
52212 origChanges = history.changes(actionDiscardTags(history.difference())),
52213 localGraph = context.graph(),
52214 remoteGraph = coreGraph$$1(history.base(), true),
52215 modified = lodash.filter(history.difference().summary(), {changeType: 'modified'}),
52216 toCheck = lodash.map(lodash.map(modified, 'entity'), 'id'),
52217 toLoad = withChildNodes(toCheck, localGraph),
52221 if (!tryAgain) history.perform(actionNoop()); // checkpoint
52222 context.container().call(loading);
52224 if (toCheck.length) {
52225 context.connection().loadMultiple(toLoad, loaded);
52231 // Reload modified entities into an alternate graph and check for conflicts..
52232 function loaded(err, result) {
52233 if (errors.length) return;
52237 msg: err.responseText,
52238 details: [ t('save.status_code', { code: err.status }) ]
52244 lodash.each(result.data, function(entity) {
52245 remoteGraph.replace(entity);
52246 toLoad = lodash.without(toLoad, entity.id);
52248 // Because loadMultiple doesn't download /full like loadEntity,
52249 // need to also load children that aren't already being checked..
52250 if (!entity.visible) return;
52251 if (entity.type === 'way') {
52252 loadMore.push.apply(loadMore,
52253 lodash.difference(entity.nodes, toCheck, toLoad, loadMore));
52254 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
52255 loadMore.push.apply(loadMore,
52256 lodash.difference(lodash.map(entity.members, 'id'), toCheck, toLoad, loadMore));
52260 if (loadMore.length) {
52261 toLoad.push.apply(toLoad, loadMore);
52262 context.connection().loadMultiple(loadMore, loaded);
52265 if (!toLoad.length) {
52272 function checkConflicts() {
52273 function choice(id, text$$1, action) {
52274 return { id: id, text: text$$1, action: function() { history.replace(action); } };
52276 function formatUser(d) {
52277 return '<a href="' + context.connection().userURL(d) + '" target="_blank">' + d + '</a>';
52279 function entityName(entity) {
52280 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
52283 function compareVersions(local$$1, remote) {
52284 if (local$$1.version !== remote.version) return false;
52286 if (local$$1.type === 'way') {
52287 var children = lodash.union(local$$1.nodes, remote.nodes);
52289 for (var i = 0; i < children.length; i++) {
52290 var a = localGraph.hasEntity(children[i]),
52291 b = remoteGraph.hasEntity(children[i]);
52293 if (a && b && a.version !== b.version) return false;
52300 lodash.each(toCheck, function(id) {
52301 var local$$1 = localGraph.entity(id),
52302 remote = remoteGraph.entity(id);
52304 if (compareVersions(local$$1, remote)) return;
52306 var action = actionMergeRemoteChanges,
52307 merge$$1 = action(id, localGraph, remoteGraph, formatUser);
52309 history.replace(merge$$1);
52311 var mergeConflicts = merge$$1.conflicts();
52312 if (!mergeConflicts.length) return; // merged safely
52314 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
52315 forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote'),
52316 keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore')),
52317 keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
52321 name: entityName(local$$1),
52322 details: mergeConflicts,
52325 choice(id, keepMine, forceLocal),
52326 choice(id, keepTheirs, forceRemote)
52335 function finalize() {
52336 if (conflicts.length) {
52337 conflicts.sort(function(a,b) { return b.id.localeCompare(a.id); });
52339 } else if (errors.length) {
52342 var changes = history.changes(actionDiscardTags(history.difference()));
52343 if (changes.modified.length || changes.created.length || changes.deleted.length) {
52344 context.connection().putChangeset(
52348 history.imageryUsed(),
52349 function(err, changeset_id) {
52352 msg: err.responseText,
52353 details: [ t('save.status_code', { code: err.status }) ]
52357 history.clearSaved();
52358 success(e, changeset_id);
52359 // Add delay to allow for postgres replication #1646 #2678
52360 window.setTimeout(function() {
52366 } else { // changes were insignificant or reverted by user
52375 function showConflicts() {
52376 var selection$$1 = context.container()
52377 .select('#sidebar')
52379 .attr('class','sidebar-component');
52383 selection$$1.call(uiConflicts(context)
52385 .on('download', function() {
52386 var data = JXON.stringify(context.connection().osmChangeJXON('CHANGEME', origChanges)),
52387 win = window.open('data:text/xml,' + encodeURIComponent(data), '_blank');
52390 .on('cancel', function() {
52392 selection$$1.remove();
52394 .on('save', function() {
52395 for (var i = 0; i < conflicts.length; i++) {
52396 if (conflicts[i].chosen === 1) { // user chose "keep theirs"
52397 var entity = context.hasEntity(conflicts[i].id);
52398 if (entity && entity.type === 'way') {
52399 var children = lodash.uniq(entity.nodes);
52400 for (var j = 0; j < children.length; j++) {
52401 history.replace(actionRevert(children[j]));
52404 history.replace(actionRevert(conflicts[i].id));
52408 selection$$1.remove();
52415 function showErrors() {
52416 var selection$$1 = uiConfirm(context.container());
52422 .select('.modal-section.header')
52424 .text(t('save.error'));
52426 addErrors(selection$$1, errors);
52427 selection$$1.okButton();
52431 function addErrors(selection$$1, data) {
52432 var message = selection$$1
52433 .select('.modal-section.message-text');
52435 var items = message
52436 .selectAll('.error-container')
52439 var enter = items.enter()
52441 .attr('class', 'error-container');
52445 .attr('class', 'error-description')
52447 .classed('hide-toggle', true)
52448 .text(function(d) { return d.msg || t('save.unknown_error_details'); })
52449 .on('click', function() {
52450 var error = select(this),
52451 detail = select(this.nextElementSibling),
52452 exp = error.classed('expanded');
52454 detail.style('display', exp ? 'none' : 'block');
52455 error.classed('expanded', !exp);
52457 event.preventDefault();
52460 var details = enter
52462 .attr('class', 'error-detail-container')
52463 .style('display', 'none');
52467 .attr('class', 'error-detail-list')
52469 .data(function(d) { return d.details || []; })
52472 .attr('class', 'error-detail-item')
52473 .text(function(d) { return d; });
52482 function success(e, changeset_id) {
52483 context.enter(modeBrowse(context)
52484 .sidebar(uiSuccess(context)
52489 .on('cancel', function() {
52490 context.ui().sidebar.hide();
52497 mode.enter = function() {
52499 context.ui().sidebar.show(ui);
52502 context.container().selectAll('#content')
52503 .attr('class', 'inactive');
52505 if (context.connection().authenticated()) {
52508 context.connection().authenticate(function(err) {
52519 mode.exit = function() {
52520 context.container().selectAll('#content')
52521 .attr('class', 'active');
52523 context.ui().sidebar.hide();
52529 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
52530 // For example, ⌘Z -> Ctrl+Z
52531 function uiCmd(code) {
52532 var detected = utilDetect();
52534 if (detected.os === 'mac') {
52538 if (detected.os === 'win') {
52539 if (code === '⌘⇧Z') return 'Ctrl+Y';
52551 for (var i = 0; i < code.length; i++) {
52552 if (code[i] in replacements) {
52553 result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
52565 function modeSelect(context, selectedIDs) {
52571 var keybinding = d3keybinding('select'),
52574 behaviorCopy(context),
52575 behaviorPaste(context),
52576 behaviorBreathe(context),
52577 behaviorHover(context),
52578 behaviorSelect(context),
52579 behaviorLasso(context),
52580 modeDragNode$$1(context).selectedIDs(selectedIDs).behavior
52584 newFeature = false,
52585 suppressMenu = false,
52589 var wrap = context.container()
52590 .select('.inspector-wrap');
52593 function singular() {
52594 if (selectedIDs.length === 1) {
52595 return context.hasEntity(selectedIDs[0]);
52600 function checkSelectedIDs() {
52602 if (Array.isArray(selectedIDs)) {
52603 ids = selectedIDs.filter(function(id) {
52604 return context.hasEntity(id);
52611 context.enter(modeBrowse(context));
52613 return !!ids.length;
52617 // find the common parent ways for nextVertex, previousVertex
52618 function commonParents() {
52619 var graph = context.graph(),
52620 commonParents = [];
52622 for (var i = 0; i < selectedIDs.length; i++) {
52623 var entity = context.hasEntity(selectedIDs[i]);
52624 if (!entity || entity.geometry(graph) !== 'vertex') {
52625 return []; // selection includes some not vertexes
52628 var currParents = lodash.map(graph.parentWays(entity), 'id');
52629 if (!commonParents.length) {
52630 commonParents = currParents;
52634 commonParents = lodash.intersection(commonParents, currParents);
52635 if (!commonParents.length) {
52640 return commonParents;
52644 function singularParent() {
52645 var parents = commonParents();
52646 if (!parents || parents.length === 0) {
52647 relatedParent = null;
52651 // relatedParent is used when we visit a vertex with multiple
52652 // parents, and we want to remember which parent line we started on.
52654 if (parents.length === 1) {
52655 relatedParent = parents[0]; // remember this parent for later
52656 return relatedParent;
52659 if (parents.indexOf(relatedParent) !== -1) {
52660 return relatedParent; // prefer the previously seen parent
52667 function closeMenu() {
52669 context.surface().call(radialMenu.close);
52674 function positionMenu() {
52675 if (suppressMenu || !radialMenu) { return; }
52677 var entity = singular();
52678 if (entity && context.geometry(entity.id) === 'relation') {
52679 suppressMenu = true;
52680 } else if (entity && entity.type === 'node') {
52681 radialMenu.center(context.projection(entity.loc));
52683 var point = context.mouse(),
52684 viewport = geoExtent$$1(context.projection.clipExtent()).polygon();
52685 if (geoPointInPolygon(point, viewport)) {
52686 radialMenu.center(point);
52688 suppressMenu = true;
52694 function showMenu() {
52696 if (!suppressMenu && radialMenu) {
52697 context.surface().call(radialMenu);
52702 function toggleMenu() {
52703 if (select('.radial-menu').empty()) {
52711 mode.selectedIDs = function() {
52712 return selectedIDs;
52716 mode.reselect = function() {
52717 if (!checkSelectedIDs()) return;
52719 var surfaceNode = context.surface().node();
52720 if (surfaceNode.focus) { // FF doesn't support it
52721 surfaceNode.focus();
52729 mode.newFeature = function(_) {
52730 if (!arguments.length) return newFeature;
52736 mode.suppressMenu = function(_) {
52737 if (!arguments.length) return suppressMenu;
52743 mode.follow = function(_) {
52744 if (!arguments.length) return follow;
52750 mode.enter = function() {
52752 function update() {
52754 checkSelectedIDs();
52758 function dblclick() {
52759 var target = select(event.target),
52760 datum = target.datum();
52762 if (datum instanceof osmWay && !target.classed('fill')) {
52763 var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
52764 prev = datum.nodes[choice.index - 1],
52765 next = datum.nodes[choice.index];
52768 actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
52769 t('operations.add.annotation.vertex')
52772 event.preventDefault();
52773 event.stopPropagation();
52774 } else if (datum.type === 'midpoint') {
52776 actionAddMidpoint({loc: datum.loc, edge: datum.edge}, osmNode()),
52777 t('operations.add.annotation.vertex'));
52779 event.preventDefault();
52780 event.stopPropagation();
52785 function selectElements(drawn) {
52786 if (!checkSelectedIDs()) return;
52788 var surface = context.surface(),
52789 entity = singular();
52791 if (entity && context.geometry(entity.id) === 'relation') {
52792 suppressMenu = true;
52796 surface.selectAll('.related')
52797 .classed('related', false);
52800 if (relatedParent) {
52801 surface.selectAll(utilEntitySelector([relatedParent]))
52802 .classed('related', true);
52805 var selection$$1 = context.surface()
52806 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
52808 if (selection$$1.empty()) {
52809 // Return to browse mode if selected DOM elements have
52810 // disappeared because the user moved them out of view..
52811 var source = event && event.type === 'zoom' && event.sourceEvent;
52812 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
52813 context.enter(modeBrowse(context));
52817 .classed('selected', true);
52823 if (!context.inIntro()) {
52824 context.enter(modeBrowse(context));
52829 function firstVertex() {
52830 event.preventDefault();
52831 var parent = singularParent();
52833 var way = context.entity(parent);
52835 modeSelect(context, [way.first()]).follow(true).suppressMenu(true)
52841 function lastVertex() {
52842 event.preventDefault();
52843 var parent = singularParent();
52845 var way = context.entity(parent);
52847 modeSelect(context, [way.last()]).follow(true).suppressMenu(true)
52853 function previousVertex() {
52854 event.preventDefault();
52855 var parent = singularParent();
52856 if (!parent) return;
52858 var way = context.entity(parent),
52859 length = way.nodes.length,
52860 curr = way.nodes.indexOf(selectedIDs[0]),
52865 } else if (way.isClosed()) {
52866 index = length - 2;
52869 if (index !== -1) {
52871 modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
52877 function nextVertex() {
52878 event.preventDefault();
52879 var parent = singularParent();
52880 if (!parent) return;
52882 var way = context.entity(parent),
52883 length = way.nodes.length,
52884 curr = way.nodes.indexOf(selectedIDs[0]),
52887 if (curr < length - 1) {
52889 } else if (way.isClosed()) {
52893 if (index !== -1) {
52895 modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
52901 function nextParent() {
52902 event.preventDefault();
52903 var parents = lodash.uniq(commonParents());
52904 if (!parents || parents.length < 2) return;
52906 var index = parents.indexOf(relatedParent);
52907 if (index < 0 || index > parents.length - 2) {
52908 relatedParent = parents[0];
52910 relatedParent = parents[index + 1];
52913 var surface = context.surface();
52914 surface.selectAll('.related')
52915 .classed('related', false);
52917 if (relatedParent) {
52918 surface.selectAll(utilEntitySelector([relatedParent]))
52919 .classed('related', true);
52924 if (!checkSelectedIDs()) return;
52926 var operations = lodash.without(values(Operations), operationDelete)
52927 .map(function(o) { return o(selectedIDs, context); })
52928 .filter(function(o) { return o.available(); });
52930 operations.unshift(operationDelete(selectedIDs, context));
52932 operations.forEach(function(operation) {
52933 if (operation.behavior) {
52934 behaviors.push(operation.behavior);
52938 behaviors.forEach(function(behavior) {
52939 context.install(behavior);
52943 .on(['[','pgup'], previousVertex)
52944 .on([']', 'pgdown'], nextVertex)
52945 .on([uiCmd('⌘['), 'home'], firstVertex)
52946 .on([uiCmd('⌘]'), 'end'], lastVertex)
52947 .on(['\\', 'pause'], nextParent)
52948 .on('⎋', esc, true)
52949 .on('space', toggleMenu);
52954 radialMenu = uiRadialMenu(context, operations);
52956 context.ui().sidebar
52957 .select(singular() ? singular().id : null, newFeature);
52960 .on('undone.select', update)
52961 .on('redone.select', update);
52964 .on('move.select', closeMenu)
52965 .on('drawn.select', selectElements);
52969 var show = event && !suppressMenu;
52976 var extent$$1 = geoExtent$$1(),
52977 graph = context.graph();
52978 selectedIDs.forEach(function(id) {
52979 var entity = context.entity(id);
52980 extent$$1._extend(entity.extent(graph));
52983 var loc = extent$$1.center();
52984 context.map().centerEase(loc);
52987 timeout$$1 = window.setTimeout(function() {
52993 .on('dblclick.select', dblclick);
52996 if (selectedIDs.length > 1) {
52997 var entities = uiSelectionList(context, selectedIDs);
52998 context.ui().sidebar.show(entities);
53003 mode.exit = function() {
53004 if (timeout$$1) window.clearTimeout(timeout$$1);
53006 if (inspector) wrap.call(inspector.close);
53008 behaviors.forEach(function(behavior) {
53009 context.uninstall(behavior);
53014 radialMenu = undefined;
53017 .on('undone.select', null)
53018 .on('redone.select', null);
53020 var surface = context.surface();
53023 .on('dblclick.select', null);
53026 .selectAll('.selected')
53027 .classed('selected', false);
53030 .selectAll('.related')
53031 .classed('related', false);
53033 context.map().on('drawn.select', null);
53034 context.ui().sidebar.hide();
53041 function uiAccount(context) {
53042 var connection = context.connection();
53045 function update(selection$$1) {
53046 if (!connection.authenticated()) {
53047 selection$$1.selectAll('#userLink, #logoutLink')
53048 .classed('hide', true);
53052 connection.userDetails(function(err, details) {
53053 var userLink = selection$$1.select('#userLink'),
53054 logoutLink = selection$$1.select('#logoutLink');
53057 logoutLink.html('');
53061 selection$$1.selectAll('#userLink, #logoutLink')
53062 .classed('hide', false);
53065 userLink.append('a')
53066 .attr('href', connection.userURL(details.display_name))
53067 .attr('target', '_blank');
53069 // Add thumbnail or dont
53070 if (details.image_url) {
53071 userLink.append('img')
53072 .attr('class', 'icon pre-text user-icon')
53073 .attr('src', details.image_url);
53076 .call(svgIcon('#icon-avatar', 'pre-text light'));
53080 userLink.append('span')
53081 .attr('class', 'label')
53082 .text(details.display_name);
53084 logoutLink.append('a')
53085 .attr('class', 'logout')
53088 .on('click.logout', function() {
53089 event.preventDefault();
53090 connection.logout();
53096 return function(selection$$1) {
53097 selection$$1.append('li')
53098 .attr('id', 'logoutLink')
53099 .classed('hide', true);
53101 selection$$1.append('li')
53102 .attr('id', 'userLink')
53103 .classed('hide', true);
53106 .on('change.account', function() { update(selection$$1); });
53108 update(selection$$1);
53112 function uiAttribution(context) {
53116 function attribution(data, klass) {
53117 var div = selection$$1.selectAll('.' + klass)
53122 .attr('class', klass)
53126 var background = div.selectAll('.attribution')
53127 .data(data, function(d) { return d.name(); });
53132 background = background.enter()
53134 .attr('class', 'attribution')
53135 .each(function(d) {
53136 if (d.terms_html) {
53138 .html(d.terms_html);
53142 var source = d.terms_text || d.id || d.name();
53145 source = '<img class="source-image" src="' + context.imagePath(d.logo) + '">';
53151 .attr('href', d.terms_url)
53152 .attr('target', '_blank')
53159 .merge(background);
53162 var copyright = background.selectAll('.copyright-notice')
53163 .data(function(d) {
53164 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
53165 return notice ? [notice] : [];
53171 copyright = copyright.enter()
53173 .attr('class', 'copyright-notice')
53181 function update() {
53182 attribution([context.background().baseLayerSource()], 'base-layer-attribution');
53183 attribution(context.background().overlayLayerSources().filter(function (s) {
53184 return s.validZoom(context.map().zoom());
53185 }), 'overlay-layer-attribution');
53189 return function(select$$1) {
53190 selection$$1 = select$$1;
53192 context.background()
53193 .on('change.attribution', update);
53196 .on('move.attribution', lodash.throttle(update, 400, {leading: false}));
53202 function rendererBackgroundSource(data) {
53203 var source = lodash.clone(data),
53205 name = source.name,
53206 best = !!source.best;
53208 source.scaleExtent = data.scaleExtent || [0, 20];
53209 source.overzoom = data.overzoom !== false;
53212 source.offset = function(_) {
53213 if (!arguments.length) return offset;
53219 source.nudge = function(_, zoomlevel) {
53220 offset[0] += _[0] / Math.pow(2, zoomlevel);
53221 offset[1] += _[1] / Math.pow(2, zoomlevel);
53226 source.name = function() {
53231 source.best = function() {
53236 source.area = function() {
53237 if (!data.polygon) return Number.MAX_VALUE; // worldwide
53238 var area$$1 = area({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
53239 return isNaN(area$$1) ? 0 : area$$1;
53243 source.imageryUsed = function() {
53244 return name || source.id;
53248 source.url = function(coord) {
53249 return data.template
53250 .replace('{x}', coord[0])
53251 .replace('{y}', coord[1])
53252 // TMS-flipped y coordinate
53253 .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
53254 .replace(/\{z(oom)?\}/, coord[2])
53255 .replace(/\{switch:([^}]+)\}/, function(s, r) {
53256 var subdomains = r.split(',');
53257 return subdomains[(coord[0] + coord[1]) % subdomains.length];
53259 .replace('{u}', function() {
53261 for (var zoom$$1 = coord[2]; zoom$$1 > 0; zoom$$1--) {
53263 var mask = 1 << (zoom$$1 - 1);
53264 if ((coord[0] & mask) !== 0) b++;
53265 if ((coord[1] & mask) !== 0) b += 2;
53273 source.intersects = function(extent$$1) {
53274 extent$$1 = extent$$1.polygon();
53275 return !data.polygon || data.polygon.some(function(polygon) {
53276 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
53281 source.validZoom = function(z) {
53282 return source.scaleExtent[0] <= z &&
53283 (source.overzoom || source.scaleExtent[1] > z);
53287 source.isLocatorOverlay = function() {
53288 return source.id === 'mapbox_locator_overlay';
53292 source.copyrightNotices = function() {};
53299 rendererBackgroundSource.Bing = function(data, dispatch$$1) {
53300 // http://msdn.microsoft.com/en-us/library/ff701716.aspx
53301 // http://msdn.microsoft.com/en-us/library/ff701701.aspx
53303 data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
53305 var bing = rendererBackgroundSource(data),
53306 key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
53307 url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
53308 key + '&jsonp={callback}',
53311 jsonpRequest(url, function(json$$1) {
53312 providers = json$$1.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
53314 attribution: provider.attribution,
53315 areas: provider.coverageAreas.map(function(area$$1) {
53317 zoom: [area$$1.zoomMin, area$$1.zoomMax],
53318 extent: geoExtent$$1([area$$1.bbox[1], area$$1.bbox[0]], [area$$1.bbox[3], area$$1.bbox[2]])
53323 dispatch$$1.call('change');
53326 bing.copyrightNotices = function(zoom$$1, extent$$1) {
53327 zoom$$1 = Math.min(zoom$$1, 21);
53328 return providers.filter(function(provider) {
53329 return lodash.some(provider.areas, function(area$$1) {
53330 return extent$$1.intersects(area$$1.extent) &&
53331 area$$1.zoom[0] <= zoom$$1 &&
53332 area$$1.zoom[1] >= zoom$$1;
53334 }).map(function(provider) {
53335 return provider.attribution;
53339 bing.logo = 'bing_maps.png';
53340 bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
53346 rendererBackgroundSource.None = function() {
53347 var source = rendererBackgroundSource({ id: 'none', template: '' });
53349 source.name = function() {
53350 return t('background.none');
53353 source.imageryUsed = function() {
53357 source.area = function() {
53358 return -1; // sources in background pane are sorted by area
53365 rendererBackgroundSource.Custom = function(template) {
53366 var source = rendererBackgroundSource({ id: 'custom', template: template });
53368 source.name = function() {
53369 return t('background.custom');
53372 source.imageryUsed = function() {
53373 return 'Custom (' + template + ')';
53376 source.area = function() {
53377 return -2; // sources in background pane are sorted by area
53383 function rendererTileLayer(context) {
53384 var tileSize = 256,
53385 tile = d3geoTile(),
53390 transformProp = utilPrefixCSSProperty('Transform'),
53391 source = rendererBackgroundSource.None();
53394 // blacklist overlay tiles around Null Island..
53395 function nearNullIsland(x, y, z) {
53397 var center = Math.pow(2, z - 1),
53398 width = Math.pow(2, z - 6),
53399 min$$1 = center - (width / 2),
53400 max$$1 = center + (width / 2) - 1;
53401 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
53407 function tileSizeAtZoom(d, z) {
53408 var epsilon = 0.002;
53409 return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + epsilon;
53413 function atZoom(t, distance) {
53414 var power = Math.pow(2, distance);
53416 Math.floor(t[0] * power),
53417 Math.floor(t[1] * power),
53422 function lookUp(d) {
53423 for (var up = -1; up > -d[2]; up--) {
53424 var tile = atZoom(d, up);
53425 if (cache[source.url(tile)] !== false) {
53432 function uniqueBy(a, n) {
53433 var o = [], seen = {};
53434 for (var i = 0; i < a.length; i++) {
53435 if (seen[a[i][n]] === undefined) {
53437 seen[a[i][n]] = true;
53444 function addSource(d) {
53445 d.push(source.url(d));
53450 // Update tiles based on current state of `projection`.
53451 function background(selection$$1) {
53452 tile.scale(projection.scale() * 2 * Math.PI)
53453 .translate(projection.translate());
53456 projection.scale() * Math.PI - projection.translate()[0],
53457 projection.scale() * Math.PI - projection.translate()[1]];
53459 z = Math.max(Math.log(projection.scale() * 2 * Math.PI) / Math.log(2) - 8, 0);
53461 render(selection$$1);
53465 // Derive the tiles onscreen, remove those offscreen and position them.
53466 // Important that this part not depend on `projection` because it's
53467 // rentered when tiles load/error (see #644).
53468 function render(selection$$1) {
53470 var showDebug = context.getDebug('tile') && !source.overlay;
53472 if (source.validZoom(z)) {
53473 tile().forEach(function(d) {
53475 if (d[3] === '') return;
53476 if (typeof d[3] !== 'string') return; // Workaround for chrome crash https://github.com/openstreetmap/iD/issues/2295
53478 if (cache[d[3]] === false && lookUp(d)) {
53479 requests.push(addSource(lookUp(d)));
53483 requests = uniqueBy(requests, 3).filter(function(r) {
53484 if (!!source.overlay && nearNullIsland(r[0], r[1], r[2])) {
53487 // don't re-request tiles which have failed in the past
53488 return cache[r[3]] !== false;
53492 var pixelOffset = [
53493 source.offset()[0] * Math.pow(2, z),
53494 source.offset()[1] * Math.pow(2, z)
53498 cache[d[3]] = true;
53502 .classed('tile-loaded', true);
53503 render(selection$$1);
53506 function error(d) {
53507 cache[d[3]] = false;
53512 render(selection$$1);
53515 function imageTransform(d) {
53516 var _ts = tileSize * Math.pow(2, z - d[2]);
53517 var scale = tileSizeAtZoom(d, z);
53518 return 'translate(' +
53519 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0]) + 'px,' +
53520 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1]) + 'px)' +
53521 'scale(' + scale + ',' + scale + ')';
53524 function debugTransform(d) {
53525 var _ts = tileSize * Math.pow(2, z - d[2]);
53526 var scale = tileSizeAtZoom(d, z);
53527 return 'translate(' +
53528 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0] + scale * (tileSize / 4)) + 'px,' +
53529 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1] + scale * (tileSize / 2)) + 'px)';
53533 var image = selection$$1.selectAll('img')
53534 .data(requests, function(d) { return d[3]; });
53537 .style(transformProp, imageTransform)
53538 .classed('tile-removing', true)
53540 var tile = select(this);
53541 window.setTimeout(function() {
53542 if (tile.classed('tile-removing')) {
53550 .attr('class', 'tile')
53551 .attr('src', function(d) { return d[3]; })
53552 .on('error', error)
53555 .style(transformProp, imageTransform)
53556 .classed('tile-debug', showDebug)
53557 .classed('tile-removing', false);
53560 var debug = selection$$1.selectAll('.tile-label-debug')
53561 .data(showDebug ? requests : [], function(d) { return d[3]; });
53568 .attr('class', 'tile-label-debug')
53570 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; })
53571 .style(transformProp, debugTransform);
53575 background.projection = function(_) {
53576 if (!arguments.length) return projection;
53582 background.dimensions = function(_) {
53583 if (!arguments.length) return tile.size();
53589 background.source = function(_) {
53590 if (!arguments.length) return source;
53593 tile.scaleExtent(source.scaleExtent);
53601 function rendererBackground(context) {
53602 var dispatch$$1 = dispatch('change'),
53603 baseLayer = rendererTileLayer(context).projection(context.projection),
53604 overlayLayers = [],
53608 function findSource(id) {
53609 return lodash.find(backgroundSources, function(d) {
53610 return d.id && d.id === id;
53615 function background(selection$$1) {
53616 var base = selection$$1.selectAll('.layer-background')
53620 .insert('div', '.layer-data')
53621 .attr('class', 'layer layer-background')
53625 var overlays = selection$$1.selectAll('.layer-overlay')
53626 .data(overlayLayers, function(d) { return d.source().name(); });
53632 .insert('div', '.layer-data')
53633 .attr('class', 'layer layer-overlay')
53635 .each(function(layer) { select(this).call(layer); });
53639 background.updateImagery = function() {
53640 var b = background.baseLayerSource(),
53642 .filter(function (d) { return !d.source().isLocatorOverlay(); })
53643 .map(function (d) { return d.source().id; })
53645 meters = geoOffsetToMeters(b.offset()),
53647 x = +meters[0].toFixed(2),
53648 y = +meters[1].toFixed(2),
53649 q = utilStringQs(window.location.hash.substring(1));
53652 if (id === 'custom') {
53653 id = 'custom:' + b.template;
53659 delete q.background;
53668 if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
53669 q.offset = x + ',' + y;
53674 window.location.replace('#' + utilQsString(q, true));
53676 var imageryUsed = [b.imageryUsed()];
53679 .filter(function (d) { return !d.source().isLocatorOverlay(); })
53680 .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
53682 var gpx = context.layers().layer('gpx');
53683 if (gpx && gpx.enabled() && gpx.hasGpx()) {
53684 imageryUsed.push('Local GPX');
53687 var mapillary_images = context.layers().layer('mapillary-images');
53688 if (mapillary_images && mapillary_images.enabled()) {
53689 imageryUsed.push('Mapillary Images');
53692 var mapillary_signs = context.layers().layer('mapillary-signs');
53693 if (mapillary_signs && mapillary_signs.enabled()) {
53694 imageryUsed.push('Mapillary Signs');
53697 context.history().imageryUsed(imageryUsed);
53701 background.sources = function(extent$$1) {
53702 return backgroundSources.filter(function(source) {
53703 return source.intersects(extent$$1);
53708 background.dimensions = function(_) {
53710 baseLayer.dimensions(_);
53712 overlayLayers.forEach(function(layer) {
53713 layer.dimensions(_);
53718 background.baseLayerSource = function(d) {
53719 if (!arguments.length) return baseLayer.source();
53721 // test source against OSM imagery blacklists..
53722 var blacklists = context.connection().imageryBlacklists();
53728 for (i = 0; i < blacklists; i++) {
53730 regex = new RegExp(blacklists[i]);
53731 fail = regex.test(d.template);
53739 // ensure at least one test was run.
53741 regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
53742 fail = regex.test(d.template);
53745 baseLayer.source(!fail ? d : rendererBackgroundSource.None());
53746 dispatch$$1.call('change');
53747 background.updateImagery();
53752 background.bing = function() {
53753 background.baseLayerSource(findSource('Bing'));
53757 background.showsLayer = function(d) {
53758 return d.id === baseLayer.source().id ||
53759 overlayLayers.some(function(layer) { return d.id === layer.source().id; });
53763 background.overlayLayerSources = function() {
53764 return overlayLayers.map(function (l) { return l.source(); });
53768 background.toggleOverlayLayer = function(d) {
53771 for (var i = 0; i < overlayLayers.length; i++) {
53772 layer = overlayLayers[i];
53773 if (layer.source() === d) {
53774 overlayLayers.splice(i, 1);
53775 dispatch$$1.call('change');
53776 background.updateImagery();
53781 layer = rendererTileLayer(context)
53783 .projection(context.projection)
53784 .dimensions(baseLayer.dimensions());
53786 overlayLayers.push(layer);
53787 dispatch$$1.call('change');
53788 background.updateImagery();
53792 background.nudge = function(d, zoom$$1) {
53793 baseLayer.source().nudge(d, zoom$$1);
53794 dispatch$$1.call('change');
53795 background.updateImagery();
53800 background.offset = function(d) {
53801 if (!arguments.length) return baseLayer.source().offset();
53802 baseLayer.source().offset(d);
53803 dispatch$$1.call('change');
53804 background.updateImagery();
53809 background.init = function() {
53810 function parseMap(qmap) {
53811 if (!qmap) return false;
53812 var args = qmap.split('/').map(Number);
53813 if (args.length < 3 || args.some(isNaN)) return false;
53814 return geoExtent$$1([args[2], args[1]]);
53817 var dataImagery = data.imagery || [],
53818 q = utilStringQs(window.location.hash.substring(1)),
53819 chosen = q.background || q.layer,
53820 extent$$1 = parseMap(q.map),
53823 backgroundSources = dataImagery.map(function(source) {
53824 if (source.type === 'bing') {
53825 return rendererBackgroundSource.Bing(source, dispatch$$1);
53827 return rendererBackgroundSource(source);
53831 backgroundSources.unshift(rendererBackgroundSource.None());
53833 if (!chosen && extent$$1) {
53834 best = lodash.find(this.sources(extent$$1), function(s) { return s.best(); });
53837 if (chosen && chosen.indexOf('custom:') === 0) {
53838 background.baseLayerSource(rendererBackgroundSource.Custom(chosen.replace(/^custom:/, '')));
53840 background.baseLayerSource(findSource(chosen) || best || findSource('Bing') || backgroundSources[1] || backgroundSources[0]);
53843 var locator = lodash.find(backgroundSources, function(d) {
53844 return d.overlay && d.default;
53848 background.toggleOverlayLayer(locator);
53851 var overlays = (q.overlays || '').split(',');
53852 overlays.forEach(function(overlay) {
53853 overlay = findSource(overlay);
53855 background.toggleOverlayLayer(overlay);
53860 var gpx = context.layers().layer('gpx');
53867 var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
53868 return !isNaN(n) && n;
53871 if (offset.length === 2) {
53872 background.offset(geoMetersToOffset(offset));
53878 return utilRebind(background, dispatch$$1, 'on');
53881 function rendererFeatures(context) {
53882 var traffic_roads = {
53884 'motorway_link': true,
53886 'trunk_link': true,
53888 'primary_link': true,
53890 'secondary_link': true,
53892 'tertiary_link': true,
53893 'residential': true,
53894 'unclassified': true,
53895 'living_street': true
53898 var service_roads = {
53910 'pedestrian': true,
53914 var past_futures = {
53916 'construction': true,
53918 'dismantled': true,
53921 'demolished': true,
53922 'obliterated': true
53925 var dispatch$$1 = dispatch('change', 'redraw'),
53934 function update() {
53935 _hidden = features.hidden();
53936 dispatch$$1.call('change');
53937 dispatch$$1.call('redraw');
53941 function defineFeature(k, filter, max$$1) {
53945 enabled: true, // whether the user wants it enabled..
53947 currentMax: (max$$1 || Infinity),
53948 defaultMax: (max$$1 || Infinity),
53949 enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
53950 disable: function() { this.enabled = false; this.currentMax = 0; },
53951 hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
53952 autoHidden: function() { return this.hidden() && this.currentMax > 0; }
53957 defineFeature('points', function isPoint(entity, resolver, geometry) {
53958 return geometry === 'point';
53961 defineFeature('traffic_roads', function isTrafficRoad(entity) {
53962 return traffic_roads[entity.tags.highway];
53965 defineFeature('service_roads', function isServiceRoad(entity) {
53966 return service_roads[entity.tags.highway];
53969 defineFeature('paths', function isPath(entity) {
53970 return paths[entity.tags.highway];
53973 defineFeature('buildings', function isBuilding(entity) {
53975 !!entity.tags['building:part'] ||
53976 (!!entity.tags.building && entity.tags.building !== 'no') ||
53977 entity.tags.amenity === 'shelter' ||
53978 entity.tags.parking === 'multi-storey' ||
53979 entity.tags.parking === 'sheds' ||
53980 entity.tags.parking === 'carports' ||
53981 entity.tags.parking === 'garage_boxes'
53985 defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
53986 return geometry === 'area' &&
53987 !_features.buildings.filter(entity) &&
53988 !_features.water.filter(entity);
53991 defineFeature('boundaries', function isBoundary(entity) {
53992 return !!entity.tags.boundary;
53995 defineFeature('water', function isWater(entity) {
53997 !!entity.tags.waterway ||
53998 entity.tags.natural === 'water' ||
53999 entity.tags.natural === 'coastline' ||
54000 entity.tags.natural === 'bay' ||
54001 entity.tags.landuse === 'pond' ||
54002 entity.tags.landuse === 'basin' ||
54003 entity.tags.landuse === 'reservoir' ||
54004 entity.tags.landuse === 'salt_pond'
54008 defineFeature('rail', function isRail(entity) {
54010 !!entity.tags.railway ||
54011 entity.tags.landuse === 'railway'
54013 traffic_roads[entity.tags.highway] ||
54014 service_roads[entity.tags.highway] ||
54015 paths[entity.tags.highway]
54019 defineFeature('power', function isPower(entity) {
54020 return !!entity.tags.power;
54023 // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
54024 defineFeature('past_future', function isPastFuture(entity) {
54026 traffic_roads[entity.tags.highway] ||
54027 service_roads[entity.tags.highway] ||
54028 paths[entity.tags.highway]
54029 ) { return false; }
54031 var strings = Object.keys(entity.tags);
54033 for (var i = 0; i < strings.length; i++) {
54034 var s = strings[i];
54035 if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
54040 // Lines or areas that don't match another feature filter.
54041 // IMPORTANT: The 'others' feature must be the last one defined,
54042 // so that code in getMatches can skip this test if `hasMatch = true`
54043 defineFeature('others', function isOther(entity, resolver, geometry) {
54044 return (geometry === 'line' || geometry === 'area');
54048 function features() {}
54051 features.features = function() {
54056 features.keys = function() {
54061 features.enabled = function(k) {
54062 if (!arguments.length) {
54063 return _keys.filter(function(k) { return _features[k].enabled; });
54065 return _features[k] && _features[k].enabled;
54069 features.disabled = function(k) {
54070 if (!arguments.length) {
54071 return _keys.filter(function(k) { return !_features[k].enabled; });
54073 return _features[k] && !_features[k].enabled;
54077 features.hidden = function(k) {
54078 if (!arguments.length) {
54079 return _keys.filter(function(k) { return _features[k].hidden(); });
54081 return _features[k] && _features[k].hidden();
54085 features.autoHidden = function(k) {
54086 if (!arguments.length) {
54087 return _keys.filter(function(k) { return _features[k].autoHidden(); });
54089 return _features[k] && _features[k].autoHidden();
54093 features.enable = function(k) {
54094 if (_features[k] && !_features[k].enabled) {
54095 _features[k].enable();
54101 features.disable = function(k) {
54102 if (_features[k] && _features[k].enabled) {
54103 _features[k].disable();
54109 features.toggle = function(k) {
54110 if (_features[k]) {
54111 (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
54117 features.resetStats = function() {
54118 for (var i = 0; i < _keys.length; i++) {
54119 _features[_keys[i]].count = 0;
54121 dispatch$$1.call('change');
54125 features.gatherStats = function(d, resolver, dimensions) {
54126 var needsRedraw = false,
54127 type = lodash.groupBy(d, function(ent) { return ent.type; }),
54128 entities = [].concat(type.relation || [], type.way || [], type.node || []),
54129 currHidden, geometry, matches, i, j;
54131 for (i = 0; i < _keys.length; i++) {
54132 _features[_keys[i]].count = 0;
54135 // adjust the threshold for point/building culling based on viewport size..
54136 // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
54137 _cullFactor = dimensions[0] * dimensions[1] / 1000000;
54139 for (i = 0; i < entities.length; i++) {
54140 geometry = entities[i].geometry(resolver);
54141 if (!(geometry === 'vertex' || geometry === 'relation')) {
54142 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
54143 for (j = 0; j < matches.length; j++) {
54144 _features[matches[j]].count++;
54149 currHidden = features.hidden();
54150 if (currHidden !== _hidden) {
54151 _hidden = currHidden;
54152 needsRedraw = true;
54153 dispatch$$1.call('change');
54156 return needsRedraw;
54160 features.stats = function() {
54161 for (var i = 0; i < _keys.length; i++) {
54162 _stats[_keys[i]] = _features[_keys[i]].count;
54169 features.clear = function(d) {
54170 for (var i = 0; i < d.length; i++) {
54171 features.clearEntity(d[i]);
54176 features.clearEntity = function(entity) {
54177 delete _cache[osmEntity$$1.key(entity)];
54181 features.reset = function() {
54186 features.getMatches = function(entity, resolver, geometry) {
54187 if (geometry === 'vertex' || geometry === 'relation') return {};
54189 var ent = osmEntity$$1.key(entity);
54190 if (!_cache[ent]) {
54194 if (!_cache[ent].matches) {
54198 for (var i = 0; i < _keys.length; i++) {
54199 if (_keys[i] === 'others') {
54200 if (hasMatch) continue;
54202 // Multipolygon members:
54204 // 1. is a way that hasn't matched other 'interesting' feature rules,
54205 // 2. and it belongs to a single parent multipolygon relation
54206 // ...then match whatever feature rules the parent multipolygon has matched.
54207 // see #2548, #2887
54210 // For this to work, getMatches must be called on relations before ways.
54212 if (entity.type === 'way') {
54213 var parents = features.getParents(entity, resolver, geometry);
54214 if (parents.length === 1 && parents[0].isMultipolygon()) {
54215 var pkey = osmEntity$$1.key(parents[0]);
54216 if (_cache[pkey] && _cache[pkey].matches) {
54217 matches = lodash.clone(_cache[pkey].matches);
54224 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
54225 matches[_keys[i]] = hasMatch = true;
54228 _cache[ent].matches = matches;
54231 return _cache[ent].matches;
54235 features.getParents = function(entity, resolver, geometry) {
54236 if (geometry === 'point') return [];
54238 var ent = osmEntity$$1.key(entity);
54239 if (!_cache[ent]) {
54243 if (!_cache[ent].parents) {
54245 if (geometry === 'vertex') {
54246 parents = resolver.parentWays(entity);
54247 } else { // 'line', 'area', 'relation'
54248 parents = resolver.parentRelations(entity);
54250 _cache[ent].parents = parents;
54252 return _cache[ent].parents;
54256 features.isHiddenFeature = function(entity, resolver, geometry) {
54257 if (!_hidden.length) return false;
54258 if (!entity.version) return false;
54260 var matches = features.getMatches(entity, resolver, geometry);
54262 for (var i = 0; i < _hidden.length; i++) {
54263 if (matches[_hidden[i]]) return true;
54269 features.isHiddenChild = function(entity, resolver, geometry) {
54270 if (!_hidden.length) return false;
54271 if (!entity.version || geometry === 'point') return false;
54273 var parents = features.getParents(entity, resolver, geometry);
54274 if (!parents.length) return false;
54276 for (var i = 0; i < parents.length; i++) {
54277 if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
54285 features.hasHiddenConnections = function(entity, resolver) {
54286 if (!_hidden.length) return false;
54287 var childNodes, connections;
54289 if (entity.type === 'midpoint') {
54290 childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
54293 childNodes = entity.nodes ? resolver.childNodes(entity) : [];
54294 connections = features.getParents(entity, resolver, entity.geometry(resolver));
54297 // gather ways connected to child nodes..
54298 connections = lodash.reduce(childNodes, function(result, e) {
54299 return resolver.isShared(e) ? lodash.union(result, resolver.parentWays(e)) : result;
54302 return connections.length ? lodash.some(connections, function(e) {
54303 return features.isHidden(e, resolver, e.geometry(resolver));
54308 features.isHidden = function(entity, resolver, geometry) {
54309 if (!_hidden.length) return false;
54310 if (!entity.version) return false;
54312 var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
54313 return fn(entity, resolver, geometry);
54317 features.filter = function(d, resolver) {
54318 if (!_hidden.length) return d;
54321 for (var i = 0; i < d.length; i++) {
54323 if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
54324 result.push(entity);
54331 return utilRebind(features, dispatch$$1, 'on');
54334 function utilBindOnce(target, type, listener, capture) {
54335 var typeOnce = type + '.once';
54337 target.on(typeOnce, null);
54338 listener.apply(this, arguments);
54340 target.on(typeOnce, one, capture);
54344 function rendererMap(context) {
54346 var dimensions = [1, 1],
54347 dispatch$$1 = dispatch('move', 'drawn'),
54348 projection = context.projection,
54349 dblclickEnabled = true,
54350 redrawEnabled = true,
54351 transformStart = projection.transform(),
54352 transformed = false,
54354 drawLayers = svgLayers(projection, context),
54355 drawPoints = svgPoints$$1(projection, context),
54356 drawVertices = svgVertices$$1(projection, context),
54357 drawLines = svgLines$$1(projection),
54358 drawAreas = svgAreas$$1(projection, context),
54359 drawMidpoints = svgMidpoints$$1(projection, context),
54360 drawLabels = svgLabels(projection, context),
54361 supersurface = select(null),
54362 wrapper = select(null),
54363 surface = select(null),
54367 var zoom$$1 = zoom$1()
54368 .scaleExtent([ztok(2), ztok(24)])
54369 .interpolate(value$1)
54370 .filter(zoomEventFilter)
54371 .on('zoom', zoomPan);
54373 var _selection = select(null);
54376 function map$$1(selection$$1) {
54378 _selection = selection$$1;
54381 .on('change.map', immediateRedraw);
54383 context.connection()
54384 .on('change.map', immediateRedraw);
54387 .on('change.map', immediateRedraw)
54388 .on('undone.context redone.context', function(stack$$1) {
54389 var followSelected = false;
54390 if (Array.isArray(stack$$1.selectedIDs)) {
54391 followSelected = (stack$$1.selectedIDs.length === 1 && stack$$1.selectedIDs[0][0] === 'n');
54393 modeSelect(context, stack$$1.selectedIDs).suppressMenu(true).follow(followSelected)
54396 if (!followSelected && stack$$1.transform) {
54397 map$$1.transformEase(stack$$1.transform);
54401 context.background()
54402 .on('change.map', immediateRedraw);
54405 .on('redraw.map', immediateRedraw);
54408 .on('change.map', function() {
54409 context.background().updateImagery();
54414 .on('dblclick.map', dblClick)
54416 .call(zoom$$1.transform, projection.transform());
54418 supersurface = selection$$1.append('div')
54419 .attr('id', 'supersurface')
54420 .call(utilSetTransform, 0, 0);
54422 // Need a wrapper div because Opera can't cope with an absolutely positioned
54423 // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
54424 wrapper = supersurface
54426 .attr('class', 'layer layer-data');
54428 map$$1.surface = surface = wrapper
54430 .selectAll('.surface')
54431 .attr('id', 'surface');
54434 .call(drawLabels.observe)
54435 .on('mousedown.zoom', function() {
54436 if (event.button === 2) {
54437 event.stopPropagation();
54440 .on('mouseup.zoom', function() {
54441 if (resetTransform()) immediateRedraw();
54443 .on('mousemove.map', function() {
54446 .on('mouseover.vertices', function() {
54447 if (map$$1.editable() && !transformed) {
54448 var hover = event.target.__data__;
54449 surface.selectAll('.data-layer-osm')
54450 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
54451 dispatch$$1.call('drawn', this, {full: false});
54454 .on('mouseout.vertices', function() {
54455 if (map$$1.editable() && !transformed) {
54456 var hover = event.relatedTarget && event.relatedTarget.__data__;
54457 surface.selectAll('.data-layer-osm')
54458 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
54459 dispatch$$1.call('drawn', this, {full: false});
54464 .call(context.background());
54466 context.on('enter.map', function() {
54467 if (map$$1.editable() && !transformed) {
54468 var all = context.intersects(map$$1.extent()),
54469 filter = utilFunctor(true),
54470 graph = context.graph();
54472 all = context.features().filter(all, graph);
54473 surface.selectAll('.data-layer-osm')
54474 .call(drawVertices, graph, all, filter, map$$1.extent(), map$$1.zoom())
54475 .call(drawMidpoints, graph, all, filter, map$$1.trimmedExtent());
54476 dispatch$$1.call('drawn', this, {full: false});
54480 map$$1.dimensions(utilGetDimensions(selection$$1));
54484 function zoomEventFilter() {
54485 // Fix for #2151, (see also d3/d3-zoom#60, d3/d3-brush#18)
54486 // Intercept `mousedown` and check if there is an orphaned zoom gesture.
54487 // This can happen if a previous `mousedown` occurred without a `mouseup`.
54488 // If we detect this, dispatch `mouseup` to complete the orphaned gesture,
54489 // so that d3-zoom won't stop propagation of new `mousedown` events.
54490 if (event.type === 'mousedown') {
54491 var hasOrphan = false;
54492 var listeners = window.__on;
54493 for (var i = 0; i < listeners.length; i++) {
54494 var listener = listeners[i];
54495 if (listener.name === 'zoom' && listener.type === 'mouseup') {
54501 var event$$1 = window.CustomEvent;
54503 event$$1 = new event$$1('mouseup');
54505 event$$1 = window.document.createEvent('Event');
54506 event$$1.initEvent('mouseup', false, false);
54508 // Event needs to be dispatched with an event.view property.
54509 event$$1.view = window;
54510 window.dispatchEvent(event$$1);
54514 return event.button !== 2; // ignore right clicks
54519 return 256 * Math.pow(2, z);
54523 return Math.max(Math.log(k) / Math.LN2 - 8, 0);
54526 function pxCenter() {
54527 return [dimensions[0] / 2, dimensions[1] / 2];
54531 function drawVector(difference, extent$$1) {
54532 var graph = context.graph(),
54533 features = context.features(),
54534 all = context.intersects(map$$1.extent()),
54538 var complete = difference.complete(map$$1.extent());
54539 data = lodash.compact(lodash.values(complete));
54540 filter = function(d) { return d.id in complete; };
54541 features.clear(data);
54544 // force a full redraw if gatherStats detects that a feature
54545 // should be auto-hidden (e.g. points or buildings)..
54546 if (features.gatherStats(all, graph, dimensions)) {
54547 extent$$1 = undefined;
54551 data = context.intersects(map$$1.extent().intersection(extent$$1));
54552 var set$$1 = set$2(lodash.map(data, 'id'));
54553 filter = function(d) { return set$$1.has(d.id); };
54557 filter = utilFunctor(true);
54561 data = features.filter(data, graph);
54563 surface.selectAll('.data-layer-osm')
54564 .call(drawVertices, graph, data, filter, map$$1.extent(), map$$1.zoom())
54565 .call(drawLines, graph, data, filter)
54566 .call(drawAreas, graph, data, filter)
54567 .call(drawMidpoints, graph, data, filter, map$$1.trimmedExtent())
54568 .call(drawLabels, graph, data, filter, dimensions, !difference && !extent$$1)
54569 .call(drawPoints, graph, data, filter);
54571 dispatch$$1.call('drawn', this, {full: true});
54575 function editOff() {
54576 context.features().resetStats();
54577 surface.selectAll('.layer-osm *').remove();
54578 dispatch$$1.call('drawn', this, {full: true});
54582 function dblClick() {
54583 if (!dblclickEnabled) {
54584 event.preventDefault();
54585 event.stopImmediatePropagation();
54590 function zoomPan(manualEvent) {
54591 var eventTransform = (manualEvent || event).transform;
54593 if (transformStart.x === eventTransform.x &&
54594 transformStart.y === eventTransform.y &&
54595 transformStart.k === eventTransform.k) {
54596 return; // no change
54599 if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
54600 surface.interrupt();
54601 uiFlash(context.container())
54602 .select('.content')
54603 .text(t('cannot_zoom'));
54604 setZoom(context.minEditableZoom(), true);
54606 dispatch$$1.call('move', this, map$$1);
54610 projection.transform(eventTransform);
54612 var scale = eventTransform.k / transformStart.k,
54613 tX = (eventTransform.x / scale - transformStart.x) * scale,
54614 tY = (eventTransform.y / scale - transformStart.y) * scale;
54616 transformed = true;
54617 utilSetTransform(supersurface, tX, tY, scale);
54620 dispatch$$1.call('move', this, map$$1);
54624 function resetTransform() {
54625 if (!transformed) return false;
54627 surface.selectAll('.radial-menu').interrupt().remove();
54628 utilSetTransform(supersurface, 0, 0);
54629 transformed = false;
54634 function redraw(difference, extent$$1) {
54635 if (surface.empty() || !redrawEnabled) return;
54637 // If we are in the middle of a zoom/pan, we can't do differenced redraws.
54638 // It would result in artifacts where differenced entities are redrawn with
54639 // one transform and unchanged entities with another.
54640 if (resetTransform()) {
54641 difference = extent$$1 = undefined;
54644 var z = String(~~map$$1.zoom());
54645 if (surface.attr('data-zoom') !== z) {
54646 surface.attr('data-zoom', z)
54647 .classed('low-zoom', z <= 16);
54651 supersurface.call(context.background());
54658 if (map$$1.editable()) {
54659 context.loadTiles(projection, dimensions);
54660 drawVector(difference, extent$$1);
54665 transformStart = projection.transform();
54671 var queueRedraw = lodash.throttle(redraw, 750);
54674 var immediateRedraw = function(difference, extent$$1) {
54675 if (!difference && !extent$$1) queueRedraw.cancel();
54676 redraw(difference, extent$$1);
54680 function pointLocation(p) {
54681 var translate = projection.translate(),
54682 scale = projection.scale() * 2 * Math.PI;
54683 return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
54687 function locationPoint(l) {
54688 var translate = projection.translate(),
54689 scale = projection.scale() * 2 * Math.PI;
54690 return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
54694 map$$1.mouse = function() {
54695 var event$$1 = mousemove || event;
54698 while ((s = event$$1.sourceEvent)) { event$$1 = s; }
54699 return mouse$$1(event$$1);
54705 map$$1.mouseCoordinates = function() {
54706 return projection.invert(map$$1.mouse());
54710 map$$1.dblclickEnable = function(_) {
54711 if (!arguments.length) return dblclickEnabled;
54712 dblclickEnabled = _;
54717 map$$1.redrawEnable = function(_) {
54718 if (!arguments.length) return redrawEnabled;
54724 function setTransform(t2, duration, force) {
54725 var t$$1 = projection.transform();
54726 if (!force && t2.k === t$$1.k && t2.x === t$$1.x && t2.y === t$$1.y) {
54733 .duration(duration)
54734 .on('start', function() { map$$1.startEase(); })
54735 .call(zoom$$1.transform, identity$9.translate(t2.x, t2.y).scale(t2.k));
54737 projection.transform(t2);
54738 transformStart = t2;
54739 _selection.call(zoom$$1.transform, transformStart);
54744 function setZoom(z2, force, duration) {
54745 if (z2 === map$$1.zoom() && !force) {
54749 var k = projection.scale(),
54750 k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
54751 center = pxCenter(),
54752 l = pointLocation(center);
54754 projection.scale(k2);
54756 var t$$1 = projection.translate();
54757 l = locationPoint(l);
54759 t$$1[0] += center[0] - l[0];
54760 t$$1[1] += center[1] - l[1];
54763 projection.scale(k); // reset scale
54766 .duration(duration)
54767 .on('start', function() { map$$1.startEase(); })
54768 .call(zoom$$1.transform, identity$9.translate(t$$1[0], t$$1[1]).scale(k2));
54770 projection.translate(t$$1);
54771 transformStart = projection.transform();
54772 _selection.call(zoom$$1.transform, transformStart);
54779 function setCenter(loc2, duration) {
54780 var c = map$$1.center();
54781 if (loc2[0] === c[0] && loc2[1] === c[1]) {
54785 var t$$1 = projection.translate(),
54786 k = projection.scale(),
54788 ll = projection(loc2);
54790 t$$1[0] = t$$1[0] - ll[0] + pxC[0];
54791 t$$1[1] = t$$1[1] - ll[1] + pxC[1];
54796 .duration(duration)
54797 .on('start', function() { map$$1.startEase(); })
54798 .call(zoom$$1.transform, identity$9.translate(t$$1[0], t$$1[1]).scale(k));
54800 projection.translate(t$$1);
54801 transformStart = projection.transform();
54802 _selection.call(zoom$$1.transform, transformStart);
54809 map$$1.pan = function(delta, duration) {
54810 var t$$1 = projection.translate(),
54811 k = projection.scale();
54813 t$$1[0] += delta[0];
54814 t$$1[1] += delta[1];
54819 .duration(duration)
54820 .on('start', function() { map$$1.startEase(); })
54821 .call(zoom$$1.transform, identity$9.translate(t$$1[0], t$$1[1]).scale(k));
54823 projection.translate(t$$1);
54824 transformStart = projection.transform();
54825 _selection.call(zoom$$1.transform, transformStart);
54826 dispatch$$1.call('move', this, map$$1);
54834 map$$1.dimensions = function(_) {
54835 if (!arguments.length) return dimensions;
54836 var center = map$$1.center();
54838 drawLayers.dimensions(dimensions);
54839 context.background().dimensions(dimensions);
54840 projection.clipExtent([[0, 0], dimensions]);
54841 mouse$$1 = utilFastMouse(supersurface.node());
54849 function zoomIn(delta) {
54850 setZoom(~~map$$1.zoom() + delta, true, 250);
54853 function zoomOut(delta) {
54854 setZoom(~~map$$1.zoom() - delta, true, 250);
54857 map$$1.zoomIn = function() { zoomIn(1); };
54858 map$$1.zoomInFurther = function() { zoomIn(4); };
54860 map$$1.zoomOut = function() { zoomOut(1); };
54861 map$$1.zoomOutFurther = function() { zoomOut(4); };
54864 map$$1.center = function(loc2) {
54865 if (!arguments.length) {
54866 return projection.invert(pxCenter());
54869 if (setCenter(loc2)) {
54870 dispatch$$1.call('move', this, map$$1);
54878 map$$1.zoom = function(z2) {
54879 if (!arguments.length) {
54880 return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
54883 if (z2 < minzoom) {
54884 surface.interrupt();
54885 uiFlash(context.container())
54886 .select('.content')
54887 .text(t('cannot_zoom'));
54888 z2 = context.minEditableZoom();
54892 dispatch$$1.call('move', this, map$$1);
54900 map$$1.zoomTo = function(entity, zoomLimits) {
54901 var extent$$1 = entity.extent(context.graph());
54902 if (!isFinite(extent$$1.area())) return;
54904 var z2 = map$$1.trimmedExtentZoom(extent$$1);
54905 zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
54906 map$$1.centerZoom(extent$$1.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
54910 map$$1.centerZoom = function(loc2, z2) {
54911 var centered = setCenter(loc2),
54912 zoomed = setZoom(z2);
54914 if (centered || zoomed) {
54915 dispatch$$1.call('move', this, map$$1);
54923 map$$1.centerEase = function(loc2, duration) {
54924 duration = duration || 250;
54925 setCenter(loc2, duration);
54930 map$$1.zoomEase = function(z2, duration) {
54931 duration = duration || 250;
54932 setZoom(z2, false, duration);
54937 map$$1.transformEase = function(t2, duration) {
54938 duration = duration || 250;
54939 setTransform(t2, duration, false);
54944 map$$1.startEase = function() {
54945 utilBindOnce(surface, 'mousedown.ease', function() {
54946 map$$1.cancelEase();
54952 map$$1.cancelEase = function() {
54953 _selection.interrupt();
54958 map$$1.extent = function(_) {
54959 if (!arguments.length) {
54960 return new geoExtent$$1(projection.invert([0, dimensions[1]]),
54961 projection.invert([dimensions[0], 0]));
54963 var extent$$1 = geoExtent$$1(_);
54964 map$$1.centerZoom(extent$$1.center(), map$$1.extentZoom(extent$$1));
54969 map$$1.trimmedExtent = function(_) {
54970 if (!arguments.length) {
54971 var headerY = 60, footerY = 30, pad = 10;
54972 return new geoExtent$$1(projection.invert([pad, dimensions[1] - footerY - pad]),
54973 projection.invert([dimensions[0] - pad, headerY + pad]));
54975 var extent$$1 = geoExtent$$1(_);
54976 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
54981 function calcZoom(extent$$1, dim) {
54982 var tl = projection([extent$$1[0][0], extent$$1[1][1]]),
54983 br = projection([extent$$1[1][0], extent$$1[0][1]]);
54985 // Calculate maximum zoom that fits extent
54986 var hFactor = (br[0] - tl[0]) / dim[0],
54987 vFactor = (br[1] - tl[1]) / dim[1],
54988 hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
54989 vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
54990 newZoom = map$$1.zoom() - Math.max(hZoomDiff, vZoomDiff);
54996 map$$1.extentZoom = function(_) {
54997 return calcZoom(geoExtent$$1(_), dimensions);
55001 map$$1.trimmedExtentZoom = function(_) {
55002 var trimY = 120, trimX = 40,
55003 trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
55004 return calcZoom(geoExtent$$1(_), trimmed);
55008 map$$1.editable = function() {
55009 return map$$1.zoom() >= context.minEditableZoom();
55013 map$$1.minzoom = function(_) {
55014 if (!arguments.length) return minzoom;
55020 map$$1.layers = drawLayers;
55023 return utilRebind(map$$1, dispatch$$1, 'on');
55026 var TAU = 2 * Math.PI;
55027 function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
55028 function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
55029 function vecSub(a, b) { return [ a[0] - b[0], a[1] - b[1] ]; }
55030 function vecScale(a, b) { return [ a[0] * b, a[1] * b ]; }
55033 function uiMapInMap(context) {
55037 function map_in_map(selection$$1) {
55038 var backgroundLayer = rendererTileLayer(context),
55039 overlayLayers = {},
55040 projection = geoRawMercator(),
55041 gpxLayer = svgGpx(projection, context).showLabels(false),
55042 debugLayer = svgDebug(projection, context),
55044 .scaleExtent([ztok(0.5), ztok(24)])
55045 .on('start', zoomStarted)
55046 .on('zoom', zoomed)
55047 .on('end', zoomEnded),
55048 isTransformed = false,
55050 skipEvents = false,
55052 zDiff = 6, // by default, minimap renders at (main zoom - 6)
55053 wrap = select(null),
55054 tiles = select(null),
55055 viewport = select(null),
55056 tStart, // transform at start of gesture
55057 tCurr, // transform at most recent event
55061 function zoomStarted() {
55062 if (skipEvents) return;
55063 tStart = tCurr = projection.transform();
55068 function zoomed() {
55069 if (skipEvents) return;
55071 var x = event.transform.x,
55072 y = event.transform.y,
55073 k = event.transform.k,
55074 isZooming = (k !== tStart.k),
55075 isPanning = (x !== tStart.x || y !== tStart.y);
55077 if (!isZooming && !isPanning) {
55078 return; // no change
55081 // lock in either zooming or panning, don't allow both in minimap.
55083 gesture = isZooming ? 'zoom' : 'pan';
55086 var tMini = projection.transform(),
55089 if (gesture === 'zoom') {
55090 var dMini = utilGetDimensions(wrap),
55091 cMini = vecScale(dMini, 0.5);
55092 scale = k / tMini.k;
55093 tX = (cMini[0] / scale - cMini[0]) * scale;
55094 tY = (cMini[1] / scale - cMini[1]) * scale;
55102 utilSetTransform(tiles, tX, tY, scale);
55103 utilSetTransform(viewport, 0, 0, scale);
55104 isTransformed = true;
55105 tCurr = identity$9.translate(x, y).scale(k);
55107 var zMain = ktoz(context.projection.scale()),
55110 zDiff = zMain - zMini;
55116 function zoomEnded() {
55117 if (skipEvents) return;
55118 if (gesture !== 'pan') return;
55120 updateProjection();
55122 var dMini = utilGetDimensions(wrap),
55123 cMini = vecScale(dMini, 0.5);
55124 context.map().center(projection.invert(cMini)); // recenter main map..
55128 function updateProjection() {
55129 var loc = context.map().center(),
55130 dMini = utilGetDimensions(wrap),
55131 cMini = vecScale(dMini, 0.5),
55132 tMain = context.projection.transform(),
55133 zMain = ktoz(tMain.k),
55134 zMini = Math.max(zMain - zDiff, 0.5),
55135 kMini = ztok(zMini);
55138 .translate([tMain.x, tMain.y])
55141 var point = projection(loc),
55142 mouse$$1 = (gesture === 'pan') ? vecSub([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0],
55143 xMini = cMini[0] - point[0] + tMain.x + mouse$$1[0],
55144 yMini = cMini[1] - point[1] + tMain.y + mouse$$1[1];
55147 .translate([xMini, yMini])
55148 .clipExtent([[0, 0], dMini]);
55150 tCurr = projection.transform();
55152 if (isTransformed) {
55153 utilSetTransform(tiles, 0, 0);
55154 utilSetTransform(viewport, 0, 0);
55155 isTransformed = false;
55159 .scaleExtent([ztok(0.5), ztok(zMain - 3)]);
55162 wrap.call(zoom$$1.transform, tCurr);
55163 skipEvents = false;
55167 function redraw() {
55168 clearTimeout(timeoutId);
55169 if (isHidden) return;
55171 updateProjection();
55173 var dMini = utilGetDimensions(wrap),
55174 zMini = ktoz(projection.scale());
55176 // setup tile container
55178 .selectAll('.map-in-map-tiles')
55181 tiles = tiles.enter()
55183 .attr('class', 'map-in-map-tiles')
55186 // redraw background
55188 .source(context.background().baseLayerSource())
55189 .projection(projection)
55190 .dimensions(dMini);
55192 var background = tiles
55193 .selectAll('.map-in-map-background')
55198 .attr('class', 'map-in-map-background')
55200 .call(backgroundLayer);
55204 var overlaySources = context.background().overlayLayerSources();
55205 var activeOverlayLayers = [];
55206 for (var i = 0; i < overlaySources.length; i++) {
55207 if (overlaySources[i].validZoom(zMini)) {
55208 if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
55209 activeOverlayLayers.push(overlayLayers[i]
55210 .source(overlaySources[i])
55211 .projection(projection)
55212 .dimensions(dMini));
55216 var overlay = tiles
55217 .selectAll('.map-in-map-overlay')
55220 overlay = overlay.enter()
55222 .attr('class', 'map-in-map-overlay')
55226 var overlays = overlay
55228 .data(activeOverlayLayers, function(d) { return d.source().name(); });
55233 overlays = overlays.enter()
55236 .each(function(layer) { select(this).call(layer); });
55239 var dataLayers = tiles
55240 .selectAll('.map-in-map-data')
55246 dataLayers = dataLayers.enter()
55248 .attr('class', 'map-in-map-data')
55254 // redraw viewport bounding box
55255 if (gesture !== 'pan') {
55256 var getPath = index$4(projection),
55257 bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
55259 viewport = wrap.selectAll('.map-in-map-viewport')
55262 viewport = viewport.enter()
55264 .attr('class', 'map-in-map-viewport')
55268 var path$$1 = viewport.selectAll('.map-in-map-bbox')
55273 .attr('class', 'map-in-map-bbox')
55275 .attr('d', getPath)
55276 .classed('thick', function(d) { return getPath.area(d) < 30; });
55281 function queueRedraw() {
55282 clearTimeout(timeoutId);
55283 timeoutId = setTimeout(function() { redraw(); }, 750);
55287 function toggle() {
55288 if (event) event.preventDefault();
55290 isHidden = !isHidden;
55292 var label = select('.minimap-toggle');
55293 label.classed('active', !isHidden)
55294 .select('input').property('checked', !isHidden);
55298 .style('display', 'block')
55299 .style('opacity', '1')
55302 .style('opacity', '0')
55303 .on('end', function() {
55304 selection$$1.selectAll('.map-in-map')
55305 .style('display', 'none');
55309 .style('display', 'block')
55310 .style('opacity', '0')
55313 .style('opacity', '1')
55314 .on('end', function() {
55321 uiMapInMap.toggle = toggle;
55323 wrap = selection$$1.selectAll('.map-in-map')
55326 wrap = wrap.enter()
55328 .attr('class', 'map-in-map')
55329 .style('display', (isHidden ? 'none' : 'block'))
55331 .on('dblclick.zoom', null)
55335 .on('drawn.map-in-map', function(drawn) {
55336 if (drawn.full === true) {
55343 var keybinding = d3keybinding('map-in-map')
55353 function uiTooltipHtml(text, key) {
55354 var s = '<span>' + text + '</span>';
55356 s += '<div class="keyhint-wrap">' +
55357 '<span> ' + (t('tooltip_keyhint')) + ' </span>' +
55358 '<span class="keyhint"> ' + key + '</span></div>';
55363 function uiBackground(context) {
55365 detected = utilDetect(),
55366 opacities = [1, 0.75, 0.5, 0.25],
55368 ['right', [0.5, 0]],
55369 ['top', [0, -0.5]],
55370 ['left', [-0.5, 0]],
55371 ['bottom', [0, 0.5]]],
55372 opacityDefault = (context.storage('background-opacity') !== null) ?
55373 (+context.storage('background-opacity')) : 1.0,
55374 customTemplate = context.storage('background-custom-template') || '',
55377 // Can be 0 from <1.3.0 use or due to issue #1923.
55378 if (opacityDefault === 0) opacityDefault = 1.0;
55381 function background(selection$$1) {
55383 function sortSources(a, b) {
55384 return a.best() && !b.best() ? -1
55385 : b.best() && !a.best() ? 1
55386 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0;
55390 function setOpacity(d) {
55391 var bg = context.container().selectAll('.layer-background')
55393 .style('opacity', d)
55394 .attr('data-opacity', d);
55396 if (!detected.opera) {
55397 utilSetTransform(bg, 0, 0);
55400 opacityList.selectAll('li')
55401 .classed('active', function(_) { return _ === d; });
55403 context.storage('background-opacity', d);
55407 function setTooltips(selection$$1) {
55408 selection$$1.each(function(d, i, nodes) {
55409 var item = select(this).select('label'),
55410 placement = (i < nodes.length / 2) ? 'bottom' : 'top';
55412 if (d === previous) {
55413 item.call(tooltip()
55414 .placement(placement)
55416 .title(function() {
55417 var tip = '<div>' + t('background.switch') + '</div>';
55418 return uiTooltipHtml(tip, uiCmd('⌘B'));
55421 } else if (d.description) {
55422 item.call(tooltip()
55423 .placement(placement)
55424 .title(d.description)
55427 item.call(tooltip().destroy);
55433 function selectLayer() {
55434 function active$$1(d) {
55435 return context.background().showsLayer(d);
55438 content.selectAll('.layer, .custom_layer')
55439 .classed('active', active$$1)
55440 .classed('switch', function(d) { return d === previous; })
55442 .selectAll('input')
55443 .property('checked', active$$1);
55447 function clickSetSource(d) {
55448 event.preventDefault();
55449 previous = context.background().baseLayerSource();
55450 context.background().baseLayerSource(d);
55452 document.activeElement.blur();
55456 function editCustom() {
55457 event.preventDefault();
55458 var template = window.prompt(t('background.custom_prompt'), customTemplate);
55460 setCustom(template);
55467 function setCustom(template) {
55468 context.storage('background-custom-template', template);
55469 var d = rendererBackgroundSource.Custom(template);
55470 content.selectAll('.custom_layer').datum(d);
55475 function clickSetOverlay(d) {
55476 event.preventDefault();
55477 context.background().toggleOverlayLayer(d);
55479 document.activeElement.blur();
55483 function drawList(layerList, type, change, filter) {
55484 var sources = context.background()
55485 .sources(context.map().extent())
55488 var layerLinks = layerList.selectAll('li.layer')
55489 .data(sources, function(d) { return d.name(); });
55494 var enter = layerLinks.enter()
55495 .insert('li', '.custom_layer')
55496 .attr('class', 'layer')
55497 .classed('best', function(d) { return d.best(); });
55499 enter.filter(function(d) { return d.best(); })
55501 .attr('class', 'best')
55503 .title(t('background.best_imagery'))
55504 .placement((textDirection === 'rtl') ? 'right' : 'left'))
55513 .attr('type', type)
55514 .attr('name', 'layers')
55515 .on('change', change);
55519 .text(function(d) { return d.name(); });
55522 layerList.selectAll('li.layer')
55524 .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
55528 function update() {
55529 backgroundList.call(drawList, 'radio', clickSetSource, function(d) { return !d.overlay; });
55530 overlayList.call(drawList, 'checkbox', clickSetOverlay, function(d) { return d.overlay; });
55534 var source = context.background().baseLayerSource();
55535 if (source.id === 'custom') {
55536 customTemplate = source.template;
55543 function updateOffsetVal() {
55544 var meters = geoOffsetToMeters(context.background().offset()),
55545 x = +meters[0].toFixed(2),
55546 y = +meters[1].toFixed(2);
55548 selectAll('.nudge-inner-rect')
55550 .classed('error', false)
55551 .property('value', x + ', ' + y);
55553 selectAll('.nudge-reset')
55554 .classed('disabled', function() {
55555 return (x === 0 && y === 0);
55560 function resetOffset() {
55561 if (event.button !== 0) return;
55562 context.background().offset([0, 0]);
55567 function nudge(d) {
55568 context.background().nudge(d, context.map().zoom());
55573 function buttonOffset(d) {
55574 if (event.button !== 0) return;
55575 var timeout$$1 = window.setTimeout(function() {
55576 interval$$1 = window.setInterval(nudge.bind(null, d), 100);
55580 function doneNudge() {
55581 window.clearTimeout(timeout$$1);
55582 window.clearInterval(interval$$1);
55584 .on('mouseup.buttonoffset', null, true)
55585 .on('mousedown.buttonoffset', null, true);
55589 .on('mouseup.buttonoffset', doneNudge, true)
55590 .on('mousedown.buttonoffset', doneNudge, true);
55596 function inputOffset() {
55597 if (event.button !== 0) return;
55598 var input = select(this);
55599 var d = input.node().value;
55601 if (d === '') return resetOffset();
55603 d = d.replace(/;/g, ',').split(',').map(function(n) {
55604 // if n is NaN, it will always get mapped to false.
55605 return !isNaN(n) && n;
55608 if (d.length !== 2 || !d[0] || !d[1]) {
55609 input.classed('error', true);
55613 context.background().offset(geoMetersToOffset(d));
55618 function dragOffset() {
55619 if (event.button !== 0) return;
55620 var origin = [event.clientX, event.clientY];
55622 context.container()
55624 .attr('class', 'nudge-surface');
55627 .on('mousemove.offset', function() {
55628 var latest = [event.clientX, event.clientY];
55630 -(origin[0] - latest[0]) / 4,
55631 -(origin[1] - latest[1]) / 4
55637 .on('mouseup.offset', function() {
55638 if (event.button !== 0) return;
55639 selectAll('.nudge-surface')
55643 .on('mousemove.offset', null)
55644 .on('mouseup.offset', null);
55647 event.preventDefault();
55656 function toggle() {
55657 if (event) event.preventDefault();
55658 tooltipBehavior.hide(button);
55659 setVisible(!button.classed('active'));
55663 function quickSwitch() {
55665 clickSetSource(previous);
55670 function setVisible(show) {
55671 if (show !== shown) {
55672 button.classed('active', show);
55676 selection$$1.on('mousedown.background-inside', function() {
55677 event.stopPropagation();
55680 .style('display', 'block')
55681 .style('right', '-300px')
55684 .style('right', '0px');
55687 .style('display', 'block')
55688 .style('right', '0px')
55691 .style('right', '-300px')
55692 .on('end', function() {
55693 select(this).style('display', 'none');
55695 selection$$1.on('mousedown.background-inside', null);
55701 var content = selection$$1
55703 .attr('class', 'fillL map-overlay col3 content hide'),
55704 tooltipBehavior = tooltip()
55705 .placement((textDirection === 'rtl') ? 'right' : 'left')
55707 .title(uiTooltipHtml(t('background.description'), key)),
55708 button = selection$$1
55710 .attr('tabindex', -1)
55711 .on('click', toggle)
55712 .call(svgIcon('#icon-layers', 'light'))
55713 .call(tooltipBehavior),
55717 /* opacity switcher */
55719 var opawrap = content
55721 .attr('class', 'opacity-options-wrapper');
55725 .text(t('background.title'));
55727 var opacityList = opawrap
55729 .attr('class', 'opacity-options');
55731 opacityList.selectAll('div.opacity')
55735 .attr('data-original-title', function(d) {
55736 return t('background.percent_brightness', { opacity: (d * 100) });
55738 .on('click.set-opacity', setOpacity)
55739 .html('<div class="select-box"></div>')
55741 .placement((textDirection === 'rtl') ? 'right' : 'left'))
55743 .attr('class', 'opacity')
55744 .style('opacity', function(d) { return 1.25 - d; });
55747 /* background switcher */
55749 var backgroundList = content
55751 .attr('class', 'layer-list')
55752 .attr('dir', 'auto');
55754 var custom = backgroundList
55756 .attr('class', 'custom_layer')
55757 .datum(rendererBackgroundSource.Custom());
55761 .attr('class', 'layer-browse')
55763 .title(t('background.custom_button'))
55764 .placement((textDirection === 'rtl') ? 'right' : 'left'))
55765 .on('click', editCustom)
55766 .call(svgIcon('#icon-search'));
55773 .attr('type', 'radio')
55774 .attr('name', 'layers')
55775 .on('change', function () {
55776 if (customTemplate) {
55777 setCustom(customTemplate);
55785 .text(t('background.custom'));
55789 .attr('class', 'imagery-faq')
55791 .attr('target', '_blank')
55792 .attr('tabindex', -1)
55793 .call(svgIcon('#icon-out-link', 'inline'))
55794 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
55796 .text(t('background.imagery_source_faq'));
55798 var overlayList = content
55800 .attr('class', 'layer-list');
55802 var controls = content
55804 .attr('class', 'controls-list');
55807 /* minimap toggle */
55809 var minimapLabel = controls
55813 .title(uiTooltipHtml(t('background.minimap.tooltip'), '/'))
55818 .classed('minimap-toggle', true)
55820 .attr('type', 'checkbox')
55821 .on('change', function() {
55822 uiMapInMap.toggle();
55823 event.preventDefault();
55828 .text(t('background.minimap.description'));
55831 /* imagery offset controls */
55833 var adjustments = content
55835 .attr('class', 'adjustments');
55839 .text(t('background.fix_misalignment'))
55841 .classed('hide-toggle', true)
55842 .classed('expanded', false)
55843 .on('click', function() {
55844 if (event.button !== 0) return;
55845 var exp = select(this).classed('expanded');
55846 nudgeContainer.style('display', exp ? 'none' : 'block');
55847 select(this).classed('expanded', !exp);
55848 event.preventDefault();
55851 var nudgeContainer = adjustments
55853 .attr('class', 'nudge-container cf')
55854 .style('display', 'none');
55858 .attr('class', 'nudge-instructions')
55859 .text(t('background.offset'));
55861 var nudgeRect = nudgeContainer
55863 .attr('class', 'nudge-outer-rect')
55864 .on('mousedown', dragOffset);
55868 .attr('class', 'nudge-inner-rect')
55870 .on('change', inputOffset)
55871 .on('mousedown', function() {
55872 if (event.button !== 0) return;
55873 event.stopPropagation();
55878 .selectAll('button')
55879 .data(directions).enter()
55881 .attr('class', function(d) { return d[0] + ' nudge'; })
55882 .on('mousedown', function(d) {
55883 if (event.button !== 0) return;
55884 buttonOffset(d[1]);
55889 .attr('title', t('background.reset'))
55890 .attr('class', 'nudge-reset disabled')
55891 .on('click', resetOffset)
55893 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
55897 .on('move.background-update', lodash.debounce(update, 1000));
55899 context.background()
55900 .on('change.background-update', update);
55904 setOpacity(opacityDefault);
55906 var keybinding = d3keybinding('background')
55908 .on(uiCmd('⌘B'), quickSwitch)
55915 context.surface().on('mousedown.background-outside', hide);
55916 context.container().on('mousedown.background-outside', hide);
55922 function uiContributors(context) {
55923 var debouncedUpdate = lodash.debounce(function() { update(); }, 1000),
55926 wrap = select(null);
55929 function update() {
55931 entities = context.intersects(context.map().extent());
55933 entities.forEach(function(entity) {
55934 if (entity && entity.user) users[entity.user] = true;
55937 var u = Object.keys(users),
55938 subset = u.slice(0, u.length > limit ? limit - 1 : limit);
55941 .call(svgIcon('#icon-nearby', 'pre-text light'));
55943 var userList = select(document.createElement('span'));
55945 userList.selectAll()
55949 .attr('class', 'user-link')
55950 .attr('href', function(d) { return context.connection().userURL(d); })
55951 .attr('target', '_blank')
55952 .attr('tabindex', -1)
55955 if (u.length > limit) {
55956 var count = select(document.createElement('span'));
55959 .attr('target', '_blank')
55960 .attr('tabindex', -1)
55961 .attr('href', function() {
55962 return context.connection().changesetsURL(context.map().center(), context.map().zoom());
55964 .text(u.length - limit + 1);
55966 wrap.append('span')
55967 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
55970 wrap.append('span')
55971 .html(t('contributors.list', { users: userList.html() }));
55978 .style('opacity', 0);
55980 } else if (hidden) {
55983 .style('opacity', 1);
55988 return function(selection$$1) {
55989 wrap = selection$$1;
55992 context.connection().on('loaded.contributors', debouncedUpdate);
55993 context.map().on('move.contributors', debouncedUpdate);
55997 function uiFeatureInfo(context) {
55998 function update(selection$$1) {
55999 var features = context.features(),
56000 stats = features.stats(),
56002 hiddenList = lodash.compact(lodash.map(features.hidden(), function(k) {
56005 return String(stats[k]) + ' ' + t('feature.' + k + '.description');
56009 selection$$1.html('');
56011 if (hiddenList.length) {
56012 var tooltipBehavior = tooltip()
56015 .title(function() {
56016 return uiTooltipHtml(hiddenList.join('<br/>'));
56019 var warning = selection$$1.append('a')
56021 .attr('tabindex', -1)
56022 .html(t('feature_info.hidden_warning', { count: count }))
56023 .call(tooltipBehavior)
56024 .on('click', function() {
56025 tooltipBehavior.hide(warning);
56026 // open map data panel?
56027 event.preventDefault();
56032 .classed('hide', !hiddenList.length);
56036 return function(selection$$1) {
56037 update(selection$$1);
56039 context.features().on('change.feature_info', function() {
56040 update(selection$$1);
56045 function uiFullScreen(context) {
56046 var element = context.container().node(),
56047 keybinding = d3keybinding('full-screen');
56051 function getFullScreenFn() {
56052 if (element.requestFullscreen) {
56053 return element.requestFullscreen;
56054 } else if (element.msRequestFullscreen) {
56055 return element.msRequestFullscreen;
56056 } else if (element.mozRequestFullScreen) {
56057 return element.mozRequestFullScreen;
56058 } else if (element.webkitRequestFullscreen) {
56059 return element.webkitRequestFullscreen;
56064 function getExitFullScreenFn() {
56065 if (document.exitFullscreen) {
56066 return document.exitFullscreen;
56067 } else if (document.msExitFullscreen) {
56068 return document.msExitFullscreen;
56069 } else if (document.mozCancelFullScreen) {
56070 return document.mozCancelFullScreen;
56071 } else if (document.webkitExitFullscreen) {
56072 return document.webkitExitFullscreen;
56077 function isFullScreen() {
56078 return document.fullscreenElement ||
56079 document.mozFullScreenElement ||
56080 document.webkitFullscreenElement ||
56081 document.msFullscreenElement;
56085 function isSupported() {
56086 return !!getFullScreenFn();
56090 function fullScreen() {
56091 event.preventDefault();
56092 if (!isFullScreen()) {
56093 // button.classed('active', true);
56094 getFullScreenFn().apply(element);
56096 // button.classed('active', false);
56097 getExitFullScreenFn().apply(document);
56102 return function() { // selection) {
56103 if (!isSupported())
56106 // button = selection.append('button')
56107 // .attr('title', t('full_screen'))
56108 // .attr('tabindex', -1)
56109 // .on('click', fullScreen)
56112 // button.append('span')
56113 // .attr('class', 'icon full-screen');
56116 .on('f11', fullScreen)
56117 .on(uiCmd('⌘⇧F'), fullScreen);
56124 function uiModal(selection$$1, blocking) {
56125 var keybinding = d3keybinding('modal');
56126 var previous = selection$$1.select('div.modal');
56127 var animate = previous.empty();
56129 previous.transition()
56131 .style('opacity', 0)
56134 var shaded = selection$$1
56136 .attr('class', 'shaded')
56137 .style('opacity', 0);
56139 shaded.close = function() {
56143 .style('opacity',0)
56149 .style('top','0px');
56157 .attr('class', 'modal fillL col6');
56160 shaded.on('click.remove-modal', function() {
56161 if (event.target === this) {
56166 modal.append('button')
56167 .attr('class', 'close')
56168 .on('click', shaded.close)
56169 .call(svgIcon('#icon-close'));
56172 .on('⌫', shaded.close)
56173 .on('⎋', shaded.close);
56181 .attr('class', 'content');
56184 shaded.transition().style('opacity', 1);
56186 shaded.style('opacity', 1);
56193 function uiLoading(context) {
56199 var loading = function(selection) {
56200 modalSelection = uiModal(selection, blocking);
56202 var loadertext = modalSelection.select('.content')
56203 .classed('loading-modal', true)
56205 .attr('class', 'modal-section fillL');
56209 .attr('class', 'loader')
56210 .attr('src', context.imagePath('loader-white.gif'));
56216 modalSelection.select('button.close')
56217 .attr('class', 'hide');
56223 loading.message = function(_) {
56224 if (!arguments.length) return message;
56230 loading.blocking = function(_) {
56231 if (!arguments.length) return blocking;
56237 loading.close = function() {
56238 modalSelection.remove();
56245 function uiGeolocate(context) {
56246 var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
56247 locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
56252 context.enter(modeBrowse(context));
56253 context.container().call(locating);
56254 navigator.geolocation.getCurrentPosition(success, error, geoOptions);
56256 // This timeout ensures that we still call finish() even if
56257 // the user declines to share their location in Firefox
56258 timeoutId = setTimeout(finish, 10000 /* 10sec */ );
56262 function success(position) {
56263 var map = context.map(),
56264 extent = geoExtent$$1([position.coords.longitude, position.coords.latitude])
56265 .padByMeters(position.coords.accuracy);
56267 map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
56277 function finish() {
56278 locating.close(); // unblock ui
56279 if (timeoutId) { clearTimeout(timeoutId); }
56280 timeoutId = undefined;
56284 return function(selection) {
56285 if (!navigator.geolocation) return;
56289 .attr('tabindex', -1)
56290 .attr('title', t('geolocate.title'))
56291 .on('click', click)
56292 .call(svgIcon('#icon-geolocate', 'light'))
56294 .placement((textDirection === 'rtl') ? 'right' : 'left'));
56298 var marked = createCommonjsModule(function (module, exports) {
56300 * marked - a markdown parser
56301 * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
56302 * https://github.com/chjj/marked
56308 * Block-Level Grammar
56313 code: /^( {4}[^\n]+\n*)+/,
56315 hr: /^( *[-*_]){3,} *(?:\n+|$)/,
56316 heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
56318 lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
56319 blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
56320 list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
56321 html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
56322 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
56324 paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
56328 block.bullet = /(?:[*+-]|\d+\.)/;
56329 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
56330 block.item = replace(block.item, 'gm')
56331 (/bull/g, block.bullet)
56334 block.list = replace(block.list)
56335 (/bull/g, block.bullet)
56336 ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
56337 ('def', '\\n+(?=' + block.def.source + ')')
56340 block.blockquote = replace(block.blockquote)
56344 block._tag = '(?!(?:'
56345 + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
56346 + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
56347 + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
56349 block.html = replace(block.html)
56350 ('comment', /<!--[\s\S]*?-->/)
56351 ('closed', /<(tag)[\s\S]+?<\/\1>/)
56352 ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
56353 (/tag/g, block._tag)
56356 block.paragraph = replace(block.paragraph)
56358 ('heading', block.heading)
56359 ('lheading', block.lheading)
56360 ('blockquote', block.blockquote)
56361 ('tag', '<' + block._tag)
56366 * Normal Block Grammar
56369 block.normal = merge({}, block);
56372 * GFM Block Grammar
56375 block.gfm = merge({}, block.normal, {
56376 fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
56378 heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
56381 block.gfm.paragraph = replace(block.paragraph)
56383 + block.gfm.fences.source.replace('\\1', '\\2') + '|'
56384 + block.list.source.replace('\\1', '\\3') + '|')
56388 * GFM + Tables Block Grammar
56391 block.tables = merge({}, block.gfm, {
56392 nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
56393 table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
56400 function Lexer(options) {
56402 this.tokens.links = {};
56403 this.options = options || marked.defaults;
56404 this.rules = block.normal;
56406 if (this.options.gfm) {
56407 if (this.options.tables) {
56408 this.rules = block.tables;
56410 this.rules = block.gfm;
56416 * Expose Block Rules
56419 Lexer.rules = block;
56422 * Static Lex Method
56425 Lexer.lex = function(src, options) {
56426 var lexer = new Lexer(options);
56427 return lexer.lex(src);
56434 Lexer.prototype.lex = function(src) {
56436 .replace(/\r\n|\r/g, '\n')
56437 .replace(/\t/g, ' ')
56438 .replace(/\u00a0/g, ' ')
56439 .replace(/\u2424/g, '\n');
56441 return this.token(src, true);
56448 Lexer.prototype.token = function(src, top, bq) {
56449 var src = src.replace(/^ +$/gm, '')
56462 if (cap = this.rules.newline.exec(src)) {
56463 src = src.substring(cap[0].length);
56464 if (cap[0].length > 1) {
56472 if (cap = this.rules.code.exec(src)) {
56473 src = src.substring(cap[0].length);
56474 cap = cap[0].replace(/^ {4}/gm, '');
56477 text: !this.options.pedantic
56478 ? cap.replace(/\n+$/, '')
56485 if (cap = this.rules.fences.exec(src)) {
56486 src = src.substring(cap[0].length);
56496 if (cap = this.rules.heading.exec(src)) {
56497 src = src.substring(cap[0].length);
56500 depth: cap[1].length,
56506 // table no leading pipe (gfm)
56507 if (top && (cap = this.rules.nptable.exec(src))) {
56508 src = src.substring(cap[0].length);
56512 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
56513 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
56514 cells: cap[3].replace(/\n$/, '').split('\n')
56517 for (i = 0; i < item.align.length; i++) {
56518 if (/^ *-+: *$/.test(item.align[i])) {
56519 item.align[i] = 'right';
56520 } else if (/^ *:-+: *$/.test(item.align[i])) {
56521 item.align[i] = 'center';
56522 } else if (/^ *:-+ *$/.test(item.align[i])) {
56523 item.align[i] = 'left';
56525 item.align[i] = null;
56529 for (i = 0; i < item.cells.length; i++) {
56530 item.cells[i] = item.cells[i].split(/ *\| */);
56533 this.tokens.push(item);
56539 if (cap = this.rules.lheading.exec(src)) {
56540 src = src.substring(cap[0].length);
56543 depth: cap[2] === '=' ? 1 : 2,
56550 if (cap = this.rules.hr.exec(src)) {
56551 src = src.substring(cap[0].length);
56559 if (cap = this.rules.blockquote.exec(src)) {
56560 src = src.substring(cap[0].length);
56563 type: 'blockquote_start'
56566 cap = cap[0].replace(/^ *> ?/gm, '');
56568 // Pass `top` to keep the current
56569 // "toplevel" state. This is exactly
56570 // how markdown.pl works.
56571 this.token(cap, top, true);
56574 type: 'blockquote_end'
56581 if (cap = this.rules.list.exec(src)) {
56582 src = src.substring(cap[0].length);
56586 type: 'list_start',
56587 ordered: bull.length > 1
56590 // Get each top-level item.
56591 cap = cap[0].match(this.rules.item);
56597 for (; i < l; i++) {
56600 // Remove the list item's bullet
56601 // so it is seen as the next token.
56602 space = item.length;
56603 item = item.replace(/^ *([*+-]|\d+\.) +/, '');
56605 // Outdent whatever the
56606 // list item contains. Hacky.
56607 if (~item.indexOf('\n ')) {
56608 space -= item.length;
56609 item = !this.options.pedantic
56610 ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
56611 : item.replace(/^ {1,4}/gm, '');
56614 // Determine whether the next list item belongs here.
56615 // Backpedal if it does not belong in this list.
56616 if (this.options.smartLists && i !== l - 1) {
56617 b = block.bullet.exec(cap[i + 1])[0];
56618 if (bull !== b && !(bull.length > 1 && b.length > 1)) {
56619 src = cap.slice(i + 1).join('\n') + src;
56624 // Determine whether item is loose or not.
56625 // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
56626 // for discount behavior.
56627 loose = next || /\n\n(?!\s*$)/.test(item);
56629 next = item.charAt(item.length - 1) === '\n';
56630 if (!loose) loose = next;
56635 ? 'loose_item_start'
56636 : 'list_item_start'
56640 this.token(item, false, bq);
56643 type: 'list_item_end'
56655 if (cap = this.rules.html.exec(src)) {
56656 src = src.substring(cap[0].length);
56658 type: this.options.sanitize
56661 pre: !this.options.sanitizer
56662 && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
56669 if ((!bq && top) && (cap = this.rules.def.exec(src))) {
56670 src = src.substring(cap[0].length);
56671 this.tokens.links[cap[1].toLowerCase()] = {
56679 if (top && (cap = this.rules.table.exec(src))) {
56680 src = src.substring(cap[0].length);
56684 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
56685 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
56686 cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
56689 for (i = 0; i < item.align.length; i++) {
56690 if (/^ *-+: *$/.test(item.align[i])) {
56691 item.align[i] = 'right';
56692 } else if (/^ *:-+: *$/.test(item.align[i])) {
56693 item.align[i] = 'center';
56694 } else if (/^ *:-+ *$/.test(item.align[i])) {
56695 item.align[i] = 'left';
56697 item.align[i] = null;
56701 for (i = 0; i < item.cells.length; i++) {
56702 item.cells[i] = item.cells[i]
56703 .replace(/^ *\| *| *\| *$/g, '')
56707 this.tokens.push(item);
56712 // top-level paragraph
56713 if (top && (cap = this.rules.paragraph.exec(src))) {
56714 src = src.substring(cap[0].length);
56717 text: cap[1].charAt(cap[1].length - 1) === '\n'
56718 ? cap[1].slice(0, -1)
56725 if (cap = this.rules.text.exec(src)) {
56726 // Top-level should never reach here.
56727 src = src.substring(cap[0].length);
56737 Error('Infinite loop on byte: ' + src.charCodeAt(0));
56741 return this.tokens;
56745 * Inline-Level Grammar
56749 escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
56750 autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
56752 tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
56753 link: /^!?\[(inside)\]\(href\)/,
56754 reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
56755 nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
56756 strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
56757 em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
56758 code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
56759 br: /^ {2,}\n(?!\s*$)/,
56761 text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
56764 inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
56765 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
56767 inline.link = replace(inline.link)
56768 ('inside', inline._inside)
56769 ('href', inline._href)
56772 inline.reflink = replace(inline.reflink)
56773 ('inside', inline._inside)
56777 * Normal Inline Grammar
56780 inline.normal = merge({}, inline);
56783 * Pedantic Inline Grammar
56786 inline.pedantic = merge({}, inline.normal, {
56787 strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
56788 em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
56792 * GFM Inline Grammar
56795 inline.gfm = merge({}, inline.normal, {
56796 escape: replace(inline.escape)('])', '~|])')(),
56797 url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
56798 del: /^~~(?=\S)([\s\S]*?\S)~~/,
56799 text: replace(inline.text)
56801 ('|', '|https?://|')
56806 * GFM + Line Breaks Inline Grammar
56809 inline.breaks = merge({}, inline.gfm, {
56810 br: replace(inline.br)('{2,}', '*')(),
56811 text: replace(inline.gfm.text)('{2,}', '*')()
56815 * Inline Lexer & Compiler
56818 function InlineLexer(links, options) {
56819 this.options = options || marked.defaults;
56820 this.links = links;
56821 this.rules = inline.normal;
56822 this.renderer = this.options.renderer || new Renderer;
56823 this.renderer.options = this.options;
56827 Error('Tokens array requires a `links` property.');
56830 if (this.options.gfm) {
56831 if (this.options.breaks) {
56832 this.rules = inline.breaks;
56834 this.rules = inline.gfm;
56836 } else if (this.options.pedantic) {
56837 this.rules = inline.pedantic;
56842 * Expose Inline Rules
56845 InlineLexer.rules = inline;
56848 * Static Lexing/Compiling Method
56851 InlineLexer.output = function(src, links, options) {
56852 var inline = new InlineLexer(links, options);
56853 return inline.output(src);
56860 InlineLexer.prototype.output = function(src) {
56869 if (cap = this.rules.escape.exec(src)) {
56870 src = src.substring(cap[0].length);
56876 if (cap = this.rules.autolink.exec(src)) {
56877 src = src.substring(cap[0].length);
56878 if (cap[2] === '@') {
56879 text = cap[1].charAt(6) === ':'
56880 ? this.mangle(cap[1].substring(7))
56881 : this.mangle(cap[1]);
56882 href = this.mangle('mailto:') + text;
56884 text = escape(cap[1]);
56887 out += this.renderer.link(href, null, text);
56892 if (!this.inLink && (cap = this.rules.url.exec(src))) {
56893 src = src.substring(cap[0].length);
56894 text = escape(cap[1]);
56896 out += this.renderer.link(href, null, text);
56901 if (cap = this.rules.tag.exec(src)) {
56902 if (!this.inLink && /^<a /i.test(cap[0])) {
56903 this.inLink = true;
56904 } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
56905 this.inLink = false;
56907 src = src.substring(cap[0].length);
56908 out += this.options.sanitize
56909 ? this.options.sanitizer
56910 ? this.options.sanitizer(cap[0])
56917 if (cap = this.rules.link.exec(src)) {
56918 src = src.substring(cap[0].length);
56919 this.inLink = true;
56920 out += this.outputLink(cap, {
56924 this.inLink = false;
56929 if ((cap = this.rules.reflink.exec(src))
56930 || (cap = this.rules.nolink.exec(src))) {
56931 src = src.substring(cap[0].length);
56932 link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
56933 link = this.links[link.toLowerCase()];
56934 if (!link || !link.href) {
56935 out += cap[0].charAt(0);
56936 src = cap[0].substring(1) + src;
56939 this.inLink = true;
56940 out += this.outputLink(cap, link);
56941 this.inLink = false;
56946 if (cap = this.rules.strong.exec(src)) {
56947 src = src.substring(cap[0].length);
56948 out += this.renderer.strong(this.output(cap[2] || cap[1]));
56953 if (cap = this.rules.em.exec(src)) {
56954 src = src.substring(cap[0].length);
56955 out += this.renderer.em(this.output(cap[2] || cap[1]));
56960 if (cap = this.rules.code.exec(src)) {
56961 src = src.substring(cap[0].length);
56962 out += this.renderer.codespan(escape(cap[2], true));
56967 if (cap = this.rules.br.exec(src)) {
56968 src = src.substring(cap[0].length);
56969 out += this.renderer.br();
56974 if (cap = this.rules.del.exec(src)) {
56975 src = src.substring(cap[0].length);
56976 out += this.renderer.del(this.output(cap[1]));
56981 if (cap = this.rules.text.exec(src)) {
56982 src = src.substring(cap[0].length);
56983 out += this.renderer.text(escape(this.smartypants(cap[0])));
56989 Error('Infinite loop on byte: ' + src.charCodeAt(0));
57000 InlineLexer.prototype.outputLink = function(cap, link) {
57001 var href = escape(link.href)
57002 , title = link.title ? escape(link.title) : null;
57004 return cap[0].charAt(0) !== '!'
57005 ? this.renderer.link(href, title, this.output(cap[1]))
57006 : this.renderer.image(href, title, escape(cap[1]));
57010 * Smartypants Transformations
57013 InlineLexer.prototype.smartypants = function(text) {
57014 if (!this.options.smartypants) return text;
57017 .replace(/---/g, '\u2014')
57019 .replace(/--/g, '\u2013')
57021 .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
57022 // closing singles & apostrophes
57023 .replace(/'/g, '\u2019')
57025 .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
57027 .replace(/"/g, '\u201d')
57029 .replace(/\.{3}/g, '\u2026');
57036 InlineLexer.prototype.mangle = function(text) {
57037 if (!this.options.mangle) return text;
57043 for (; i < l; i++) {
57044 ch = text.charCodeAt(i);
57045 if (Math.random() > 0.5) {
57046 ch = 'x' + ch.toString(16);
57048 out += '&#' + ch + ';';
57058 function Renderer(options) {
57059 this.options = options || {};
57062 Renderer.prototype.code = function(code, lang, escaped) {
57063 if (this.options.highlight) {
57064 var out = this.options.highlight(code, lang);
57065 if (out != null && out !== code) {
57072 return '<pre><code>'
57073 + (escaped ? code : escape(code, true))
57074 + '\n</code></pre>';
57077 return '<pre><code class="'
57078 + this.options.langPrefix
57079 + escape(lang, true)
57081 + (escaped ? code : escape(code, true))
57082 + '\n</code></pre>\n';
57085 Renderer.prototype.blockquote = function(quote) {
57086 return '<blockquote>\n' + quote + '</blockquote>\n';
57089 Renderer.prototype.html = function(html) {
57093 Renderer.prototype.heading = function(text, level, raw) {
57097 + this.options.headerPrefix
57098 + raw.toLowerCase().replace(/[^\w]+/g, '-')
57106 Renderer.prototype.hr = function() {
57107 return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
57110 Renderer.prototype.list = function(body, ordered) {
57111 var type = ordered ? 'ol' : 'ul';
57112 return '<' + type + '>\n' + body + '</' + type + '>\n';
57115 Renderer.prototype.listitem = function(text) {
57116 return '<li>' + text + '</li>\n';
57119 Renderer.prototype.paragraph = function(text) {
57120 return '<p>' + text + '</p>\n';
57123 Renderer.prototype.table = function(header, body) {
57134 Renderer.prototype.tablerow = function(content) {
57135 return '<tr>\n' + content + '</tr>\n';
57138 Renderer.prototype.tablecell = function(content, flags) {
57139 var type = flags.header ? 'th' : 'td';
57140 var tag = flags.align
57141 ? '<' + type + ' style="text-align:' + flags.align + '">'
57142 : '<' + type + '>';
57143 return tag + content + '</' + type + '>\n';
57146 // span level renderer
57147 Renderer.prototype.strong = function(text) {
57148 return '<strong>' + text + '</strong>';
57151 Renderer.prototype.em = function(text) {
57152 return '<em>' + text + '</em>';
57155 Renderer.prototype.codespan = function(text) {
57156 return '<code>' + text + '</code>';
57159 Renderer.prototype.br = function() {
57160 return this.options.xhtml ? '<br/>' : '<br>';
57163 Renderer.prototype.del = function(text) {
57164 return '<del>' + text + '</del>';
57167 Renderer.prototype.link = function(href, title, text) {
57168 if (this.options.sanitize) {
57170 var prot = decodeURIComponent(unescape(href))
57171 .replace(/[^\w:]/g, '')
57176 if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
57180 var out = '<a href="' + href + '"';
57182 out += ' title="' + title + '"';
57184 out += '>' + text + '</a>';
57188 Renderer.prototype.image = function(href, title, text) {
57189 var out = '<img src="' + href + '" alt="' + text + '"';
57191 out += ' title="' + title + '"';
57193 out += this.options.xhtml ? '/>' : '>';
57197 Renderer.prototype.text = function(text) {
57202 * Parsing & Compiling
57205 function Parser(options) {
57208 this.options = options || marked.defaults;
57209 this.options.renderer = this.options.renderer || new Renderer;
57210 this.renderer = this.options.renderer;
57211 this.renderer.options = this.options;
57215 * Static Parse Method
57218 Parser.parse = function(src, options, renderer) {
57219 var parser = new Parser(options, renderer);
57220 return parser.parse(src);
57227 Parser.prototype.parse = function(src) {
57228 this.inline = new InlineLexer(src.links, this.options, this.renderer);
57229 this.tokens = src.reverse();
57232 while (this.next()) {
57243 Parser.prototype.next = function() {
57244 return this.token = this.tokens.pop();
57248 * Preview Next Token
57251 Parser.prototype.peek = function() {
57252 return this.tokens[this.tokens.length - 1] || 0;
57256 * Parse Text Tokens
57259 Parser.prototype.parseText = function() {
57260 var body = this.token.text;
57262 while (this.peek().type === 'text') {
57263 body += '\n' + this.next().text;
57266 return this.inline.output(body);
57270 * Parse Current Token
57273 Parser.prototype.tok = function() {
57274 switch (this.token.type) {
57279 return this.renderer.hr();
57282 return this.renderer.heading(
57283 this.inline.output(this.token.text),
57288 return this.renderer.code(this.token.text,
57290 this.token.escaped);
57303 for (i = 0; i < this.token.header.length; i++) {
57304 flags = { header: true, align: this.token.align[i] };
57305 cell += this.renderer.tablecell(
57306 this.inline.output(this.token.header[i]),
57307 { header: true, align: this.token.align[i] }
57310 header += this.renderer.tablerow(cell);
57312 for (i = 0; i < this.token.cells.length; i++) {
57313 row = this.token.cells[i];
57316 for (j = 0; j < row.length; j++) {
57317 cell += this.renderer.tablecell(
57318 this.inline.output(row[j]),
57319 { header: false, align: this.token.align[j] }
57323 body += this.renderer.tablerow(cell);
57325 return this.renderer.table(header, body);
57327 case 'blockquote_start': {
57330 while (this.next().type !== 'blockquote_end') {
57331 body += this.tok();
57334 return this.renderer.blockquote(body);
57336 case 'list_start': {
57338 , ordered = this.token.ordered;
57340 while (this.next().type !== 'list_end') {
57341 body += this.tok();
57344 return this.renderer.list(body, ordered);
57346 case 'list_item_start': {
57349 while (this.next().type !== 'list_item_end') {
57350 body += this.token.type === 'text'
57355 return this.renderer.listitem(body);
57357 case 'loose_item_start': {
57360 while (this.next().type !== 'list_item_end') {
57361 body += this.tok();
57364 return this.renderer.listitem(body);
57367 var html = !this.token.pre && !this.options.pedantic
57368 ? this.inline.output(this.token.text)
57370 return this.renderer.html(html);
57372 case 'paragraph': {
57373 return this.renderer.paragraph(this.inline.output(this.token.text));
57376 return this.renderer.paragraph(this.parseText());
57385 function escape(html, encode) {
57387 .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
57388 .replace(/</g, '<')
57389 .replace(/>/g, '>')
57390 .replace(/"/g, '"')
57391 .replace(/'/g, ''');
57394 function unescape(html) {
57395 // explicitly match decimal, hex, and named HTML entities
57396 return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
57397 n = n.toLowerCase();
57398 if (n === 'colon') return ':';
57399 if (n.charAt(0) === '#') {
57400 return n.charAt(1) === 'x'
57401 ? String.fromCharCode(parseInt(n.substring(2), 16))
57402 : String.fromCharCode(+n.substring(1));
57408 function replace(regex, opt) {
57409 regex = regex.source;
57411 return function self(name, val) {
57412 if (!name) return new RegExp(regex, opt);
57413 val = val.source || val;
57414 val = val.replace(/(^|[^\[])\^/g, '$1');
57415 regex = regex.replace(name, val);
57423 function merge(obj) {
57428 for (; i < arguments.length; i++) {
57429 target = arguments[i];
57430 for (key in target) {
57431 if (Object.prototype.hasOwnProperty.call(target, key)) {
57432 obj[key] = target[key];
57445 function marked(src, opt, callback) {
57446 if (callback || typeof opt === 'function') {
57452 opt = merge({}, marked.defaults, opt || {});
57454 var highlight = opt.highlight
57460 tokens = Lexer.lex(src, opt);
57462 return callback(e);
57465 pending = tokens.length;
57467 var done = function(err) {
57469 opt.highlight = highlight;
57470 return callback(err);
57476 out = Parser.parse(tokens, opt);
57481 opt.highlight = highlight;
57485 : callback(null, out);
57488 if (!highlight || highlight.length < 3) {
57492 delete opt.highlight;
57494 if (!pending) return done();
57496 for (; i < tokens.length; i++) {
57498 if (token.type !== 'code') {
57499 return --pending || done();
57501 return highlight(token.text, token.lang, function(err, code) {
57502 if (err) return done(err);
57503 if (code == null || code === token.text) {
57504 return --pending || done();
57507 token.escaped = true;
57508 --pending || done();
57516 if (opt) opt = merge({}, marked.defaults, opt);
57517 return Parser.parse(Lexer.lex(src, opt), opt);
57519 e.message += '\nPlease report this to https://github.com/chjj/marked.';
57520 if ((opt || marked.defaults).silent) {
57521 return '<p>An error occured:</p><pre>'
57522 + escape(e.message + '', true)
57534 marked.setOptions = function(opt) {
57535 merge(marked.defaults, opt);
57539 marked.defaults = {
57550 langPrefix: 'lang-',
57551 smartypants: false,
57553 renderer: new Renderer,
57561 marked.Parser = Parser;
57562 marked.parser = Parser.parse;
57564 marked.Renderer = Renderer;
57566 marked.Lexer = Lexer;
57567 marked.lexer = Lexer.lex;
57569 marked.InlineLexer = InlineLexer;
57570 marked.inlineLexer = InlineLexer.output;
57572 marked.parse = marked;
57575 module.exports = marked;
57578 }).call(function() {
57579 return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
57583 // toggles the visibility of ui elements, using a combination of the
57584 // hide class, which sets display=none, and a d3 transition for opacity.
57585 // this will cause blinking when called repeatedly, so check that the
57586 // value actually changes between calls.
57587 function uiToggle(show, callback) {
57588 return function(selection$$1) {
57590 .style('opacity', show ? 0 : 1)
57591 .classed('hide', false)
57593 .style('opacity', show ? 1 : 0)
57594 .on('end', function() {
57596 .classed('hide', !show)
57597 .style('opacity', null);
57598 if (callback) callback.apply(this);
57603 // Tooltips and svg mask used to highlight certain features
57604 function d3curtain() {
57606 var dispatch$$1 = dispatch(),
57607 surface = select(null),
57608 tooltip = select(null),
57609 darkness = select(null);
57611 function curtain(selection$$1) {
57612 surface = selection$$1
57614 .attr('id', 'curtain')
57615 .style('z-index', 1000)
57616 .style('pointer-events', 'none')
57617 .style('position', 'absolute')
57621 darkness = surface.append('path')
57624 .attr('class', 'curtain-darkness');
57626 select(window).on('resize.curtain', resize);
57628 tooltip = selection$$1.append('div')
57629 .attr('class', 'tooltip')
57630 .style('z-index', 1002);
57634 .attr('class', 'tooltip-arrow');
57638 .attr('class', 'tooltip-inner');
57643 function resize() {
57645 .attr('width', window.innerWidth)
57646 .attr('height', window.innerHeight);
57647 curtain.cut(darkness.datum());
57652 curtain.reveal = function(box, text$$1, tooltipclass, duration) {
57653 if (typeof box === 'string') box = select(box).node();
57654 if (box.getBoundingClientRect) box = box.getBoundingClientRect();
57656 curtain.cut(box, duration);
57659 // pseudo markdown bold text hack
57660 var parts = text$$1.split('**');
57661 var html$$1 = parts[0] ? '<span>' + parts[0] + '</span>' : '';
57662 if (parts[1]) html$$1 += '<span class="bold">' + parts[1] + '</span>';
57664 var selection$$1 = tooltip
57665 .classed('in', true)
57666 .selectAll('.tooltip-inner')
57669 var dimensions = utilGetDimensions(selection$$1, true),
57670 w = window.innerWidth,
57671 h = window.innerHeight,
57674 // trim box dimensions to just the portion that fits in the window..
57675 if (box.top + box.height > h) {
57676 box.height -= (box.top + box.height - h);
57678 if (box.left + box.width > w) {
57679 box.width -= (box.left + box.width - w);
57682 // determine tooltip placement..
57683 if (box.top + box.height < Math.min(100, box.width + box.left)) {
57685 pos = [box.left + box.width / 2 - dimensions[0] / 2, box.top + box.height];
57687 } else if (box.left + box.width + 300 < w) {
57689 pos = [box.left + box.width, box.top + box.height / 2 - dimensions[1] / 2];
57691 } else if (box.left > 300) {
57693 pos = [box.left - 200, box.top + box.height / 2 - dimensions[1] / 2];
57697 pos = [box.left, box.top + box.height];
57701 Math.min(Math.max(10, pos[0]), w - dimensions[0] - 10),
57702 Math.min(Math.max(10, pos[1]), h - dimensions[1] - 10)
57705 if (duration !== 0 || !tooltip.classed(side)) {
57706 tooltip.call(uiToggle(true));
57710 .style('top', pos[1] + 'px')
57711 .style('left', pos[0] + 'px')
57712 .attr('class', 'curtain-tooltip tooltip in ' + side + ' ' + tooltipclass);
57715 tooltip.call(uiToggle(false));
57720 curtain.cut = function(datum, duration) {
57721 darkness.datum(datum)
57724 (duration === 0 ? darkness : darkness.transition().duration(duration || 600))
57725 .attr('d', function(d) {
57726 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
57727 window.innerWidth + ',' + window.innerHeight + 'L' +
57728 window.innerWidth + ',0 Z';
57730 if (!d) return string;
57731 return string + 'M' +
57732 d.left + ',' + d.top + 'L' +
57733 d.left + ',' + (d.top + d.height) + 'L' +
57734 (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
57735 (d.left + d.width) + ',' + (d.top) + 'Z';
57741 curtain.remove = function() {
57747 return utilRebind(curtain, dispatch$$1, 'on');
57750 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"]}};
57752 function pointBox(point, context) {
57753 var rect = context.surfaceRect();
57754 point = context.projection(point);
57756 left: point[0] + rect.left - 30,
57757 top: point[1] + rect.top - 50,
57764 function pad$1(box, padding, context) {
57765 if (box instanceof Array) {
57766 var rect = context.surfaceRect();
57767 box = context.projection(box);
57769 left: box[0] + rect.left,
57770 top: box[1] + rect.top
57774 left: box.left - padding,
57775 top: box.top - padding,
57776 width: (box.width || 0) + 2 * padding,
57777 height: (box.width || 0) + 2 * padding
57782 function icon(name, svgklass) {
57783 return '<svg class="icon ' + (svgklass || '') + '">' +
57784 '<use xlink:href="' + name + '"></use></svg>';
57787 function uiIntroNavigation(context, reveal) {
57788 var dispatch$$1 = dispatch('done'),
57792 title: 'intro.navigation.title'
57796 function set$$1(f, t$$1) {
57797 timeouts.push(window.setTimeout(f, t$$1));
57801 function eventCancel() {
57802 event.stopPropagation();
57803 event.preventDefault();
57807 step.enter = function() {
57808 var rect = context.surfaceRect(),
57810 left: rect.left + 10,
57811 top: rect.top + 70,
57812 width: rect.width - 70,
57813 height: rect.height - 170
57816 context.map().centerZoom([-85.63591, 41.94285], 19);
57818 reveal(map$$1, t('intro.navigation.drag'));
57820 context.map().on('move.intro', lodash.debounce(function() {
57821 context.map().on('move.intro', null);
57823 context.on('enter.intro', inspectTownHall);
57827 function townhall() {
57828 var hall = [-85.63645945147184, 41.942986488012565];
57829 var point = context.projection(hall);
57831 if (point[0] < 0 || point[0] > rect.width ||
57832 point[1] < 0 || point[1] > rect.height) {
57833 context.map().center(hall);
57836 var box = pointBox(hall, context);
57837 reveal(box, t('intro.navigation.select'));
57839 context.map().on('move.intro', function() {
57840 var box = pointBox(hall, context);
57841 reveal(box, t('intro.navigation.select'), {duration: 0});
57846 function inspectTownHall(mode) {
57847 if (mode.id !== 'select') return;
57848 context.on('enter.intro', null);
57849 context.map().on('move.intro', null);
57850 set$$1(function() {
57851 reveal('.entity-editor-pane',
57852 t('intro.navigation.pane', { button: icon('#icon-close', 'pre-text') }));
57853 context.on('exit.intro', streetSearch);
57858 function streetSearch() {
57859 context.on('exit.intro', null);
57860 reveal('.search-header input',
57861 t('intro.navigation.search', { name: t('intro.graph.spring_st') }));
57862 select('.search-header input')
57863 .on('keyup.intro', searchResult);
57867 function searchResult() {
57868 var first = select('.feature-list-item:nth-child(0n+2)'), // skip No Results item
57869 firstName = first.select('.entity-name'),
57870 name = t('intro.graph.spring_st');
57872 if (!firstName.empty() && firstName.text() === name) {
57873 reveal(first.node(), t('intro.navigation.choose', { name: name }));
57874 context.on('exit.intro', selectedStreet);
57875 select('.search-header input')
57876 .on('keydown.intro', eventCancel, true)
57877 .on('keyup.intro', null);
57882 function selectedStreet() {
57883 var springSt = [-85.63585099140167, 41.942506848938926];
57884 context.map().center(springSt);
57885 context.on('exit.intro', function() {
57886 dispatch$$1.call('done');
57889 set$$1(function() {
57890 reveal('.entity-editor-pane',
57891 t('intro.navigation.chosen', {
57892 name: t('intro.graph.spring_st'),
57893 button: icon('#icon-close', 'pre-text')
57900 step.exit = function() {
57901 timeouts.forEach(window.clearTimeout);
57902 context.map().on('move.intro', null);
57903 context.on('enter.intro', null);
57904 context.on('exit.intro', null);
57905 select('.search-header input')
57906 .on('keydown.intro', null)
57907 .on('keyup.intro', null);
57911 return utilRebind(step, dispatch$$1, 'on');
57914 function uiIntroPoint(context, reveal) {
57915 var dispatch$$1 = dispatch('done'),
57919 title: 'intro.points.title'
57923 function setTimeout(f, t$$1) {
57924 timeouts.push(window.setTimeout(f, t$$1));
57928 function eventCancel() {
57929 event.stopPropagation();
57930 event.preventDefault();
57934 step.enter = function() {
57935 context.map().centerZoom([-85.63279, 41.94394], 19);
57936 reveal('button.add-point',
57937 t('intro.points.add', { button: icon('#icon-point', 'pre-text') }),
57938 { tooltipClass: 'intro-points-add' });
57940 var corner = [-85.632481,41.944094];
57942 context.on('enter.intro', addPoint);
57945 function addPoint(mode) {
57946 if (mode.id !== 'add-point') return;
57947 context.on('enter.intro', enterSelect);
57949 var pointBox$$1 = pad$1(corner, 150, context);
57950 reveal(pointBox$$1, t('intro.points.place'));
57952 context.map().on('move.intro', function() {
57953 pointBox$$1 = pad$1(corner, 150, context);
57954 reveal(pointBox$$1, t('intro.points.place'), {duration: 0});
57959 function enterSelect(mode) {
57960 if (mode.id !== 'select') return;
57961 context.map().on('move.intro', null);
57962 context.on('enter.intro', null);
57964 setTimeout(function() {
57965 reveal('.preset-search-input',
57966 t('intro.points.search', {name: context.presets().item('amenity/cafe').name()}));
57967 select('.preset-search-input').on('keyup.intro', keySearch);
57972 function keySearch() {
57973 var first = select('.preset-list-item:first-child');
57974 if (first.classed('preset-amenity-cafe')) {
57975 reveal(first.select('.preset-list-button').node(), t('intro.points.choose'));
57976 utilBindOnce(context.history(), 'change.intro', selectedPreset);
57977 select('.preset-search-input')
57978 .on('keydown.intro', eventCancel, true)
57979 .on('keyup.intro', null);
57984 function selectedPreset() {
57985 setTimeout(function() {
57986 reveal('.entity-editor-pane', t('intro.points.describe'), {tooltipClass: 'intro-points-describe'});
57987 context.history().on('change.intro', closeEditor);
57988 context.on('exit.intro', selectPoint);
57993 function closeEditor() {
57994 select('.preset-search-input').on('keydown.intro', null);
57995 context.history().on('change.intro', null);
57996 reveal('.entity-editor-pane',
57997 t('intro.points.close', { button: icon('#icon-apply', 'pre-text') }));
58001 function selectPoint() {
58002 context.on('exit.intro', null);
58003 context.history().on('change.intro', null);
58004 context.on('enter.intro', enterReselect);
58006 var pointBox$$1 = pad$1(corner, 150, context);
58007 reveal(pointBox$$1, t('intro.points.reselect'));
58009 context.map().on('move.intro', function() {
58010 pointBox$$1 = pad$1(corner, 150, context);
58011 reveal(pointBox$$1, t('intro.points.reselect'), {duration: 0});
58016 function enterReselect(mode) {
58017 if (mode.id !== 'select') return;
58018 context.map().on('move.intro', null);
58019 context.on('enter.intro', null);
58021 setTimeout(function() {
58022 reveal('.entity-editor-pane',
58023 t('intro.points.fixname', { button: icon('#icon-apply', 'pre-text') }));
58024 context.on('exit.intro', deletePoint);
58029 function deletePoint() {
58030 context.on('exit.intro', null);
58031 context.on('enter.intro', enterDelete);
58033 var pointBox$$1 = pad$1(corner, 150, context);
58034 reveal(pointBox$$1, t('intro.points.reselect_delete'));
58036 context.map().on('move.intro', function() {
58037 pointBox$$1 = pad$1(corner, 150, context);
58038 reveal(pointBox$$1, t('intro.points.reselect_delete'), {duration: 0});
58043 function enterDelete(mode) {
58044 if (mode.id !== 'select') return;
58045 context.map().on('move.intro', null);
58046 context.on('enter.intro', null);
58047 context.on('exit.intro', deletePoint);
58048 context.map().on('move.intro', deletePoint);
58049 context.history().on('change.intro', deleted);
58051 setTimeout(function() {
58052 var node = select('.radial-menu-item-delete').node();
58053 var pointBox$$1 = pad$1(node.getBoundingClientRect(), 50, context);
58054 reveal(pointBox$$1,
58055 t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }));
58060 function deleted(changed) {
58061 if (changed.deleted().length) {
58062 dispatch$$1.call('done');
58069 step.exit = function() {
58070 timeouts.forEach(window.clearTimeout);
58071 context.on('exit.intro', null);
58072 context.on('enter.intro', null);
58073 context.map().on('move.intro', null);
58074 context.history().on('change.intro', null);
58075 select('.preset-search-input')
58076 .on('keyup.intro', null)
58077 .on('keydown.intro', null);
58080 return utilRebind(step, dispatch$$1, 'on');
58083 function uiIntroArea(context, reveal) {
58084 var dispatch$$1 = dispatch('done'),
58088 title: 'intro.areas.title'
58092 step.enter = function() {
58093 var playground = [-85.63552, 41.94159],
58094 corner = [-85.63565411045074, 41.9417715536927];
58095 context.map().centerZoom(playground, 19);
58096 reveal('button.add-area',
58097 t('intro.areas.add', { button: icon('#icon-area', 'pre-text') }),
58098 { tooltipClass: 'intro-areas-add' });
58100 context.on('enter.intro', addArea);
58103 function addArea(mode) {
58104 if (mode.id !== 'add-area') return;
58105 context.on('enter.intro', drawArea);
58107 var padding = 120 * Math.pow(2, context.map().zoom() - 19);
58108 var pointBox$$1 = pad$1(corner, padding, context);
58109 reveal(pointBox$$1, t('intro.areas.corner'));
58111 context.map().on('move.intro', function() {
58112 padding = 120 * Math.pow(2, context.map().zoom() - 19);
58113 pointBox$$1 = pad$1(corner, padding, context);
58114 reveal(pointBox$$1, t('intro.areas.corner'), {duration: 0});
58119 function drawArea(mode) {
58120 if (mode.id !== 'draw-area') return;
58121 context.on('enter.intro', enterSelect);
58123 var padding = 150 * Math.pow(2, context.map().zoom() - 19);
58124 var pointBox$$1 = pad$1(playground, padding, context);
58125 reveal(pointBox$$1, t('intro.areas.place'));
58127 context.map().on('move.intro', function() {
58128 padding = 150 * Math.pow(2, context.map().zoom() - 19);
58129 pointBox$$1 = pad$1(playground, padding, context);
58130 reveal(pointBox$$1, t('intro.areas.place'), {duration: 0});
58135 function enterSelect(mode) {
58136 if (mode.id !== 'select') return;
58137 context.map().on('move.intro', null);
58138 context.on('enter.intro', null);
58140 timeout$$1 = setTimeout(function() {
58141 reveal('.preset-search-input',
58142 t('intro.areas.search',
58143 { name: context.presets().item('leisure/playground').name() }));
58144 select('.preset-search-input').on('keyup.intro', keySearch);
58149 function keySearch() {
58150 var first = select('.preset-list-item:first-child');
58151 if (first.classed('preset-leisure-playground')) {
58152 reveal(first.select('.preset-list-button').node(), t('intro.areas.choose'));
58153 utilBindOnce(context.history(), 'change.intro', selectedPreset);
58154 select('.preset-search-input').on('keyup.intro', null);
58159 function selectedPreset() {
58161 t('intro.areas.describe', { button: icon('#icon-apply', 'pre-text') }));
58162 context.on('exit.intro', function() {
58163 dispatch$$1.call('done');
58169 step.exit = function() {
58170 window.clearTimeout(timeout$$1);
58171 context.on('enter.intro', null);
58172 context.on('exit.intro', null);
58173 context.history().on('change.intro', null);
58174 context.map().on('move.intro', null);
58175 select('.preset-search-input').on('keyup.intro', null);
58179 return utilRebind(step, dispatch$$1, 'on');
58182 function uiIntroLine(context, reveal) {
58183 var dispatch$$1 = dispatch('done'),
58185 centroid = [-85.62830, 41.95699],
58186 midpoint = [-85.62975395449628, 41.95787501510204],
58187 start = [-85.6297754121684, 41.95805253325314],
58188 intersection = [-85.62974496187628, 41.95742515554585],
58189 targetId = 'w17965351',
58194 title: 'intro.lines.title'
58198 function timeout$$1(f, t$$1) {
58199 timeouts.push(window.setTimeout(f, t$$1));
58203 function eventCancel() {
58204 event.stopPropagation();
58205 event.preventDefault();
58209 step.enter = function() {
58210 context.map().centerZoom(start, 18);
58211 reveal('button.add-line',
58212 t('intro.lines.add', { button: icon('#icon-line', 'pre-text') }),
58213 { tooltipClass: 'intro-lines-add' });
58215 context.on('enter.intro', addLine);
58218 function addLine(mode) {
58219 if (mode.id !== 'add-line') return;
58221 context.on('enter.intro', drawLine);
58223 var padding = 150 * Math.pow(2, context.map().zoom() - 18);
58224 var pointBox$$1 = pad$1(start, padding, context);
58225 reveal(pointBox$$1, t('intro.lines.start'));
58227 context.map().on('move.intro', function() {
58228 padding = 150 * Math.pow(2, context.map().zoom() - 18);
58229 pointBox$$1 = pad$1(start, padding, context);
58230 reveal(pointBox$$1, t('intro.lines.start'), {duration: 0});
58235 function drawLine(mode) {
58236 if (mode.id !== 'draw-line') return;
58237 drawId = mode.selectedIDs()[0];
58238 context.history().on('change.intro', checkIntersection);
58239 context.on('enter.intro', retry);
58241 var padding = 300 * Math.pow(2, context.map().zoom() - 19);
58242 var pointBox$$1 = pad$1(midpoint, padding, context);
58243 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}));
58245 context.map().on('move.intro', function() {
58246 padding = 300 * Math.pow(2, context.map().zoom() - 19);
58247 pointBox$$1 = pad$1(midpoint, padding, context);
58248 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}), {duration: 0});
58253 // ended line before creating intersection
58254 function retry(mode) {
58255 if (mode.id !== 'select') return;
58256 context.history().on('change.intro', null);
58257 var pointBox$$1 = pad$1(intersection, 30, context);
58258 reveal(pointBox$$1, t('intro.lines.restart', {name: t('intro.graph.flower_st')}));
58259 select(window).on('mousedown.intro', eventCancel, true);
58261 timeout$$1(step.restart, 3000);
58265 function checkIntersection() {
58267 function joinedTargetWay() {
58268 var drawEntity = drawId && context.hasEntity(drawId);
58274 var drawNodes = context.graph().childNodes(drawEntity);
58275 return lodash.some(drawNodes, function(node) {
58276 return lodash.some(context.graph().parentWays(node), function(parent) {
58277 return parent.id === targetId;
58282 if (joinedTargetWay()) {
58283 context.history().on('change.intro', null);
58284 context.on('enter.intro', enterSelect);
58286 var padding = 900 * Math.pow(2, context.map().zoom() - 19);
58287 var pointBox$$1 = pad$1(centroid, padding, context);
58288 reveal(pointBox$$1, t('intro.lines.finish'));
58290 context.map().on('move.intro', function() {
58291 padding = 900 * Math.pow(2, context.map().zoom() - 19);
58292 pointBox$$1 = pad$1(centroid, padding, context);
58293 reveal(pointBox$$1, t('intro.lines.finish'), {duration: 0});
58299 function enterSelect(mode) {
58300 if (mode.id !== 'select') return;
58301 context.map().on('move.intro', null);
58302 context.on('enter.intro', null);
58303 select('#curtain').style('pointer-events', 'all');
58308 function presetCategory() {
58309 timeout$$1(function() {
58310 select('#curtain').style('pointer-events', 'none');
58311 var road = select('.preset-category-road .preset-list-button');
58312 reveal(road.node(), t('intro.lines.road'));
58313 utilBindOnce(road, 'click.intro', roadCategory);
58318 function roadCategory() {
58319 timeout$$1(function() {
58320 var grid = select('.subgrid');
58321 reveal(grid.node(), t('intro.lines.residential'));
58322 utilBindOnce(grid.selectAll(':not(.preset-highway-residential) .preset-list-button'),
58323 'click.intro', retryPreset);
58324 utilBindOnce(grid.selectAll('.preset-highway-residential .preset-list-button'),
58325 'click.intro', roadDetails);
58330 // selected wrong road type
58331 function retryPreset() {
58332 timeout$$1(function() {
58333 var preset = select('.entity-editor-pane .preset-list-button');
58334 reveal(preset.node(), t('intro.lines.wrong_preset'));
58335 utilBindOnce(preset, 'click.intro', presetCategory);
58340 function roadDetails() {
58342 t('intro.lines.describe', { button: icon('#icon-apply', 'pre-text') }));
58343 context.on('exit.intro', function() {
58344 dispatch$$1.call('done');
58350 step.restart = function() {
58356 step.exit = function() {
58357 select(window).on('mousedown.intro', null, true);
58358 select('#curtain').style('pointer-events', 'none');
58359 timeouts.forEach(window.clearTimeout);
58360 context.on('enter.intro', null);
58361 context.on('exit.intro', null);
58362 context.map().on('move.intro', null);
58363 context.history().on('change.intro', null);
58365 context.replace(actionDeleteMultiple([drawId]));
58370 return utilRebind(step, dispatch$$1, 'on');
58373 function uiIntroStartEditing(context, reveal) {
58374 var dispatch$$1 = dispatch('done', 'startEditing'),
58379 title: 'intro.startediting.title'
58383 function timeout$$1(f, t$$1) {
58384 timeouts.push(window.setTimeout(f, t$$1));
58388 step.enter = function() {
58389 reveal('.map-control.help-control',
58390 t('intro.startediting.help', { button: icon('#icon-help', 'pre-text') }));
58392 timeout$$1(function() {
58393 reveal('#bar button.save', t('intro.startediting.save'));
58396 timeout$$1(function() {
58397 reveal('#surface');
58400 timeout$$1(function() {
58401 modalSelection = uiModal(context.container());
58403 modalSelection.select('.modal')
58404 .attr('class', 'modal-splash modal col6');
58406 modalSelection.selectAll('.close').remove();
58408 var startbutton = modalSelection.select('.content')
58409 .attr('class', 'fillL')
58411 .attr('class', 'modal-section huge-modal-button')
58412 .on('click', function() {
58413 modalSelection.remove();
58418 .attr('class','illustration');
58422 .text(t('intro.startediting.start'));
58424 dispatch$$1.call('startEditing');
58429 step.exit = function() {
58430 if (modalSelection) { modalSelection.remove(); }
58431 timeouts.forEach(window.clearTimeout);
58435 return utilRebind(step, dispatch$$1, 'on');
58438 var sampleIntros = {
58439 navigation: uiIntroNavigation,
58440 point: uiIntroPoint,
58443 startEditing: uiIntroStartEditing
58447 function uiIntro(context) {
58450 function localizedName(id) {
58452 n2140018997: 'city_hall',
58453 n367813436: 'fire_department',
58454 w203988286: 'memory_isle_park',
58455 w203972937: 'riverwalk_trail',
58456 w203972938: 'riverwalk_trail',
58457 w203972940: 'riverwalk_trail',
58458 w41785752: 'w_michigan_ave',
58459 w134150789: 'w_michigan_ave',
58460 w134150795: 'w_michigan_ave',
58461 w134150800: 'w_michigan_ave',
58462 w134150811: 'w_michigan_ave',
58463 w134150802: 'e_michigan_ave',
58464 w134150836: 'e_michigan_ave',
58465 w41074896: 'e_michigan_ave',
58466 w17965834: 'spring_st',
58467 w203986457: 'scidmore_park',
58468 w203049587: 'petting_zoo',
58469 w17967397: 'n_andrews_st',
58470 w17967315: 's_andrews_st',
58471 w17967326: 'n_constantine_st',
58472 w17966400: 's_constantine_st',
58473 w170848823: 'rocky_river',
58474 w170848824: 'rocky_river',
58475 w170848331: 'rocky_river',
58476 w17967752: 'railroad_dr',
58477 w17965998: 'conrail_rr',
58478 w134150845: 'conrail_rr',
58479 w170989131: 'st_joseph_river',
58480 w143497377: 'n_main_st',
58481 w134150801: 's_main_st',
58482 w134150830: 's_main_st',
58483 w17966462: 's_main_st',
58484 w17967734: 'water_st',
58485 w17964996: 'foster_st',
58486 w170848330: 'portage_river',
58487 w17965351: 'flower_st',
58488 w17965502: 'elm_st',
58489 w17965402: 'walnut_st',
58490 w17964793: 'morris_ave',
58491 w17967444: 'east_st',
58492 w17966984: 'portage_ave'
58495 return features[id] && t('intro.graph.' + features[id]);
58499 var introGraph = {};
58501 for (var key in dataIntroGraph) {
58502 introGraph[key] = osmEntity$$1(dataIntroGraph[key]);
58503 var name = localizedName(key);
58505 introGraph[key].tags.name = name;
58510 function intro(selection$$1) {
58511 context.enter(modeBrowse(context));
58513 // Save current map state
58514 var history = context.history().toJSON(),
58515 hash = window.location.hash,
58516 center = context.map().center(),
58517 zoom$$1 = context.map().zoom(),
58518 background = context.background().baseLayerSource(),
58519 opacity = selectAll('#map .layer-background').style('opacity'),
58520 loadedTiles = context.connection().loadedTiles(),
58521 baseEntities = context.history().graph().base().entities;
58524 context.inIntro(true);
58526 // Load semi-real data used in intro
58527 context.connection().toggle(false).reset();
58528 context.history().reset();
58530 context.history().merge(values(coreGraph$$1().load(introGraph).entities));
58531 context.background().bing();
58533 selectAll('#map .layer-background').style('opacity', 1);
58535 var curtain = d3curtain();
58536 selection$$1.call(curtain);
58539 function reveal(box, text$$1, options) {
58540 options = options || {};
58541 curtain.reveal(box,
58543 options.tooltipClass || '',
58548 var steps = ['navigation', 'point', 'area', 'line', 'startEditing'].map(function(step, i) {
58549 var s = sampleIntros[step](context, reveal)
58550 .on('done', function() {
58551 entered.filter(function(d) {
58552 return d.title === s.title;
58553 }).classed('finished', true);
58554 enter(steps[i + 1]);
58559 steps[steps.length - 1].on('startEditing', function() {
58562 selectAll('#map .layer-background').style('opacity', opacity);
58563 context.connection().toggle(true).reset().loadedTiles(loadedTiles);
58564 context.history().reset().merge(values(baseEntities));
58565 context.background().baseLayerSource(background);
58566 if (history) context.history().fromJSON(history, false);
58567 context.map().centerZoom(center, zoom$$1);
58568 window.location.replace(hash);
58569 context.inIntro(false);
58572 var navwrap = selection$$1
58574 .attr('class', 'intro-nav-wrap fillD');
58576 var buttonwrap = navwrap
58578 .attr('class', 'joined')
58579 .selectAll('button.step');
58581 var entered = buttonwrap
58585 .attr('class', 'step')
58586 .on('click', enter);
58590 .text(function(d) { return t(d.title); });
58594 .attr('class', 'status')
58595 .text(' - ' + t('intro.done'));
58600 function enter(newStep) {
58601 if (step) { step.exit(); }
58603 context.enter(modeBrowse(context));
58608 entered.classed('active', function(d) {
58609 return d.title === step.title;
58619 function uiHelp(context) {
58624 'help.editing_saving',
58633 var docs = docKeys.map(function(key) {
58634 var text$$1 = t(key);
58636 title: text$$1.split('\n')[0].replace('#', '').trim(),
58637 html: marked(text$$1.split('\n').slice(1).join('\n'))
58642 function help(selection$$1) {
58649 function toggle() {
58650 if (event) event.preventDefault();
58651 tooltipBehavior.hide(button);
58652 setVisible(!button.classed('active'));
58656 function setVisible(show) {
58657 if (show !== shown) {
58658 button.classed('active', show);
58662 selection$$1.on('mousedown.help-inside', function() {
58663 return event.stopPropagation();
58665 pane.style('display', 'block')
58666 .style('right', '-500px')
58669 .style('right', '0px');
58671 pane.style('right', '0px')
58674 .style('right', '-500px')
58675 .on('end', function() {
58676 select(this).style('display', 'none');
58678 selection$$1.on('mousedown.help-inside', null);
58684 function clickHelp(d, i) {
58685 var rtl = (textDirection === 'rtl');
58686 pane.property('scrollTop', 0);
58687 doctitle.html(d.title);
58690 body.selectAll('a')
58691 .attr('target', '_blank');
58692 menuItems.classed('selected', function(m) {
58693 return m.title === d.title;
58698 nav.call(drawNext).call(drawPrevious);
58700 nav.call(drawPrevious).call(drawNext);
58704 function drawNext(selection$$1) {
58705 if (i < docs.length - 1) {
58706 var nextLink = selection$$1
58708 .attr('class', 'next')
58709 .on('click', function() {
58710 clickHelp(docs[i + 1], i + 1);
58715 .text(docs[i + 1].title)
58716 .call(svgIcon((rtl ? '#icon-backward' : '#icon-forward'), 'inline'));
58721 function drawPrevious(selection$$1) {
58723 var prevLink = selection$$1
58725 .attr('class', 'previous')
58726 .on('click', function() {
58727 clickHelp(docs[i - 1], i - 1);
58731 .call(svgIcon((rtl ? '#icon-forward' : '#icon-backward'), 'inline'))
58733 .text(docs[i - 1].title);
58739 function clickWalkthrough() {
58740 select(document.body).call(uiIntro(context));
58745 var pane = selection$$1.append('div')
58746 .attr('class', 'help-wrap map-overlay fillL col5 content hide'),
58747 tooltipBehavior = tooltip()
58748 .placement((textDirection === 'rtl') ? 'right' : 'left')
58750 .title(uiTooltipHtml(t('help.title'), key)),
58751 button = selection$$1.append('button')
58752 .attr('tabindex', -1)
58753 .on('click', toggle)
58754 .call(svgIcon('#icon-help', 'light'))
58755 .call(tooltipBehavior),
58759 var toc = pane.append('ul')
58760 .attr('class', 'toc');
58762 var menuItems = toc.selectAll('li')
58767 .html(function(d) { return d.title; })
58768 .on('click', clickHelp);
58771 .attr('class','walkthrough')
58773 .text(t('splash.walkthrough'))
58774 .on('click', clickWalkthrough);
58776 var content = pane.append('div')
58777 .attr('class', 'left-content');
58779 var doctitle = content.append('h2')
58780 .text(t('help.title'));
58782 var body = content.append('div')
58783 .attr('class', 'body');
58785 var nav = content.append('div')
58786 .attr('class', 'nav');
58788 clickHelp(docs[0], 0);
58790 var keybinding = d3keybinding('help')
58798 context.surface().on('mousedown.help-outside', hide);
58799 context.container().on('mousedown.help-outside', hide);
58805 function uiInfo(context) {
58806 var key = uiCmd('⌘I'),
58807 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
58811 function info(selection$$1) {
58813 function radiansToMeters(r) {
58814 // using WGS84 authalic radius (6371007.1809 m)
58815 return r * 6371007.1809;
58818 function steradiansToSqmeters(r) {
58819 // http://gis.stackexchange.com/a/124857/40446
58820 return r / (4 * Math.PI) * 510065621724000;
58824 function toLineString(feature) {
58825 if (feature.type === 'LineString') return feature;
58827 var result = { type: 'LineString', coordinates: [] };
58828 if (feature.type === 'Polygon') {
58829 result.coordinates = feature.coordinates[0];
58830 } else if (feature.type === 'MultiPolygon') {
58831 result.coordinates = feature.coordinates[0][0];
58838 function displayLength(m) {
58839 var d = m * (isImperial ? 3.28084 : 1),
58858 // drop unnecessary precision
58859 p = d > 1000 ? 0 : d > 100 ? 1 : 2;
58861 return String(d.toFixed(p)) + ' ' + unit;
58865 function displayArea(m2) {
58866 var d = m2 * (isImperial ? 10.7639111056 : 1),
58867 d1, d2, p1, p2, unit1, unit2;
58870 if (d >= 6969600) { // > 0.25mi² show mi²
58878 if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres
58884 if (d >= 250000) { // > 0.25km² show km²
58892 if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares
58898 // drop unnecessary precision
58899 p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
58900 p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
58902 return String(d1.toFixed(p1)) + ' ' + unit1 +
58903 (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
58907 function redraw() {
58908 if (isHidden) return;
58910 var resolver = context.graph(),
58911 selected = lodash.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
58912 singular = selected.length === 1 ? selected[0] : null,
58913 extent$$1 = geoExtent$$1(),
58918 .attr('class', 'infobox-heading fillD')
58919 .text(singular || t('infobox.selected', { n: selected.length }));
58921 if (!selected.length) return;
58924 for (var i = 0; i < selected.length; i++) {
58925 entity = context.entity(selected[i]);
58926 extent$$1._extend(entity.extent(resolver));
58928 center = extent$$1.center();
58931 var list = wrap.append('ul');
58933 // multiple features, just display extent center..
58936 .text(t('infobox.center') + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
58940 // single feature, display details..
58941 if (!entity) return;
58942 var geometry = entity.geometry(resolver);
58944 if (geometry === 'line' || geometry === 'area') {
58945 var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
58946 feature = entity.asGeoJSON(resolver),
58947 length = radiansToMeters(d3GeoLength(toLineString(feature))),
58948 lengthLabel = t('infobox.' + (closed ? 'perimeter' : 'length')),
58949 centroid = d3GeoCentroid(feature);
58952 .text(t('infobox.geometry') + ': ' +
58953 (closed ? t('infobox.closed') + ' ' : '') + t('geometry.' + geometry) );
58956 var area$$1 = steradiansToSqmeters(entity.area(resolver));
58958 .text(t('infobox.area') + ': ' + displayArea(area$$1));
58962 .text(lengthLabel + ': ' + displayLength(length));
58965 .text(t('infobox.centroid') + ': ' + centroid[0].toFixed(5) + ', ' + centroid[1].toFixed(5));
58968 var toggle = isImperial ? 'imperial' : 'metric';
58970 .text(t('infobox.' + toggle))
58972 .attr('class', 'button')
58973 .on('click', function() {
58974 event.preventDefault();
58975 isImperial = !isImperial;
58980 var centerLabel = t('infobox.' + (entity.type === 'node' ? 'location' : 'center'));
58983 .text(t('infobox.geometry') + ': ' + t('geometry.' + geometry));
58986 .text(centerLabel + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
58991 function toggle() {
58993 event.preventDefault();
58996 isHidden = !isHidden;
59000 .style('display', 'block')
59001 .style('opacity', 1)
59004 .style('opacity', 0)
59005 .on('end', function() {
59006 select(this).style('display', 'none');
59010 .style('display', 'block')
59011 .style('opacity', 0)
59014 .style('opacity', 1)
59015 .on('end', function() {
59022 var wrap = selection$$1.selectAll('.infobox')
59025 wrap = wrap.enter()
59027 .attr('class', 'infobox fillD2')
59028 .style('display', (isHidden ? 'none' : 'block'))
59032 .on('drawn.info', redraw);
59036 var keybinding = d3keybinding('info')
59046 function uiMapData(context) {
59048 features = context.features().keys(),
59049 layers = context.layers(),
59050 fills = ['wireframe', 'partial', 'full'],
59051 fillDefault = context.storage('area-fill') || 'partial',
59052 fillSelected = fillDefault;
59055 function map_data(selection$$1) {
59057 function showsFeature(d) {
59058 return context.features().enabled(d);
59062 function autoHiddenFeature(d) {
59063 return context.features().autoHidden(d);
59067 function clickFeature(d) {
59068 context.features().toggle(d);
59073 function showsFill(d) {
59074 return fillSelected === d;
59078 function setFill(d) {
59079 lodash.each(fills, function(opt) {
59080 context.surface().classed('fill-' + opt, Boolean(opt === d));
59084 if (d !== 'wireframe') {
59086 context.storage('area-fill', d);
59092 function showsLayer(which) {
59093 var layer = layers.layer(which);
59095 return layer.enabled();
59101 function setLayer(which, enabled) {
59102 var layer = layers.layer(which);
59104 layer.enabled(enabled);
59110 function toggleLayer(which) {
59111 setLayer(which, !showsLayer(which));
59115 function clickGpx() {
59116 toggleLayer('gpx');
59120 function clickMapillaryImages() {
59121 toggleLayer('mapillary-images');
59122 if (!showsLayer('mapillary-images')) {
59123 setLayer('mapillary-signs', false);
59128 function clickMapillarySigns() {
59129 toggleLayer('mapillary-signs');
59133 function drawMapillaryItems(selection$$1) {
59134 var mapillaryImages = layers.layer('mapillary-images'),
59135 mapillarySigns = layers.layer('mapillary-signs'),
59136 supportsMapillaryImages = mapillaryImages && mapillaryImages.supported(),
59137 supportsMapillarySigns = mapillarySigns && mapillarySigns.supported(),
59138 showsMapillaryImages = supportsMapillaryImages && mapillaryImages.enabled(),
59139 showsMapillarySigns = supportsMapillarySigns && mapillarySigns.enabled();
59141 var mapillaryList = selection$$1
59142 .selectAll('.layer-list-mapillary')
59145 mapillaryList = mapillaryList.enter()
59147 .attr('class', 'layer-list layer-list-mapillary')
59148 .merge(mapillaryList);
59151 var mapillaryImageLayerItem = mapillaryList
59152 .selectAll('.list-item-mapillary-images')
59153 .data(supportsMapillaryImages ? [0] : []);
59155 mapillaryImageLayerItem.exit()
59158 var enterImages = mapillaryImageLayerItem.enter()
59160 .attr('class', 'list-item-mapillary-images');
59162 var labelImages = enterImages
59165 .title(t('mapillary_images.tooltip'))
59166 .placement('top'));
59170 .attr('type', 'checkbox')
59171 .on('change', clickMapillaryImages);
59175 .text(t('mapillary_images.title'));
59178 var mapillarySignLayerItem = mapillaryList
59179 .selectAll('.list-item-mapillary-signs')
59180 .data(supportsMapillarySigns ? [0] : []);
59182 mapillarySignLayerItem.exit()
59185 var enterSigns = mapillarySignLayerItem.enter()
59187 .attr('class', 'list-item-mapillary-signs');
59189 var labelSigns = enterSigns
59192 .title(t('mapillary_signs.tooltip'))
59193 .placement('top'));
59197 .attr('type', 'checkbox')
59198 .on('change', clickMapillarySigns);
59202 .text(t('mapillary_signs.title'));
59206 mapillaryImageLayerItem = mapillaryImageLayerItem
59207 .merge(enterImages);
59209 mapillaryImageLayerItem
59210 .classed('active', showsMapillaryImages)
59211 .selectAll('input')
59212 .property('checked', showsMapillaryImages);
59215 mapillarySignLayerItem = mapillarySignLayerItem
59216 .merge(enterSigns);
59218 mapillarySignLayerItem
59219 .classed('active', showsMapillarySigns)
59220 .selectAll('input')
59221 .property('disabled', !showsMapillaryImages)
59222 .property('checked', showsMapillarySigns);
59224 mapillarySignLayerItem
59225 .selectAll('label')
59226 .classed('deemphasize', !showsMapillaryImages);
59230 function drawGpxItem(selection$$1) {
59231 var gpx = layers.layer('gpx'),
59232 hasGpx = gpx && gpx.hasGpx(),
59233 showsGpx = hasGpx && gpx.enabled();
59235 var gpxLayerItem = selection$$1
59236 .selectAll('.layer-list-gpx')
59237 .data(gpx ? [0] : []);
59240 gpxLayerItem.exit()
59244 var enter = gpxLayerItem.enter()
59246 .attr('class', 'layer-list layer-list-gpx')
59248 .classed('list-item-gpx', true);
59252 .attr('class', 'list-item-gpx-extent')
59254 .title(t('gpx.zoom'))
59255 .placement((textDirection === 'rtl') ? 'right' : 'left'))
59256 .on('click', function() {
59257 event.preventDefault();
59258 event.stopPropagation();
59261 .call(svgIcon('#icon-search'));
59265 .attr('class', 'list-item-gpx-browse')
59267 .title(t('gpx.browse'))
59268 .placement((textDirection === 'rtl') ? 'right' : 'left'))
59269 .on('click', function() {
59270 select(document.createElement('input'))
59271 .attr('type', 'file')
59272 .on('change', function() {
59273 gpx.files(event.target.files);
59277 .call(svgIcon('#icon-geolocate'));
59279 var labelGpx = enter
59281 .call(tooltip().title(t('gpx.drag_drop')).placement('top'));
59285 .attr('type', 'checkbox')
59286 .on('change', clickGpx);
59290 .text(t('gpx.local_layer'));
59294 gpxLayerItem = gpxLayerItem
59298 .classed('active', showsGpx)
59299 .selectAll('input')
59300 .property('disabled', !hasGpx)
59301 .property('checked', showsGpx);
59304 .selectAll('label')
59305 .classed('deemphasize', !hasGpx);
59309 function drawList(selection$$1, data, type, name, change, active$$1) {
59310 var items = selection$$1.selectAll('li')
59318 var enter = items.enter()
59320 .attr('class', 'layer')
59323 .title(function(d) {
59324 var tip = t(name + '.' + d + '.tooltip'),
59325 key = (d === 'wireframe' ? 'W' : null);
59327 if (name === 'feature' && autoHiddenFeature(d)) {
59328 tip += '<div>' + t('map_data.autohidden') + '</div>';
59330 return uiTooltipHtml(tip, key);
59340 .attr('type', type)
59341 .attr('name', name)
59342 .on('change', change);
59346 .text(function(d) { return t(name + '.' + d + '.description'); });
59353 .classed('active', active$$1)
59354 .selectAll('input')
59355 .property('checked', active$$1)
59356 .property('indeterminate', function(d) {
59357 return (name === 'feature' && autoHiddenFeature(d));
59362 function update() {
59363 dataLayerContainer.call(drawMapillaryItems);
59364 dataLayerContainer.call(drawGpxItem);
59366 fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);
59367 featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
59371 function hidePanel() {
59376 function togglePanel() {
59377 if (event) event.preventDefault();
59378 tooltipBehavior.hide(button);
59379 setVisible(!button.classed('active'));
59383 function toggleWireframe() {
59385 event.preventDefault();
59386 event.stopPropagation();
59388 setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
59389 context.map().pan([0,0]); // trigger a redraw
59393 function setVisible(show) {
59394 if (show !== shown) {
59395 button.classed('active', show);
59400 selection$$1.on('mousedown.map_data-inside', function() {
59401 return event.stopPropagation();
59403 content.style('display', 'block')
59404 .style('right', '-300px')
59407 .style('right', '0px');
59409 content.style('display', 'block')
59410 .style('right', '0px')
59413 .style('right', '-300px')
59414 .on('end', function() {
59415 select(this).style('display', 'none');
59417 selection$$1.on('mousedown.map_data-inside', null);
59423 var content = selection$$1
59425 .attr('class', 'fillL map-overlay col3 content hide'),
59426 tooltipBehavior = tooltip()
59427 .placement((textDirection === 'rtl') ? 'right' : 'left')
59429 .title(uiTooltipHtml(t('map_data.description'), key)),
59430 button = selection$$1
59432 .attr('tabindex', -1)
59433 .on('click', togglePanel)
59434 .call(svgIcon('#icon-data', 'light'))
59435 .call(tooltipBehavior),
59440 .text(t('map_data.title'));
59446 .text(t('map_data.data_layers'))
59448 .classed('hide-toggle', true)
59449 .classed('expanded', true)
59450 .on('click', function() {
59451 var exp = select(this).classed('expanded');
59452 dataLayerContainer.style('display', exp ? 'none' : 'block');
59453 select(this).classed('expanded', !exp);
59454 event.preventDefault();
59457 var dataLayerContainer = content
59459 .attr('class', 'data-data-layers')
59460 .style('display', 'block');
59466 .text(t('map_data.fill_area'))
59468 .classed('hide-toggle', true)
59469 .classed('expanded', false)
59470 .on('click', function() {
59471 var exp = select(this).classed('expanded');
59472 fillContainer.style('display', exp ? 'none' : 'block');
59473 select(this).classed('expanded', !exp);
59474 event.preventDefault();
59477 var fillContainer = content
59479 .attr('class', 'data-area-fills')
59480 .style('display', 'none');
59482 var fillList = fillContainer
59484 .attr('class', 'layer-list layer-fill-list');
59490 .text(t('map_data.map_features'))
59492 .classed('hide-toggle', true)
59493 .classed('expanded', false)
59494 .on('click', function() {
59495 var exp = select(this).classed('expanded');
59496 featureContainer.style('display', exp ? 'none' : 'block');
59497 select(this).classed('expanded', !exp);
59498 event.preventDefault();
59501 var featureContainer = content
59503 .attr('class', 'data-feature-filters')
59504 .style('display', 'none');
59506 var featureList = featureContainer
59508 .attr('class', 'layer-list layer-feature-list');
59512 .on('change.map_data-update', update);
59514 setFill(fillDefault);
59516 var keybinding = d3keybinding('features')
59517 .on(key, togglePanel)
59518 .on('W', toggleWireframe)
59519 .on('B', hidePanel)
59520 .on('H', hidePanel);
59525 context.surface().on('mousedown.map_data-outside', hidePanel);
59526 context.container().on('mousedown.map_data-outside', hidePanel);
59533 function uiModes(context) {
59535 modeAddPoint$$1(context),
59536 modeAddLine$$1(context),
59537 modeAddArea$$1(context)
59541 function editable() {
59542 return context.editable() && context.mode().id !== 'save';
59546 return function(selection$$1) {
59547 var buttons = selection$$1.selectAll('button.add-button')
59550 buttons = buttons.enter()
59552 .attr('tabindex', -1)
59553 .attr('class', function(mode) { return mode.id + ' add-button col4'; })
59554 .on('click.mode-buttons', function(mode) {
59555 if (mode.id === context.mode().id) {
59556 context.enter(modeBrowse(context));
59558 context.enter(mode);
59562 .placement('bottom')
59564 .title(function(mode) {
59565 return uiTooltipHtml(mode.description, mode.key);
59570 .on('move.modes', lodash.debounce(update, 500));
59573 .on('enter.modes', update);
59576 .each(function(d) {
59578 .call(svgIcon('#icon-' + d.button, 'pre-text'));
59583 .attr('class', 'label')
59584 .text(function(mode) { return mode.title; });
59587 .on('enter.editor', function(entered) {
59588 selection$$1.selectAll('button.add-button')
59589 .classed('active', function(mode) { return entered.button === mode.button; });
59590 context.container()
59591 .classed('mode-' + entered.id, true);
59595 .on('exit.editor', function(exited) {
59596 context.container()
59597 .classed('mode-' + exited.id, false);
59600 var keybinding = d3keybinding('mode-buttons');
59602 modes.forEach(function(m) {
59603 keybinding.on(m.key, function() {
59604 if (editable()) context.enter(m);
59612 function update() {
59613 selection$$1.selectAll('button.add-button')
59614 .property('disabled', !editable());
59619 function uiRestore(context) {
59621 return function(selection) {
59622 if (!context.history().lock() || !context.history().restorableChanges())
59625 var modalSelection = uiModal(selection, true);
59627 modalSelection.select('.modal')
59628 .attr('class', 'modal fillL col6');
59630 var introModal = modalSelection.select('.content');
59633 .attr('class','cf');
59637 .attr('class', 'modal-section')
59639 .text(t('restore.heading'));
59643 .attr('class','modal-section')
59645 .text(t('restore.description'));
59647 var buttonWrap = introModal
59649 .attr('class', 'modal-actions cf');
59651 var restore = buttonWrap
59653 .attr('class', 'restore col6')
59654 .text(t('restore.restore'))
59655 .on('click', function() {
59656 context.history().restore();
59657 modalSelection.remove();
59662 .attr('class', 'reset col6')
59663 .text(t('restore.reset'))
59664 .on('click', function() {
59665 context.history().clearSaved();
59666 modalSelection.remove();
59669 restore.node().focus();
59673 function uiSave(context) {
59674 var history = context.history(),
59678 function saving() {
59679 return context.mode().id === 'save';
59684 event.preventDefault();
59685 if (!context.inIntro() && !saving() && history.hasChanges()) {
59686 context.enter(modeSave$$1(context));
59691 function getBackground(numChanges) {
59693 if (numChanges === 0) {
59695 } else if (numChanges <= 50) {
59696 step = numChanges / 50;
59697 return rgb$1('#fff', '#ff8')(step); // white -> yellow
59699 step = Math.min((numChanges - 50) / 50, 1.0);
59700 return rgb$1('#ff8', '#f88')(step); // yellow -> red
59705 return function(selection$$1) {
59706 var numChanges = 0;
59708 function updateCount() {
59709 var _ = history.difference().summary().length;
59710 if (_ === numChanges) return;
59714 .title(uiTooltipHtml(
59715 t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key)
59718 var background = getBackground(numChanges);
59721 .classed('disabled', numChanges === 0)
59722 .classed('has-count', numChanges > 0)
59723 .style('background', background);
59725 button.select('span.count')
59727 .style('background', background)
59728 .style('border-color', background);
59732 var tooltipBehavior = tooltip()
59733 .placement('bottom')
59735 .title(uiTooltipHtml(t('save.no_changes'), key));
59737 var button = selection$$1
59739 .attr('class', 'save col12 disabled')
59740 .attr('tabindex', -1)
59742 .call(tooltipBehavior);
59745 .call(svgIcon('#icon-save', 'pre-text'))
59747 .attr('class', 'label')
59748 .text(t('save.title'));
59752 .attr('class', 'count')
59758 var keybinding = d3keybinding('save')
59759 .on(key, save, true);
59765 .on('change.save', updateCount);
59768 .on('enter.save', function() {
59769 button.property('disabled', saving());
59770 if (saving()) button.call(tooltipBehavior.hide);
59775 function uiScale(context) {
59776 var projection = context.projection,
59777 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
59782 function scaleDefs(loc1, loc2) {
59783 var lat = (loc2[1] + loc1[1]) / 2,
59784 conversion = (isImperial ? 3.28084 : 1),
59785 dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
59786 scale = { dist: 0, px: 0, text: '' },
59787 buckets, i, val, dLon;
59790 buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
59792 buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
59795 // determine a user-friendly endpoint for the scale
59796 for (i = 0; i < buckets.length; i++) {
59799 scale.dist = Math.floor(dist / val) * val;
59802 scale.dist = +dist.toFixed(2);
59806 dLon = geoMetersToLon(scale.dist / conversion, lat);
59807 scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
59810 if (scale.dist >= 5280) {
59811 scale.dist /= 5280;
59812 scale.text = String(scale.dist) + ' mi';
59814 scale.text = String(scale.dist) + ' ft';
59817 if (scale.dist >= 1000) {
59818 scale.dist /= 1000;
59819 scale.text = String(scale.dist) + ' km';
59821 scale.text = String(scale.dist) + ' m';
59829 function update(selection) {
59830 // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
59831 var dims = context.map().dimensions(),
59832 loc1 = projection.invert([0, dims[1]]),
59833 loc2 = projection.invert([maxLength, dims[1]]),
59834 scale = scaleDefs(loc1, loc2);
59836 selection.select('#scalepath')
59837 .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
59839 selection.select('#scaletext')
59840 .attr('x', scale.px + 8)
59841 .attr('y', tickHeight)
59846 return function(selection) {
59847 function switchUnits() {
59848 isImperial = !isImperial;
59849 selection.call(update);
59852 var g = selection.append('svg')
59853 .attr('id', 'scale')
59854 .on('click', switchUnits)
59856 .attr('transform', 'translate(10,11)');
59858 g.append('path').attr('id', 'scalepath');
59859 g.append('text').attr('id', 'scaletext');
59861 selection.call(update);
59863 context.map().on('move.scale', function() {
59870 function search(x, dims, r) {
59871 if (!dims) dims = 'NSEW';
59872 if (typeof x !== 'string') return { val: null, regex: r };
59873 r = r || /[\s\,]*([\-|\—|\―]?[0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/gi;
59875 if (!m) return { val: null, regex: r };
59876 else if (m[4] && dims.indexOf(m[4]) === -1) return { val: null, regex: r };
59878 val: (((m[1]) ? parseFloat(m[1]) : 0) +
59879 ((m[2] ? parseFloat(m[2]) / 60 : 0)) +
59880 ((m[3] ? parseFloat(m[3]) / 3600 : 0))) *
59881 ((m[4] && m[4] === 'S' || m[4] === 'W') ? -1 : 1),
59888 function pair(x, dims) {
59890 var one = search(x, dims);
59891 if (one.val === null) return null;
59892 var two = search(x, dims, one.regex);
59893 if (two.val === null) return null;
59894 // null if one/two are not contiguous.
59895 if (one.raw + two.raw !== x) return null;
59897 return swapdim(one.val, two.val, one.dim);
59899 return [one.val, two.val];
59903 function swapdim(a, b, dim) {
59904 if (dim === 'N' || dim === 'S') return [a, b];
59905 if (dim === 'W' || dim === 'E') return [b, a];
59908 function uiFeatureList(context) {
59909 var geocodeResults;
59912 function featureList(selection$$1) {
59913 var header = selection$$1.append('div')
59914 .attr('class', 'header fillL cf');
59916 header.append('h3')
59917 .text(t('inspector.feature_list'));
59919 var searchWrap = selection$$1.append('div')
59920 .attr('class', 'search-header');
59922 var search = searchWrap.append('input')
59923 .attr('placeholder', t('inspector.search'))
59924 .attr('type', 'search')
59925 .on('keypress', keypress)
59926 .on('input', inputevent);
59929 .call(svgIcon('#icon-search', 'pre-text'));
59931 var listWrap = selection$$1.append('div')
59932 .attr('class', 'inspector-body');
59934 var list = listWrap.append('div')
59935 .attr('class', 'feature-list cf');
59938 .on('exit.feature-list', clearSearch);
59940 .on('drawn.feature-list', mapDrawn);
59943 function keypress() {
59944 var q = search.property('value'),
59945 items = list.selectAll('.feature-list-item');
59946 if (event.keyCode === 13 && q.length && items.size()) {
59947 click(items.datum());
59952 function inputevent() {
59953 geocodeResults = undefined;
59958 function clearSearch() {
59959 search.property('value', '');
59964 function mapDrawn(e) {
59971 function features() {
59974 graph = context.graph(),
59975 q = search.property('value').toLowerCase();
59977 if (!q) return result;
59979 var idMatch = q.match(/^([nwr])([0-9]+)$/);
59984 geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
59985 type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
59990 var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
59992 if (locationMatch) {
59993 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
59997 type: t('inspector.location'),
59998 name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6),
60003 function addEntity(entity) {
60004 if (entity.id in entities || result.length > 200)
60007 entities[entity.id] = true;
60009 var name = utilDisplayName(entity) || '';
60010 if (name.toLowerCase().indexOf(q) >= 0) {
60011 var matched = context.presets().match(entity, graph),
60012 type = (matched && matched.name()) || utilDisplayType(entity.id);
60016 geometry: context.geometry(entity.id),
60022 graph.parentRelations(entity).forEach(function(parent) {
60027 var visible = context.surface().selectAll('.point, .line, .area').nodes();
60028 for (var i = 0; i < visible.length && result.length <= 200; i++) {
60029 addEntity(visible[i].__data__);
60032 (geocodeResults || []).forEach(function(d) {
60033 // https://github.com/openstreetmap/iD/issues/1890
60034 if (d.osm_type && d.osm_id) {
60036 id: osmEntity$$1.id.fromOSM(d.osm_type, d.osm_id),
60037 geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
60038 type: d.type !== 'yes' ? (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' ')
60039 : (d.class.charAt(0).toUpperCase() + d.class.slice(1)).replace('_', ' '),
60040 name: d.display_name,
60041 extent: new geoExtent$$1(
60042 [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
60043 [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
60052 function drawList() {
60053 var value = search.property('value'),
60054 results = features();
60056 list.classed('filtered', value.length);
60058 var noResultsWorldwide = geocodeResults && geocodeResults.length === 0;
60060 var resultsIndicator = list.selectAll('.no-results-item')
60062 .enter().append('button')
60063 .property('disabled', true)
60064 .attr('class', 'no-results-item')
60065 .call(svgIcon('#icon-alert', 'pre-text'));
60067 resultsIndicator.append('span')
60068 .attr('class', 'entity-name');
60070 list.selectAll('.no-results-item .entity-name')
60071 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
60073 list.selectAll('.geocode-item')
60075 .enter().append('button')
60076 .attr('class', 'geocode-item')
60077 .on('click', geocoderSearch)
60079 .attr('class', 'label')
60081 .attr('class', 'entity-name')
60082 .text(t('geocoder.search'));
60084 list.selectAll('.no-results-item')
60085 .style('display', (value.length && !results.length) ? 'block' : 'none');
60087 list.selectAll('.geocode-item')
60088 .style('display', (value && geocodeResults === undefined) ? 'block' : 'none');
60090 list.selectAll('.feature-list-item')
60094 var items = list.selectAll('.feature-list-item')
60095 .data(results, function(d) { return d.id; });
60097 var enter = items.enter()
60098 .insert('button', '.geocode-item')
60099 .attr('class', 'feature-list-item')
60100 .on('mouseover', mouseover)
60101 .on('mouseout', mouseout)
60102 .on('click', click);
60106 .attr('class', 'label');
60108 label.each(function(d) {
60110 .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
60113 label.append('span')
60114 .attr('class', 'entity-type')
60115 .text(function(d) { return d.type; });
60117 label.append('span')
60118 .attr('class', 'entity-name')
60119 .text(function(d) { return d.name; });
60121 enter.style('opacity', 0)
60123 .style('opacity', 1);
60132 function mouseover(d) {
60133 if (d.id === -1) return;
60135 context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
60136 .classed('hover', true);
60140 function mouseout() {
60141 context.surface().selectAll('.hover')
60142 .classed('hover', false);
60146 function click(d) {
60147 event.preventDefault();
60149 context.map().centerZoom([d.location[1], d.location[0]], 20);
60151 else if (d.entity) {
60152 if (d.entity.type === 'node') {
60153 context.map().center(d.entity.loc);
60154 } else if (d.entity.type === 'way') {
60155 var center = context.projection(context.map().center()),
60156 edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
60157 context.map().center(edge.loc);
60159 context.enter(modeSelect(context, [d.entity.id]).suppressMenu(true));
60161 context.zoomToEntity(d.id);
60166 function geocoderSearch() {
60167 services.geocoder.search(search.property('value'), function (err, resp) {
60168 geocodeResults = resp || [];
60175 return featureList;
60178 function uiPresetIcon() {
60179 var preset, geometry;
60182 function presetIcon(selection$$1) {
60183 selection$$1.each(render);
60187 function render() {
60188 var selection$$1 = select(this),
60189 p = preset.apply(this, arguments),
60190 geom = geometry.apply(this, arguments),
60191 picon = p.icon || (geom === 'line' ? 'other-line' : 'marker-stroked'),
60192 isMaki = dataFeatureIcons.indexOf(picon) !== -1;
60194 function tag_classes(p) {
60196 for (var i in p.tags) {
60198 if (p.tags[i] !== '*') {
60199 s += ' tag-' + i + '-' + p.tags[i];
60205 var fill = selection$$1.selectAll('.preset-icon-fill')
60208 fill = fill.enter()
60213 .attr('class', function() {
60214 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
60217 var frame = selection$$1.selectAll('.preset-icon-frame')
60220 frame = frame.enter()
60222 .call(svgIcon('#preset-icon-frame'))
60226 .attr('class', function() {
60227 return 'preset-icon-frame ' + (geom === 'area' ? '' : 'hide');
60231 var icon = selection$$1.selectAll('.preset-icon')
60234 icon = icon.enter()
60236 .attr('class', 'preset-icon')
60241 .attr('class', 'preset-icon preset-icon-' +
60242 (isMaki ? (geom === 'area' ? '24' : '28') : (geom === 'area' ? '44' : '60'))
60245 icon.selectAll('svg')
60246 .attr('class', function() {
60247 return 'icon ' + picon + (isMaki ? '' : tag_classes(p));
60250 icon.selectAll('use')
60251 .attr('href', '#' + picon + (isMaki ? '-15' : ''));
60255 presetIcon.preset = function(_) {
60256 if (!arguments.length) return preset;
60257 preset = utilFunctor(_);
60262 presetIcon.geometry = function(_) {
60263 if (!arguments.length) return geometry;
60264 geometry = utilFunctor(_);
60271 function d3combobox() {
60272 var event$$1 = dispatch('accept'),
60276 caseSensitive = false;
60278 var fetcher = function(val, cb) {
60279 cb(data.filter(function(d) {
60283 .indexOf(val.toLowerCase()) !== -1;
60287 var combobox = function(input, attachTo) {
60289 container = select(document.body)
60290 .selectAll('div.combobox')
60291 .filter(function(d) { return d === input.node(); }),
60292 shown = !container.empty();
60295 .classed('combobox-input', true)
60296 .on('focus.typeahead', focus)
60297 .on('blur.typeahead', blur)
60298 .on('keydown.typeahead', keydown)
60299 .on('keyup.typeahead', keyup)
60300 .on('input.typeahead', change)
60302 var parent = this.parentNode,
60303 sibling = this.nextSibling;
60305 var caret = select(parent).selectAll('.combobox-caret')
60306 .filter(function(d) { return d === input.node(); })
60307 .data([input.node()]);
60309 caret = caret.enter()
60310 .insert('div', function() { return sibling; })
60311 .attr('class', 'combobox-caret')
60315 .on('mousedown', function () {
60316 // prevent the form element from blurring. it blurs
60318 event.stopPropagation();
60319 event.preventDefault();
60321 input.node().focus();
60330 fetch(value(), render);
60334 window.setTimeout(hide, 150);
60339 container = select(document.body)
60340 .insert('div', ':first-child')
60341 .datum(input.node())
60342 .attr('class', 'combobox')
60343 .style('position', 'absolute')
60344 .style('display', 'block')
60345 .style('left', '0px')
60346 .on('mousedown', function () {
60347 // prevent moving focus out of the text field
60348 event.preventDefault();
60351 select(document.body)
60352 .on('scroll.combobox', render, true);
60361 container.remove();
60363 select(document.body)
60364 .on('scroll.combobox', null);
60370 function keydown() {
60371 switch (event.keyCode) {
60372 // backspace, delete
60375 input.on('input.typeahead', function() {
60378 var start = input.property('selectionStart');
60379 input.node().setSelectionRange(start, start);
60380 input.on('input.typeahead', change);
60385 container.selectAll('a.selected').each(function (d) {
60386 event$$1.call('accept', this, d);
60392 event.preventDefault();
60397 event.preventDefault();
60402 event.preventDefault();
60405 event.stopPropagation();
60409 switch (event.keyCode) {
60416 container.selectAll('a.selected').each(function (d) {
60417 event$$1.call('accept', this, d);
60424 function change() {
60425 fetch(value(), function() {
60426 if (input.property('selectionEnd') === input.property('value').length) {
60433 function nav(dir) {
60434 if (!suggestions.length) return;
60435 idx = Math.max(Math.min(idx + dir, suggestions.length - 1), 0);
60436 input.property('value', suggestions[idx].value);
60442 var value = input.property('value'),
60443 start = input.property('selectionStart'),
60444 end = input.property('selectionEnd');
60446 if (start && end) {
60447 value = value.substring(0, start);
60453 function fetch(v, cb) {
60454 fetcher.call(input, v, function(_) {
60460 function autocomplete() {
60461 var v = caseSensitive ? value() : value().toLowerCase();
60465 for (var i = 0; i < suggestions.length; i++) {
60466 var suggestion = suggestions[i].value,
60467 compare = caseSensitive ? suggestion : suggestion.toLowerCase();
60469 if (compare.indexOf(v) === 0) {
60471 input.property('value', suggestion);
60472 input.node().setSelectionRange(v.length, suggestion.length);
60478 function render() {
60479 if (suggestions.length >= minItems && document.activeElement === input.node()) {
60486 var options = container
60487 .selectAll('a.combobox-option')
60488 .data(suggestions, function(d) { return d.value; });
60495 .attr('class', 'combobox-option')
60496 .text(function(d) { return d.value; })
60498 .attr('title', function(d) { return d.title; })
60499 .classed('selected', function(d, i) { return i === idx; })
60500 .on('mouseover', select$$1)
60501 .on('click', accept)
60505 var node = attachTo ? attachTo.node() : input.node(),
60506 rect = node.getBoundingClientRect();
60509 .style('left', rect.left + 'px')
60510 .style('width', rect.width + 'px')
60511 .style('top', rect.height + rect.top + 'px');
60514 function select$$1(d, i) {
60519 function ensureVisible() {
60520 var node = container.selectAll('a.selected').node();
60521 if (node) node.scrollIntoView();
60524 function accept(d) {
60525 if (!shown) return;
60527 .property('value', d.value)
60528 .dispatch('change');
60529 event$$1.call('accept', this, d);
60534 combobox.fetcher = function(_) {
60535 if (!arguments.length) return fetcher;
60540 combobox.data = function(_) {
60541 if (!arguments.length) return data;
60546 combobox.minItems = function(_) {
60547 if (!arguments.length) return minItems;
60552 combobox.caseSensitive = function(_) {
60553 if (!arguments.length) return caseSensitive;
60558 return utilRebind(combobox, event$$1, 'on');
60562 d3combobox.off = function(input) {
60564 .on('focus.typeahead', null)
60565 .on('blur.typeahead', null)
60566 .on('keydown.typeahead', null)
60567 .on('keyup.typeahead', null)
60568 .on('input.typeahead', null)
60570 select(this.parentNode).selectAll('.combobox-caret')
60571 .filter(function(d) { return d === input.node(); })
60572 .on('mousedown', null);
60575 select(document.body)
60576 .on('scroll.combobox', null);
60579 function uiDisclosure() {
60580 var dispatch$$1 = dispatch('toggled'),
60583 content = function () {};
60586 var disclosure = function(selection$$1) {
60587 var hideToggle = selection$$1.selectAll('.hide-toggle')
60590 hideToggle = hideToggle.enter()
60593 .attr('class', 'hide-toggle')
60594 .merge(hideToggle);
60598 .on('click', toggle)
60599 .classed('expanded', expanded);
60602 var wrap = selection$$1.selectAll('div')
60605 wrap = wrap.enter()
60610 .classed('hide', !expanded)
60614 function toggle() {
60615 expanded = !expanded;
60616 hideToggle.classed('expanded', expanded);
60617 wrap.call(uiToggle(expanded));
60618 dispatch$$1.call('toggled', this, expanded);
60623 disclosure.title = function(_) {
60624 if (!arguments.length) return title;
60630 disclosure.expanded = function(_) {
60631 if (!arguments.length) return expanded;
60637 disclosure.content = function(_) {
60638 if (!arguments.length) return content;
60644 return utilRebind(disclosure, dispatch$$1, 'on');
60647 function uiRawMemberEditor(context) {
60649 taginfo = services.taginfo;
60652 function selectMember(d) {
60653 event.preventDefault();
60654 context.enter(modeSelect(context, [d.id]).suppressMenu(true));
60658 function changeRole(d) {
60659 var role = select(this).property('value');
60660 var member = { id: d.id, type: d.type, role: role };
60662 actionChangeMember(d.relation.id, member, d.index),
60663 t('operations.change_role.annotation')
60668 function deleteMember(d) {
60670 actionDeleteMember(d.relation.id, d.index),
60671 t('operations.delete_member.annotation')
60674 if (!context.hasEntity(d.relation.id)) {
60675 context.enter(modeBrowse(context));
60680 function rawMemberEditor(selection$$1) {
60681 var entity = context.entity(id),
60684 entity.members.forEach(function(member, index) {
60691 member: context.hasEntity(member.id)
60695 selection$$1.call(uiDisclosure()
60696 .title(t('inspector.all_members') + ' (' + memberships.length + ')')
60698 .on('toggled', toggled)
60703 function toggled(expanded) {
60705 selection$$1.node().parentNode.scrollTop += 200;
60710 function content(wrap) {
60711 var list = wrap.selectAll('.member-list')
60714 list = list.enter()
60716 .attr('class', 'member-list')
60720 var items = list.selectAll('li')
60721 .data(memberships, function(d) {
60722 return osmEntity$$1.key(d.relation) + ',' + d.index + ',' +
60723 (d.member ? osmEntity$$1.key(d.member) : 'incomplete');
60730 var enter = items.enter()
60732 .attr('class', 'member-row form-field')
60733 .classed('member-incomplete', function(d) { return !d.member; });
60736 .each(function(d) {
60738 var label = select(this).append('label')
60739 .attr('class', 'form-label')
60742 .on('click', selectMember);
60744 label.append('span')
60745 .attr('class', 'member-entity-type')
60746 .text(function(d) {
60747 var matched = context.presets().match(d.member, context.graph());
60748 return (matched && matched.name()) || utilDisplayType(d.member.id);
60751 label.append('span')
60752 .attr('class', 'member-entity-name')
60753 .text(function(d) { return utilDisplayName(d.member); });
60756 select(this).append('label')
60757 .attr('class', 'form-label')
60758 .text(t('inspector.incomplete', { id: d.id }));
60764 .attr('class', 'member-role')
60765 .property('type', 'text')
60766 .attr('maxlength', 255)
60767 .attr('placeholder', t('inspector.role'))
60768 .property('value', function(d) { return d.role; })
60769 .on('change', changeRole);
60773 .attr('tabindex', -1)
60774 .attr('class', 'remove button-input-action member-delete minor')
60775 .on('click', deleteMember)
60776 .call(svgIcon('#operation-delete'));
60779 enter.each(bindTypeahead);
60783 function bindTypeahead(d) {
60784 var row = select(this),
60785 role = row.selectAll('input.member-role');
60787 function sort(value, data) {
60788 var sameletter = [],
60790 for (var i = 0; i < data.length; i++) {
60791 if (data[i].value.substring(0, value.length) === value) {
60792 sameletter.push(data[i]);
60794 other.push(data[i]);
60797 return sameletter.concat(other);
60800 role.call(d3combobox()
60801 .fetcher(function(role, callback) {
60802 var rtype = entity.tags.type;
60805 rtype: rtype || '',
60806 geometry: context.geometry(d.member.id),
60808 }, function(err, data) {
60809 if (!err) callback(sort(role, data));
60815 function unbind() {
60816 var row = select(this);
60818 row.selectAll('input.member-role')
60819 .call(d3combobox.off);
60825 rawMemberEditor.entityID = function(_) {
60826 if (!arguments.length) return id;
60828 return rawMemberEditor;
60832 return rawMemberEditor;
60835 function uiRawMembershipEditor(context) {
60836 var taginfo = services.taginfo,
60840 function selectRelation(d) {
60841 event.preventDefault();
60842 context.enter(modeSelect(context, [d.relation.id]).suppressMenu(true));
60846 function changeRole(d) {
60847 var role = select(this).property('value');
60849 actionChangeMember(d.relation.id, lodash.extend({}, d.member, { role: role }), d.index),
60850 t('operations.change_role.annotation')
60855 function addMembership(d, role) {
60860 actionAddMember(d.relation.id, { id: id, type: context.entity(id).type, role: role }),
60861 t('operations.add_member.annotation')
60865 var relation = osmRelation();
60867 actionAddEntity(relation),
60868 actionAddMember(relation.id, { id: id, type: context.entity(id).type, role: role }),
60869 t('operations.add.annotation.relation')
60872 context.enter(modeSelect(context, [relation.id]).suppressMenu(true));
60877 function deleteMembership(d) {
60879 actionDeleteMember(d.relation.id, d.index),
60880 t('operations.delete_member.annotation')
60885 function relations(q) {
60886 var newRelation = {
60888 value: t('inspector.new_relation')
60891 graph = context.graph();
60893 context.intersects(context.extent()).forEach(function(entity) {
60894 if (entity.type !== 'relation' || entity.id === id)
60897 var matched = context.presets().match(entity, graph),
60898 presetName = (matched && matched.name()) || t('inspector.relation'),
60899 entityName = utilDisplayName(entity) || '';
60901 var value = presetName + ' ' + entityName;
60902 if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
60911 result.sort(function(a, b) {
60912 return osmRelation.creationOrder(a.relation, b.relation);
60915 // Dedupe identical names by appending relation id - see #2891
60916 var dupeGroups = lodash(result)
60918 .filter(function(v) { return v.length > 1; })
60921 dupeGroups.forEach(function(group) {
60922 group.forEach(function(obj) {
60923 obj.value += ' ' + obj.relation.id;
60927 result.unshift(newRelation);
60932 function rawMembershipEditor(selection$$1) {
60933 var entity = context.entity(id),
60936 context.graph().parentRelations(entity).forEach(function(relation) {
60937 relation.members.forEach(function(member, index) {
60938 if (member.id === entity.id) {
60939 memberships.push({ relation: relation, member: member, index: index });
60944 selection$$1.call(uiDisclosure()
60945 .title(t('inspector.all_relations') + ' (' + memberships.length + ')')
60947 .on('toggled', toggled)
60952 function toggled(expanded) {
60954 selection$$1.node().parentNode.scrollTop += 200;
60959 function content(wrap) {
60960 var list = wrap.selectAll('.member-list')
60963 list = list.enter()
60965 .attr('class', 'member-list')
60969 var items = list.selectAll('li.member-row-normal')
60970 .data(memberships, function(d) {
60971 return osmEntity$$1.key(d.relation) + ',' + d.index;
60978 var enter = items.enter()
60980 .attr('class', 'member-row member-row-normal form-field');
60984 .attr('class', 'form-label')
60987 .on('click', selectRelation);
60991 .attr('class', 'member-entity-type')
60992 .text(function(d) {
60993 var matched = context.presets().match(d.relation, context.graph());
60994 return (matched && matched.name()) || t('inspector.relation');
60999 .attr('class', 'member-entity-name')
61000 .text(function(d) { return utilDisplayName(d.relation); });
61004 .attr('class', 'member-role')
61005 .property('type', 'text')
61006 .attr('maxlength', 255)
61007 .attr('placeholder', t('inspector.role'))
61008 .property('value', function(d) { return d.member.role; })
61009 .on('change', changeRole);
61013 .attr('tabindex', -1)
61014 .attr('class', 'remove button-input-action member-delete minor')
61015 .on('click', deleteMembership)
61016 .call(svgIcon('#operation-delete'));
61019 enter.each(bindTypeahead);
61023 var newrow = list.selectAll('.member-row-new')
61024 .data(showBlank ? [0] : []);
61029 enter = newrow.enter()
61031 .attr('class', 'member-row member-row-new form-field');
61035 .attr('type', 'text')
61036 .attr('class', 'member-entity-input');
61040 .attr('class', 'member-role')
61041 .property('type', 'text')
61042 .attr('maxlength', 255)
61043 .attr('placeholder', t('inspector.role'))
61044 .on('change', changeRole);
61048 .attr('tabindex', -1)
61049 .attr('class', 'remove button-input-action member-delete minor')
61050 .on('click', deleteMembership)
61051 .call(svgIcon('#operation-delete'));
61056 newrow.selectAll('.member-entity-input')
61059 .fetcher(function(value, callback) { callback(relations(value)); })
61060 .on('accept', onAccept)
61064 var addrel = wrap.selectAll('.add-relation')
61067 addrel = addrel.enter()
61069 .attr('class', 'add-relation')
61073 .call(svgIcon('#icon-plus', 'light'))
61074 .on('click', function() {
61077 list.selectAll('.member-entity-input').node().focus();
61081 function onAccept(d) {
61082 var role = list.selectAll('.member-row-new .member-role').property('value');
61083 addMembership(d, role);
61087 function bindTypeahead(d) {
61088 var row = select(this),
61089 role = row.selectAll('input.member-role');
61091 function sort(value, data) {
61092 var sameletter = [],
61094 for (var i = 0; i < data.length; i++) {
61095 if (data[i].value.substring(0, value.length) === value) {
61096 sameletter.push(data[i]);
61098 other.push(data[i]);
61101 return sameletter.concat(other);
61104 role.call(d3combobox()
61105 .fetcher(function(role, callback) {
61106 var rtype = d.relation.tags.type;
61109 rtype: rtype || '',
61110 geometry: context.geometry(id),
61112 }, function(err, data) {
61113 if (!err) callback(sort(role, data));
61119 function unbind() {
61120 var row = select(this);
61122 row.selectAll('input.member-role')
61123 .call(d3combobox.off);
61129 rawMembershipEditor.entityID = function(_) {
61130 if (!arguments.length) return id;
61132 return rawMembershipEditor;
61136 return rawMembershipEditor;
61139 function uiTagReference(tag) {
61140 var taginfo = services.taginfo,
61148 function findLocal(data) {
61149 var locale = utilDetect().locale.toLowerCase(),
61152 if (locale !== 'pt-br') { // see #3776, prefer 'pt' over 'pt-br'
61153 localized = lodash.find(data, function(d) {
61154 return d.lang.toLowerCase() === locale;
61156 if (localized) return localized;
61159 // try the non-regional version of a language, like
61160 // 'en' if the language is 'en-US'
61161 if (locale.indexOf('-') !== -1) {
61162 var first = locale.split('-')[0];
61163 localized = lodash.find(data, function(d) {
61164 return d.lang.toLowerCase() === first;
61166 if (localized) return localized;
61169 // finally fall back to english
61170 return lodash.find(data, function(d) {
61171 return d.lang.toLowerCase() === 'en';
61176 function load(param) {
61177 if (!taginfo) return;
61179 button.classed('tag-reference-loading', true);
61181 taginfo.docs(param, function show(err, data) {
61183 if (!err && data) {
61184 docs = findLocal(data);
61190 if (!docs || !docs.title) {
61191 if (param.hasOwnProperty('value')) {
61192 load(lodash.omit(param, 'value')); // retry with key only
61194 body.append('p').text(t('inspector.no_documentation_key'));
61201 if (docs.image && docs.image.thumb_url_prefix) {
61204 .attr('class', 'wiki-image')
61205 .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
61206 .on('load', function() { done(); })
61207 .on('error', function() { select(this).remove(); done(); });
61214 .text(docs.description || t('inspector.documentation_redirect'));
61218 .attr('target', '_blank')
61219 .attr('tabindex', -1)
61220 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
61221 .call(svgIcon('#icon-out-link', 'inline'))
61223 .text(t('inspector.reference'));
61231 button.classed('tag-reference-loading', false);
61235 .style('max-height', '200px')
61236 .style('opacity', '1');
61242 function hide(selection$$1) {
61243 selection$$1 = selection$$1 || body.transition().duration(200);
61246 .style('max-height', '0px')
61247 .style('opacity', '0');
61253 tagReference.button = function(selection$$1) {
61254 button = selection$$1.selectAll('.tag-reference-button')
61257 button = button.enter()
61259 .attr('class', 'tag-reference-button')
61260 .attr('tabindex', -1)
61261 .call(svgIcon('#icon-inspect'))
61265 .on('click', function () {
61266 event.stopPropagation();
61267 event.preventDefault();
61270 } else if (loaded) {
61279 tagReference.body = function(selection$$1) {
61280 body = selection$$1.selectAll('.tag-reference-body')
61283 body = body.enter()
61285 .attr('class', 'tag-reference-body cf')
61286 .style('max-height', '0')
61287 .style('opacity', '0')
61290 if (showing === false) {
61296 tagReference.showing = function(_) {
61297 if (!arguments.length) return showing;
61299 return tagReference;
61303 return tagReference;
61306 function uiRawTagEditor(context) {
61307 var taginfo = services.taginfo,
61308 dispatch$$1 = dispatch('change'),
61316 function rawTagEditor(selection$$1) {
61317 var count = Object.keys(tags).filter(function(d) { return d; }).length;
61319 selection$$1.call(uiDisclosure()
61320 .title(t('inspector.all_tags') + ' (' + count + ')')
61321 .expanded(context.storage('raw_tag_editor.expanded') === 'true' || preset.isFallback())
61322 .on('toggled', toggled)
61323 .content(content));
61325 function toggled(expanded) {
61326 context.storage('raw_tag_editor.expanded', expanded);
61328 selection$$1.node().parentNode.scrollTop += 200;
61334 function content(wrap) {
61335 var entries$$1 = entries(tags);
61337 if (!entries$$1.length || showBlank) {
61339 entries$$1.push({key: '', value: ''});
61342 var list = wrap.selectAll('.tag-list')
61345 list = list.enter()
61347 .attr('class', 'tag-list')
61350 var newTag = wrap.selectAll('.add-tag')
61355 .attr('class', 'add-tag')
61356 .on('click', addTag)
61357 .call(svgIcon('#icon-plus', 'light'));
61360 var items = list.selectAll('.tag-row')
61361 .data(entries$$1, function(d) { return d.key; });
61369 var enter = items.enter()
61371 .attr('class', 'tag-row cf');
61375 .attr('class', 'key-wrap')
61377 .property('type', 'text')
61378 .attr('class', 'key')
61379 .attr('maxlength', 255)
61380 .on('blur', keyChange)
61381 .on('change', keyChange);
61385 .attr('class', 'input-wrap-position')
61387 .property('type', 'text')
61388 .attr('class', 'value')
61389 .attr('maxlength', 255)
61390 .on('blur', valueChange)
61391 .on('change', valueChange)
61392 .on('keydown.push-more', pushMore);
61396 .attr('tabindex', -1)
61397 .attr('class', 'remove minor')
61398 .call(svgIcon('#operation-delete'));
61405 .sort(function(a, b) {
61406 return (a.key === '') ? 1
61407 : (b.key === '') ? -1
61408 : ascending(a.key, b.key);
61412 .each(function(tag) {
61413 var row = select(this),
61414 key = row.select('input.key'), // propagate bound data to child
61415 value = row.select('input.value'); // propagate bound data to child
61418 bindTypeahead(key, value);
61421 var isRelation = (context.entity(id).type === 'relation'),
61424 if (isRelation && tag.key === 'type') {
61425 reference = uiTagReference({ rtype: tag.value }, context);
61427 reference = uiTagReference({ key: tag.key, value: tag.value }, context);
61430 if (state === 'hover') {
61431 reference.showing(false);
61435 .call(reference.button)
61436 .call(reference.body);
61439 items.selectAll('input.key')
61440 .attr('title', function(d) { return d.key; })
61441 .call(utilGetSetValue, function(d) { return d.key; });
61443 items.selectAll('input.value')
61444 .attr('title', function(d) { return d.value; })
61445 .call(utilGetSetValue, function(d) { return d.value; });
61447 items.selectAll('button.remove')
61448 .on('click', removeTag);
61451 function pushMore() {
61452 if (event.keyCode === 9 && !event.shiftKey &&
61453 list.selectAll('li:last-child input.value').node() === this) {
61459 function bindTypeahead(key, value) {
61461 function sort(value, data) {
61462 var sameletter = [],
61464 for (var i = 0; i < data.length; i++) {
61465 if (data[i].value.substring(0, value.length) === value) {
61466 sameletter.push(data[i]);
61468 other.push(data[i]);
61471 return sameletter.concat(other);
61474 key.call(d3combobox()
61475 .fetcher(function(value, callback) {
61478 geometry: context.geometry(id),
61480 }, function(err, data) {
61481 if (!err) callback(sort(value, data));
61485 value.call(d3combobox()
61486 .fetcher(function(value, callback) {
61489 key: utilGetSetValue(key),
61490 geometry: context.geometry(id),
61492 }, function(err, data) {
61493 if (!err) callback(sort(value, data));
61499 function unbind() {
61500 var row = select(this);
61502 row.selectAll('input.key')
61503 .call(d3combobox.off);
61505 row.selectAll('input.value')
61506 .call(d3combobox.off);
61510 function keyChange(d) {
61512 kNew = this.value.trim(),
61515 if (kNew && kNew !== kOld) {
61516 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
61518 suffix = +(match[2] || 1);
61519 while (tags[kNew]) { // rename key if already in use
61520 kNew = base + '_' + suffix++;
61523 tag[kOld] = undefined;
61524 tag[kNew] = d.value;
61525 d.key = kNew; // Maintain DOM identity through the subsequent update.
61527 dispatch$$1.call('change', this, tag);
61531 function valueChange(d) {
61533 tag[d.key] = this.value;
61534 dispatch$$1.call('change', this, tag);
61538 function removeTag(d) {
61540 tag[d.key] = undefined;
61541 dispatch$$1.call('change', this, tag);
61542 select(this.parentNode).remove();
61546 function addTag() {
61547 // Wrapped in a setTimeout in case it's being called from a blur
61548 // handler. Without the setTimeout, the call to `content` would
61549 // wipe out the pending value change.
61550 setTimeout(function() {
61553 list.selectAll('li:last-child input.key').node().focus();
61559 rawTagEditor.state = function(_) {
61560 if (!arguments.length) return state;
61562 return rawTagEditor;
61566 rawTagEditor.preset = function(_) {
61567 if (!arguments.length) return preset;
61569 return rawTagEditor;
61573 rawTagEditor.tags = function(_) {
61574 if (!arguments.length) return tags;
61576 return rawTagEditor;
61580 rawTagEditor.entityID = function(_) {
61581 if (!arguments.length) return id;
61583 return rawTagEditor;
61587 return utilRebind(rawTagEditor, dispatch$$1, 'on');
61590 function uiFieldCheck(field) {
61591 var dispatch$$1 = dispatch('change'),
61592 options = field.strings && field.strings.options,
61595 input = select(null),
61596 text$$1 = select(null),
61597 label = select(null),
61601 for (var k in options) {
61602 values$$1.push(k === 'undefined' ? undefined : k);
61603 texts.push(field.t('options.' + k, { 'default': options[k] }));
61606 values$$1 = [undefined, 'yes'];
61607 texts = [t('inspector.unknown'), t('inspector.check.yes')];
61608 if (field.type === 'check') {
61609 values$$1.push('no');
61610 texts.push(t('inspector.check.no'));
61615 var check = function(selection$$1) {
61616 // hack: pretend oneway field is a oneway_yes field
61617 // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
61618 if (field.id === 'oneway') {
61619 for (var key in entity.tags) {
61620 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
61621 texts[0] = t('presets.fields.oneway_yes.options.undefined');
61627 selection$$1.classed('checkselect', 'true');
61629 label = selection$$1.selectAll('.preset-input-wrap')
61632 var enter = label.enter()
61634 .attr('class', 'preset-input-wrap');
61638 .property('indeterminate', field.type === 'check')
61639 .attr('type', 'checkbox')
61640 .attr('id', 'preset-input-' + field.id);
61645 .attr('class', 'value');
61647 label = label.merge(enter);
61648 input = label.selectAll('input');
61649 text$$1 = label.selectAll('span.value');
61652 .on('click', function() {
61654 t$$1[field.key] = values$$1[(values$$1.indexOf(value) + 1) % values$$1.length];
61655 dispatch$$1.call('change', this, t$$1);
61656 event.stopPropagation();
61661 check.entity = function(_) {
61662 if (!arguments.length) return entity;
61668 check.tags = function(tags) {
61669 value = tags[field.key];
61670 input.property('indeterminate', field.type === 'check' && !value);
61671 input.property('checked', value === 'yes');
61672 text$$1.text(texts[values$$1.indexOf(value)]);
61673 label.classed('set', !!value);
61677 check.focus = function() {
61678 input.node().focus();
61681 return utilRebind(check, dispatch$$1, 'on');
61684 function uiFieldCombo(field, context) {
61685 var dispatch$$1 = dispatch('change'),
61686 nominatim = services.geocoder,
61687 taginfo = services.taginfo,
61688 isMulti = (field.type === 'multiCombo'),
61689 isNetwork = (field.type === 'networkCombo'),
61690 optstrings = field.strings && field.strings.options,
61691 optarray = field.options,
61692 snake_case = (field.snake_case || (field.snake_case === undefined)),
61693 combobox = d3combobox().minItems(isMulti ? 1 : 2),
61701 // ensure multiCombo field.key ends with a ':'
61702 if (isMulti && field.key.match(/:$/) === null) {
61707 function snake(s) {
61708 return s.replace(/\s+/g, '_');
61711 function unsnake(s) {
61712 return s.replace(/_+/g, ' ');
61715 function clean(s) {
61716 return s.split(';')
61717 .map(function(s) { return s.trim(); })
61722 // returns the tag value for a display value
61723 // (for multiCombo, dval should be the key suffix, not the entire key)
61724 function tagValue(dval) {
61725 dval = clean(dval || '');
61728 var match = lodash.find(comboData, function(o) {
61729 return o.key && clean(o.value) === dval;
61736 if (field.type === 'typeCombo' && !dval) {
61740 return (snake_case ? snake(dval) : dval) || undefined;
61744 // returns the display value for a tag value
61745 // (for multiCombo, tval should be the key suffix, not the entire key)
61746 function displayValue(tval) {
61750 var match = lodash.find(comboData, function(o) { return o.key === tval && o.value; });
61752 return match.value;
61756 if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
61760 return snake_case ? unsnake(tval) : tval;
61764 function objectDifference(a, b) {
61765 return lodash.reject(a, function(d1) {
61766 return lodash.some(b, function(d2) { return d1.value === d2.value; });
61771 function initCombo(selection$$1, attachTo) {
61773 selection$$1.attr('readonly', 'readonly');
61774 selection$$1.call(combobox, attachTo);
61775 setStaticValues(setPlaceholder);
61777 } else if (optarray) {
61778 selection$$1.call(combobox, attachTo);
61779 setStaticValues(setPlaceholder);
61781 } else if (taginfo) {
61782 selection$$1.call(combobox.fetcher(setTaginfoValues), attachTo);
61783 setTaginfoValues('', setPlaceholder);
61788 function setStaticValues(callback) {
61789 if (!(optstrings || optarray)) return;
61792 comboData = Object.keys(optstrings).map(function(k) {
61793 var v = field.t('options.' + k, { 'default': optstrings[k] });
61801 } else if (optarray) {
61802 comboData = optarray.map(function(k) {
61803 var v = snake_case ? unsnake(k) : k;
61812 combobox.data(objectDifference(comboData, multiData));
61813 if (callback) callback(comboData);
61817 function setTaginfoValues(q, callback) {
61818 var fn = isMulti ? 'multikeys' : 'values';
61819 var query = (isMulti ? field.key : '') + q;
61820 var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
61821 if (hasCountryPrefix) {
61822 query = country + ':';
61827 geometry: context.geometry(entity.id),
61829 }, function(err, data) {
61831 if (hasCountryPrefix) {
61832 data = lodash.filter(data, function(d) {
61833 return d.value.toLowerCase().indexOf(country + ':') === 0;
61836 comboData = lodash.map(data, function(d) {
61838 if (isMulti) k = k.replace(field.key, '');
61839 var v = snake_case ? unsnake(k) : k;
61843 title: isMulti ? v : d.title
61846 comboData = objectDifference(comboData, multiData);
61847 if (callback) callback(comboData);
61852 function setPlaceholder(d) {
61855 ph = field.placeholder() || t('inspector.add');
61857 var vals = lodash.map(d, 'value').filter(function(s) { return s.length < 20; }),
61858 placeholders = vals.length > 1 ? vals : lodash.map(d, 'key');
61859 ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
61862 container.selectAll('input')
61863 .attr('placeholder', ph + '…');
61867 function change() {
61868 var val = tagValue(utilGetSetValue(input)),
61873 container.classed('active', false);
61874 utilGetSetValue(input, '');
61875 field.keys.push(field.key + val);
61876 t$$1[field.key + val] = 'yes';
61877 window.setTimeout(function() { input.node().focus(); }, 10);
61880 t$$1[field.key] = val;
61883 dispatch$$1.call('change', this, t$$1);
61887 function removeMultikey(d) {
61888 event.stopPropagation();
61890 t$$1[d.key] = undefined;
61891 dispatch$$1.call('change', this, t$$1);
61895 function combo(selection$$1) {
61897 container = selection$$1.selectAll('ul').data([0]);
61899 container = container.enter()
61901 .attr('class', 'form-field-multicombo')
61902 .on('click', function() {
61903 window.setTimeout(function() { input.node().focus(); }, 10);
61908 container = selection$$1;
61911 input = container.selectAll('input')
61914 input = input.enter()
61916 .attr('type', 'text')
61917 .attr('id', 'preset-input-' + field.id)
61918 .call(initCombo, selection$$1)
61921 if (isNetwork && nominatim && entity) {
61922 var center = entity.extent(context.graph()).center();
61923 nominatim.countryCode(center, function (err, code) {
61929 .on('change', change)
61930 .on('blur', change);
61934 .on('accept', function() {
61935 input.node().blur();
61936 input.node().focus();
61940 .on('focus', function() { container.classed('active', true); });
61945 combo.tags = function(tags) {
61949 // Build multiData array containing keys already set..
61950 Object.keys(tags).forEach(function(key) {
61951 if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
61953 var suffix = key.substring(field.key.length);
61956 value: displayValue(suffix)
61960 // Set keys for form-field modified (needed for undo and reset buttons)..
61961 field.keys = lodash.map(multiData, 'key');
61963 // Exclude existing multikeys from combo options..
61964 var available = objectDifference(comboData, multiData);
61965 combobox.data(available);
61967 // Hide 'Add' button if this field uses fixed set of
61968 // translateable optstrings and they're all currently used..
61969 container.selectAll('.combobox-input, .combobox-caret')
61970 .classed('hide', optstrings && !available.length);
61974 var chips = container.selectAll('.chips')
61980 var enter = chips.enter()
61981 .insert('li', 'input')
61982 .attr('class', 'chips');
61984 enter.append('span');
61987 chips = chips.merge(enter);
61989 chips.select('span')
61990 .text(function(d) { return d.value; });
61993 .on('click', removeMultikey)
61994 .attr('class', 'remove')
61998 utilGetSetValue(input, displayValue(tags[field.key]));
62003 combo.focus = function() {
62004 input.node().focus();
62008 combo.entity = function(_) {
62009 if (!arguments.length) return entity;
62015 return utilRebind(combo, dispatch$$1, 'on');
62018 function uiFieldText(field, context) {
62019 var dispatch$$1 = dispatch('change'),
62020 nominatim = services.geocoder,
62025 function i(selection$$1) {
62026 var fieldId = 'preset-input-' + field.id;
62028 input = selection$$1.selectAll('input')
62031 input = input.enter()
62033 .attr('type', field.type)
62034 .attr('id', fieldId)
62035 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
62039 .on('input', change(true))
62040 .on('blur', change())
62041 .on('change', change());
62043 if (field.type === 'tel' && nominatim && entity) {
62044 var center = entity.extent(context.graph()).center();
62045 nominatim.countryCode(center, function (err, countryCode) {
62046 if (err || !dataPhoneFormats[countryCode]) return;
62047 selection$$1.selectAll('#' + fieldId)
62048 .attr('placeholder', dataPhoneFormats[countryCode]);
62051 } else if (field.type === 'number') {
62052 input.attr('type', 'text');
62054 var spinControl = selection$$1.selectAll('.spin-control')
62057 var enter = spinControl.enter()
62059 .attr('class', 'spin-control');
62064 .attr('class', 'increment')
62065 .attr('tabindex', -1);
62070 .attr('class', 'decrement')
62071 .attr('tabindex', -1);
62073 spinControl = spinControl
62076 spinControl.selectAll('button')
62077 .on('click', function(d) {
62078 event.preventDefault();
62079 var num = parseInt(input.node().value || 0, 10);
62080 if (!isNaN(num)) input.node().value = num + d;
62087 function change(onInput) {
62088 return function() {
62090 t$$1[field.key] = utilGetSetValue(input) || undefined;
62091 dispatch$$1.call('change', this, t$$1, onInput);
62096 i.entity = function(_) {
62097 if (!arguments.length) return entity;
62103 i.tags = function(tags) {
62104 utilGetSetValue(input, tags[field.key] || '');
62108 i.focus = function() {
62109 var node = input.node();
62110 if (node) node.focus();
62113 return utilRebind(i, dispatch$$1, 'on');
62116 function uiFieldAccess(field) {
62117 var dispatch$$1 = dispatch('change'),
62120 function access(selection$$1) {
62121 var wrap = selection$$1.selectAll('.preset-input-wrap')
62124 wrap = wrap.enter()
62126 .attr('class', 'cf preset-input-wrap')
62130 var list = wrap.selectAll('ul')
62133 list = list.enter()
62138 items = list.selectAll('li')
62142 var enter = items.enter()
62144 .attr('class', function(d) { return 'cf preset-access-' + d; });
62148 .attr('class', 'col6 label preset-label-access')
62149 .attr('for', function(d) { return 'preset-input-access-' + d; })
62150 .text(function(d) { return field.t('types.' + d); });
62154 .attr('class', 'col6 preset-input-access-wrap')
62156 .attr('type', 'text')
62157 .attr('class', 'preset-input-access')
62158 .attr('id', function(d) { return 'preset-input-access-' + d; })
62159 .each(function(d) {
62162 .data(access.options(d)));
62167 items = items.merge(enter);
62169 wrap.selectAll('.preset-input-access')
62170 .on('change', change)
62171 .on('blur', change);
62175 function change(d) {
62177 tag[d] = utilGetSetValue(select(this)) || undefined;
62178 dispatch$$1.call('change', this, tag);
62182 access.options = function(type) {
62183 var options = ['no', 'permissive', 'private', 'destination'];
62185 if (type !== 'access') {
62186 options.unshift('yes');
62187 options.push('designated');
62189 if (type === 'bicycle') {
62190 options.push('dismount');
62194 return options.map(function(option) {
62196 title: field.t('options.' + option + '.description'),
62203 var placeholders = {
62205 foot: 'designated',
62206 motor_vehicle: 'no'
62210 motor_vehicle: 'no',
62216 motor_vehicle: 'no'
62219 motor_vehicle: 'no',
62220 bicycle: 'designated'
62223 motor_vehicle: 'no',
62224 horse: 'designated'
62228 motor_vehicle: 'no',
62234 motor_vehicle: 'yes',
62239 motor_vehicle: 'yes'
62243 motor_vehicle: 'yes',
62249 motor_vehicle: 'yes',
62255 motor_vehicle: 'yes',
62261 motor_vehicle: 'yes',
62267 motor_vehicle: 'yes',
62273 motor_vehicle: 'yes',
62279 motor_vehicle: 'yes',
62284 motor_vehicle: 'yes'
62288 motor_vehicle: 'yes',
62294 motor_vehicle: 'yes',
62300 motor_vehicle: 'yes',
62307 access.tags = function(tags) {
62308 utilGetSetValue(items.selectAll('.preset-input-access'),
62309 function(d) { return tags[d] || ''; })
62310 .attr('placeholder', function() {
62311 return tags.access ? tags.access : field.placeholder();
62314 items.selectAll('#preset-input-access-access')
62315 .attr('placeholder', 'yes');
62317 lodash.forEach(placeholders[tags.highway], function(v, k) {
62318 items.selectAll('#preset-input-access-' + k)
62319 .attr('placeholder', function() { return (tags.access || v); });
62324 access.focus = function() {
62325 items.selectAll('.preset-input-access')
62330 return utilRebind(access, dispatch$$1, 'on');
62333 function uiFieldAddress(field, context) {
62334 var dispatch$$1 = dispatch('init', 'change'),
62335 nominatim = services.geocoder,
62336 wrap = select(null),
62337 isInitialized = false,
62340 function getNearStreets() {
62341 var extent$$1 = entity.extent(context.graph()),
62342 l = extent$$1.center(),
62343 box = geoExtent$$1(l).padByMeters(200);
62345 var streets = context.intersects(box)
62346 .filter(isAddressable)
62348 var loc = context.projection([
62349 (extent$$1[0][0] + extent$$1[1][0]) / 2,
62350 (extent$$1[0][1] + extent$$1[1][1]) / 2]),
62351 choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
62353 title: d.tags.name,
62354 value: d.tags.name,
62355 dist: choice.distance
62358 .sort(function(a, b) {
62359 return a.dist - b.dist;
62362 return lodash.uniqBy(streets, 'value');
62364 function isAddressable(d) {
62365 return d.tags.highway && d.tags.name && d.type === 'way';
62370 function getNearCities() {
62371 var extent$$1 = entity.extent(context.graph()),
62372 l = extent$$1.center(),
62373 box = geoExtent$$1(l).padByMeters(200);
62375 var cities = context.intersects(box)
62376 .filter(isAddressable)
62379 title: d.tags['addr:city'] || d.tags.name,
62380 value: d.tags['addr:city'] || d.tags.name,
62381 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62384 .sort(function(a, b) {
62385 return a.dist - b.dist;
62388 return lodash.uniqBy(cities, 'value');
62391 function isAddressable(d) {
62393 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
62396 if (d.tags.place && d.tags.name && (
62397 d.tags.place === 'city' ||
62398 d.tags.place === 'town' ||
62399 d.tags.place === 'village'))
62402 if (d.tags['addr:city']) return true;
62408 function getNearValues(key) {
62409 var extent$$1 = entity.extent(context.graph()),
62410 l = extent$$1.center(),
62411 box = geoExtent$$1(l).padByMeters(200);
62413 var results = context.intersects(box)
62414 .filter(function hasTag(d) {
62415 return d.tags[key];
62419 title: d.tags[key],
62420 value: d.tags[key],
62421 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62424 .sort(function(a, b) {
62425 return a.dist - b.dist;
62428 return lodash.uniqBy(results, 'value');
62432 function initCallback(err, countryCode) {
62435 var addressFormat = lodash.find(dataAddressFormats, function (a) {
62436 return a && a.countryCodes && lodash.includes(a.countryCodes, countryCode);
62437 }) || lodash.first(dataAddressFormats);
62439 var widths = addressFormat.widths || {
62440 housenumber: 1/3, street: 2/3,
62441 city: 2/3, state: 1/4, postcode: 1/3
62445 // Normalize widths.
62446 var total = lodash.reduce(r, function(sum$$1, field) {
62447 return sum$$1 + (widths[field] || 0.5);
62450 return r.map(function (field) {
62453 width: (widths[field] || 0.5) / total
62458 wrap.selectAll('div.addr-row')
62459 .data(addressFormat.format)
62462 .attr('class', 'addr-row')
62463 .selectAll('input')
62467 .property('type', 'text')
62468 .attr('placeholder', function (d) {
62469 var localkey = d.id + '!' + countryCode,
62470 tkey = field.strings.placeholders[localkey] ? localkey : d.id;
62471 return field.t('placeholders.' + tkey);
62473 .attr('class', function (d) { return 'addr-' + d.id; })
62474 .style('width', function (d) { return d.width * 100 + '%'; });
62478 // setup dropdowns for common address tags
62479 var dropdowns = addressFormat.dropdowns || [
62480 'city', 'county', 'country', 'district', 'hamlet',
62481 'neighbourhood', 'place', 'postcode', 'province',
62482 'quarter', 'state', 'street', 'subdistrict', 'suburb'
62485 // If fields exist for any of these tags, create dropdowns to pick nearby values..
62486 dropdowns.forEach(function(tag) {
62487 var nearValues = (tag === 'street') ? getNearStreets
62488 : (tag === 'city') ? getNearCities
62491 wrap.selectAll('input.addr-' + tag)
62494 .fetcher(function(value, callback) {
62495 callback(nearValues('addr:' + tag));
62499 wrap.selectAll('input')
62500 .on('blur', change())
62501 .on('change', change());
62503 wrap.selectAll('input:not(.combobox-input)')
62504 .on('input', change(true));
62506 dispatch$$1.call('init');
62507 isInitialized = true;
62511 function address(selection$$1) {
62512 isInitialized = false;
62514 wrap = selection$$1.selectAll('.preset-input-wrap')
62517 wrap = wrap.enter()
62519 .attr('class', 'preset-input-wrap')
62522 if (nominatim && entity) {
62523 var center = entity.extent(context.graph()).center();
62524 nominatim.countryCode(center, initCallback);
62529 function change(onInput) {
62530 return function() {
62533 wrap.selectAll('input')
62534 .each(function (field) {
62535 tags['addr:' + field.id] = this.value || undefined;
62538 dispatch$$1.call('change', this, tags, onInput);
62543 function updateTags(tags) {
62544 utilGetSetValue(wrap.selectAll('input'), function (field) {
62545 return tags['addr:' + field.id] || '';
62550 address.entity = function(_) {
62551 if (!arguments.length) return entity;
62557 address.tags = function(tags) {
62558 if (isInitialized) {
62561 dispatch$$1.on('init', function () {
62562 dispatch$$1.on('init', null);
62569 address.focus = function() {
62570 var node = wrap.selectAll('input').node();
62571 if (node) node.focus();
62575 return utilRebind(address, dispatch$$1, 'on');
62578 function uiFieldCycleway(field) {
62579 var dispatch$$1 = dispatch('change'),
62580 items = select(null);
62583 function cycleway(selection$$1) {
62585 function stripcolon(s) {
62586 return s.replace(':', '');
62590 var wrap = selection$$1.selectAll('.preset-input-wrap')
62593 wrap = wrap.enter()
62595 .attr('class', 'cf preset-input-wrap')
62599 var div = wrap.selectAll('ul')
62607 items = div.selectAll('li')
62610 var enter = items.enter()
62612 .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
62616 .attr('class', 'col6 label preset-label-cycleway')
62617 .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
62618 .text(function(d) { return field.t('types.' + d); });
62622 .attr('class', 'col6 preset-input-cycleway-wrap')
62624 .attr('type', 'text')
62625 .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
62626 .each(function(d) {
62627 select(this).call(d3combobox().data(cycleway.options(d)));
62632 wrap.selectAll('.preset-input-cycleway')
62633 .on('change', change)
62634 .on('blur', change);
62638 function change() {
62639 var left = utilGetSetValue(select('.preset-input-cyclewayleft')),
62640 right = utilGetSetValue(select('.preset-input-cyclewayright')),
62643 if (left === 'none' || left === '') { left = undefined; }
62644 if (right === 'none' || right === '') { right = undefined; }
62646 // Always set both left and right as changing one can affect the other
62648 cycleway: undefined,
62649 'cycleway:left': left,
62650 'cycleway:right': right
62653 // If the left and right tags match, use the cycleway tag to tag both
62654 // sides the same way
62655 if (left === right) {
62658 'cycleway:left': undefined,
62659 'cycleway:right': undefined
62663 dispatch$$1.call('change', this, tag);
62667 cycleway.options = function() {
62668 return keys(field.strings.options).map(function(option) {
62670 title: field.t('options.' + option + '.description'),
62677 cycleway.tags = function(tags) {
62678 utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
62679 // If cycleway is set, always return that
62680 if (tags.cycleway) {
62681 return tags.cycleway;
62683 return tags[d] || '';
62685 .attr('placeholder', field.placeholder());
62689 cycleway.focus = function() {
62690 items.selectAll('.preset-input-cycleway')
62695 return utilRebind(cycleway, dispatch$$1, 'on');
62698 function uiFieldLanes(field, context) {
62699 var dispatch$$1 = dispatch('change'),
62705 function lanes(selection$$1) {
62706 lanesData = context.entity(wayID).lanes();
62708 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
62709 selection$$1.call(lanes.off);
62713 var wrap = selection$$1.selectAll('.preset-input-wrap')
62716 wrap = wrap.enter()
62718 .attr('class', 'preset-input-wrap')
62721 var surface = wrap.selectAll('.surface')
62724 var d = utilGetDimensions(wrap);
62725 var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
62727 surface = surface.enter()
62729 .attr('width', d[0])
62730 .attr('height', 300)
62731 .attr('class', 'surface')
62735 var lanesSelection = surface.selectAll('.lanes')
62738 lanesSelection = lanesSelection.enter()
62740 .attr('class', 'lanes')
62741 .merge(lanesSelection);
62744 .attr('transform', function () {
62745 return 'translate(' + (freeSpace / 2) + ', 0)';
62749 var lane = lanesSelection.selectAll('.lane')
62750 .data(lanesData.lanes);
62755 var enter = lane.enter()
62757 .attr('class', 'lane');
62763 .attr('width', LANE_WIDTH)
62764 .attr('height', LANE_HEIGHT);
62768 .attr('class', 'forward')
62776 .attr('class', 'bothways')
62784 .attr('class', 'backward')
62795 .attr('transform', function(d) {
62796 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
62799 lane.select('.forward')
62800 .style('visibility', function(d) {
62801 return d.direction === 'forward' ? 'visible' : 'hidden';
62804 lane.select('.bothways')
62805 .style('visibility', function(d) {
62806 return d.direction === 'bothways' ? 'visible' : 'hidden';
62809 lane.select('.backward')
62810 .style('visibility', function(d) {
62811 return d.direction === 'backward' ? 'visible' : 'hidden';
62816 lanes.entity = function(_) {
62817 if (!wayID || wayID !== _.id) {
62822 lanes.tags = function() {};
62823 lanes.focus = function() {};
62824 lanes.off = function() {};
62826 return utilRebind(lanes, dispatch$$1, 'on');
62829 function uiFieldLocalized(field, context) {
62830 var dispatch$$1 = dispatch('change', 'input'),
62831 wikipedia = services.wikipedia,
62832 input = select(null),
62833 localizedInputs = select(null),
62838 function localized(selection$$1) {
62839 input = selection$$1.selectAll('.localized-main')
62842 input = input.enter()
62844 .attr('type', 'text')
62845 .attr('id', 'preset-input-' + field.id)
62846 .attr('class', 'localized-main')
62847 .attr('placeholder', field.placeholder())
62850 if (field.id === 'name') {
62851 var preset = context.presets().match(entity, context.graph());
62852 input.call(d3combobox().fetcher(
62853 utilSuggestNames(preset, dataSuggestions)
62858 .on('input', change(true))
62859 .on('blur', change())
62860 .on('change', change());
62863 var translateButton = selection$$1.selectAll('.localized-add')
62866 translateButton = translateButton.enter()
62868 .attr('class', 'button-input-action localized-add minor')
62869 .attr('tabindex', -1)
62870 .call(svgIcon('#icon-plus'))
62872 .title(t('translate.translate'))
62873 .placement('left'))
62874 .merge(translateButton);
62877 .on('click', addNew);
62880 localizedInputs = selection$$1.selectAll('.localized-wrap')
62883 localizedInputs = localizedInputs.enter().append('div')
62884 .attr('class', 'localized-wrap')
62885 .merge(localizedInputs);
62889 function addNew() {
62890 event.preventDefault();
62891 var data$$1 = localizedInputs.selectAll('div.entry').data();
62892 var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
62893 var langExists = lodash.find(data$$1, function(datum) { return datum.lang === defaultLang;});
62894 var isLangEn = defaultLang.indexOf('en') > -1;
62895 if (isLangEn || langExists) {
62898 data$$1.push({ lang: defaultLang, value: '' });
62899 localizedInputs.call(render, data$$1);
62903 function change(onInput) {
62904 return function() {
62906 t$$1[field.key] = utilGetSetValue(select(this)) || undefined;
62907 dispatch$$1.call('change', this, t$$1, onInput);
62912 function key(lang) {
62913 return field.key + ':' + lang;
62917 function changeLang(d) {
62918 var lang = utilGetSetValue(select(this)),
62920 language = lodash.find(dataWikipedia, function(d) {
62921 return d[0].toLowerCase() === lang.toLowerCase() ||
62922 d[1].toLowerCase() === lang.toLowerCase();
62925 if (language) lang = language[2];
62927 if (d.lang && d.lang !== lang) {
62928 t$$1[key(d.lang)] = undefined;
62931 var value = utilGetSetValue(select(this.parentNode)
62932 .selectAll('.localized-value'));
62934 if (lang && value) {
62935 t$$1[key(lang)] = value;
62936 } else if (lang && wikiTitles && wikiTitles[d.lang]) {
62937 t$$1[key(lang)] = wikiTitles[d.lang];
62941 dispatch$$1.call('change', this, t$$1);
62945 function changeValue(d) {
62946 if (!d.lang) return;
62948 t$$1[key(d.lang)] = utilGetSetValue(select(this)) || undefined;
62949 dispatch$$1.call('change', this, t$$1);
62953 function fetcher(value, cb) {
62954 var v = value.toLowerCase();
62956 cb(dataWikipedia.filter(function(d) {
62957 return d[0].toLowerCase().indexOf(v) >= 0 ||
62958 d[1].toLowerCase().indexOf(v) >= 0 ||
62959 d[2].toLowerCase().indexOf(v) >= 0;
62960 }).map(function(d) {
62961 return { value: d[1] };
62966 function render(selection$$1, data$$1) {
62967 var wraps = selection$$1.selectAll('div.entry').
62968 data(data$$1, function(d) { return d.lang; });
62973 .style('max-height','0px')
62974 .style('opacity', '0')
62975 .style('top','-10px')
62978 var innerWrap = wraps.enter()
62979 .insert('div', ':first-child');
62981 innerWrap.attr('class', 'entry')
62983 var wrap = select(this);
62984 var langcombo = d3combobox().fetcher(fetcher).minItems(0);
62988 .attr('class','form-label')
62989 .text(t('translate.localized_translation_label'))
62990 .attr('for','localized-lang');
62994 .attr('class', 'minor remove')
62995 .on('click', function(d){
62996 event.preventDefault();
62998 t$$1[key(d.lang)] = undefined;
62999 dispatch$$1.call('change', this, t$$1);
63000 select(this.parentNode.parentNode)
63002 .style('max-height','240px')
63004 .style('opacity', '0')
63005 .style('max-height','0px')
63008 .call(svgIcon('#operation-delete'));
63012 .attr('class', 'localized-lang')
63013 .attr('type', 'text')
63014 .attr('placeholder',t('translate.localized_translation_language'))
63015 .on('blur', changeLang)
63016 .on('change', changeLang)
63021 .on('blur', changeValue)
63022 .on('change', changeValue)
63023 .attr('type', 'text')
63024 .attr('placeholder', t('translate.localized_translation_name'))
63025 .attr('class', 'localized-value');
63029 .style('margin-top', '0px')
63030 .style('max-height', '0px')
63031 .style('opacity', '0')
63034 .style('margin-top', '10px')
63035 .style('max-height', '240px')
63036 .style('opacity', '1')
63037 .on('end', function() {
63039 .style('max-height', '')
63040 .style('overflow', 'visible');
63044 var entry = selection$$1.selectAll('.entry');
63046 utilGetSetValue(entry.select('.localized-lang'), function(d) {
63047 var lang = lodash.find(dataWikipedia, function(lang) { return lang[2] === d.lang; });
63048 return lang ? lang[1] : d.lang;
63051 utilGetSetValue(entry.select('.localized-value'),
63052 function(d) { return d.value; });
63056 localized.tags = function(tags) {
63057 // Fetch translations from wikipedia
63058 if (tags.wikipedia && !wikiTitles) {
63060 var wm = tags.wikipedia.match(/([^:]+):(.+)/);
63061 if (wm && wm[0] && wm[1]) {
63062 wikipedia.translations(wm[1], wm[2], function(d) {
63068 utilGetSetValue(input, tags[field.key] || '');
63070 var postfixed = [], k, m;
63072 m = k.match(/^(.*):([a-zA-Z_-]+)$/);
63073 if (m && m[1] === field.key && m[2]) {
63074 postfixed.push({ lang: m[2], value: tags[k] });
63078 localizedInputs.call(render, postfixed.reverse());
63082 localized.focus = function() {
63083 input.node().focus();
63087 localized.entity = function(_) {
63088 if (!arguments.length) return entity;
63093 return utilRebind(localized, dispatch$$1, 'on');
63096 function uiFieldMaxspeed(field, context) {
63097 var dispatch$$1 = dispatch('change'),
63100 unitInput = select(null),
63101 input = select(null),
63104 var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
63105 imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
63108 function maxspeed(selection$$1) {
63109 combobox = d3combobox();
63110 var unitCombobox = d3combobox().data(['km/h', 'mph'].map(comboValues));
63112 input = selection$$1.selectAll('#preset-input-' + field.id)
63115 input = input.enter()
63117 .attr('type', 'text')
63118 .attr('id', 'preset-input-' + field.id)
63119 .attr('placeholder', field.placeholder())
63124 .on('change', change)
63125 .on('blur', change);
63127 var childNodes = context.graph().childNodes(context.entity(entity.id)),
63128 loc = childNodes[~~(childNodes.length/2)].loc;
63130 isImperial = lodash.some(dataImperial.features, function(f) {
63131 return lodash.some(f.geometry.coordinates, function(d) {
63132 return geoPointInPolygon(loc, d);
63136 unitInput = selection$$1.selectAll('input.maxspeed-unit')
63139 unitInput = unitInput.enter()
63141 .attr('type', 'text')
63142 .attr('class', 'maxspeed-unit')
63143 .call(unitCombobox)
63147 .on('blur', changeUnits)
63148 .on('change', changeUnits);
63151 function changeUnits() {
63152 isImperial = utilGetSetValue(unitInput) === 'mph';
63153 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
63160 function setSuggestions() {
63161 combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
63162 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
63166 function comboValues(d) {
63168 value: d.toString(),
63169 title: d.toString()
63174 function change() {
63176 value = utilGetSetValue(input);
63179 tag[field.key] = undefined;
63180 } else if (isNaN(value) || !isImperial) {
63181 tag[field.key] = value;
63183 tag[field.key] = value + ' mph';
63186 dispatch$$1.call('change', this, tag);
63190 maxspeed.tags = function(tags) {
63191 var value = tags[field.key];
63193 if (value && value.indexOf('mph') >= 0) {
63194 value = parseInt(value, 10);
63196 } else if (value) {
63197 isImperial = false;
63201 utilGetSetValue(input, value || '');
63205 maxspeed.focus = function() {
63206 input.node().focus();
63210 maxspeed.entity = function(_) {
63215 return utilRebind(maxspeed, dispatch$$1, 'on');
63218 function uiFieldRadio(field) {
63219 var dispatch$$1 = dispatch('change'),
63220 placeholder = select(null),
63221 labels = select(null),
63222 radios = select(null);
63225 function radio(selection$$1) {
63226 selection$$1.classed('preset-radio', true);
63228 var wrap = selection$$1.selectAll('.preset-input-wrap')
63231 var enter = wrap.enter()
63233 .attr('class', 'preset-input-wrap toggle-list');
63237 .attr('class', 'placeholder');
63243 placeholder = wrap.selectAll('.placeholder');
63245 labels = wrap.selectAll('label')
63246 .data(field.options || field.keys);
63248 enter = labels.enter()
63251 enter.append('input')
63252 .attr('type', 'radio')
63253 .attr('name', field.id)
63254 .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
63255 .attr('checked', false);
63257 enter.append('span')
63258 .text(function(d) { return field.t('options.' + d, { 'default': d }); });
63263 radios = labels.selectAll('input')
63264 .on('change', change);
63268 function change() {
63270 if (field.key) t$$1[field.key] = undefined;
63271 radios.each(function(d) {
63272 var active$$1 = select(this).property('checked');
63274 if (active$$1) t$$1[field.key] = d;
63276 t$$1[d] = active$$1 ? 'yes' : undefined;
63279 dispatch$$1.call('change', this, t$$1);
63283 radio.tags = function(tags) {
63284 function checked(d) {
63286 return tags[field.key] === d;
63288 return !!(tags[d] && tags[d] !== 'no');
63292 labels.classed('active', checked);
63293 radios.property('checked', checked);
63294 var selection$$1 = radios.filter(function() { return this.checked; });
63295 if (selection$$1.empty()) {
63296 placeholder.text(t('inspector.none'));
63298 placeholder.text(selection$$1.attr('value'));
63303 radio.focus = function() {
63304 radios.node().focus();
63308 return utilRebind(radio, dispatch$$1, 'on');
63311 function uiFieldRestrictions(field, context) {
63312 var dispatch$$1 = dispatch('change'),
63313 breathe = behaviorBreathe(context),
63314 hover = behaviorHover(context),
63315 initialized = false,
63320 function restrictions(selection$$1) {
63321 // if form field is hidden or has detached from dom, clean up.
63322 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
63323 selection$$1.call(restrictions.off);
63327 var wrap = selection$$1.selectAll('.preset-input-wrap')
63330 var enter = wrap.enter()
63332 .attr('class', 'preset-input-wrap');
63336 .attr('class', 'restriction-help');
63339 var intersection = osmIntersection(context.graph(), vertexID),
63340 graph = intersection.graph,
63341 vertex = graph.entity(vertexID),
63342 filter = utilFunctor(true),
63343 extent$$1 = geoExtent$$1(),
63344 projection = geoRawMercator();
63346 var d = utilGetDimensions(wrap.merge(enter)),
63347 c = [d[0] / 2, d[1] / 2],
63351 .scale(256 * Math.pow(2, z) / (2 * Math.PI));
63353 var s = projection(vertex.loc);
63356 .translate([c[0] - s[0], c[1] - s[1]])
63357 .clipExtent([[0, 0], d]);
63359 var drawLayers = svgLayers(projection, context).only('osm').dimensions(d),
63360 drawVertices = svgVertices$$1(projection, context),
63361 drawLines = svgLines$$1(projection, context),
63362 drawTurns = svgTurns(projection, context);
63370 var surface = wrap.selectAll('.surface');
63372 if (!enter.empty()) {
63373 initialized = true;
63380 .call(utilSetDimensions, d)
63381 .call(drawVertices, graph, [vertex], filter, extent$$1, z)
63382 .call(drawLines, graph, intersection.ways, filter)
63383 .call(drawTurns, graph, intersection.turns(fromNodeID));
63386 .on('click.restrictions', click)
63387 .on('mouseover.restrictions', mouseover)
63388 .on('mouseout.restrictions', mouseout);
63391 .selectAll('.selected')
63392 .classed('selected', false);
63396 .selectAll('.' + intersection.highways[fromNodeID].id)
63397 .classed('selected', true);
63403 .on('change.restrictions', render);
63406 .on('resize.restrictions', function() {
63407 utilSetDimensions(wrap, null);
63417 var datum = event.target.__data__;
63418 if (datum instanceof osmEntity$$1) {
63419 fromNodeID = intersection.adjacentNodeId(datum.id);
63421 } else if (datum instanceof osmTurn) {
63422 if (datum.restriction) {
63424 actionUnrestrictTurn(datum, projection),
63425 t('operations.restriction.annotation.delete')
63429 actionRestrictTurn(datum, projection),
63430 t('operations.restriction.annotation.create')
63437 function mouseover() {
63438 var datum = event.target.__data__;
63439 if (datum instanceof osmTurn) {
63440 var graph = context.graph(),
63441 presets = context.presets(),
63444 if (datum.restriction) {
63445 preset = presets.match(graph.entity(datum.restriction), graph);
63447 preset = presets.item('type/restriction/' +
63448 osmInferRestriction(
63458 wrap.selectAll('.restriction-help')
63459 .text(t('operations.restriction.help.' +
63460 (datum.restriction ? 'toggle_off' : 'toggle_on'),
63461 { restriction: preset.name() })
63467 function mouseout() {
63468 wrap.selectAll('.restriction-help')
63469 .text(t('operations.restriction.help.' +
63470 (fromNodeID ? 'toggle' : 'select'))
63475 function render() {
63476 if (context.hasEntity(vertexID)) {
63477 restrictions(selection$$1);
63483 restrictions.entity = function(_) {
63484 if (!vertexID || vertexID !== _.id) {
63491 restrictions.tags = function() {};
63492 restrictions.focus = function() {};
63495 restrictions.off = function(selection$$1) {
63496 if (!initialized) return;
63498 selection$$1.selectAll('.surface')
63501 .on('click.restrictions', null)
63502 .on('mouseover.restrictions', null)
63503 .on('mouseout.restrictions', null);
63506 .on('change.restrictions', null);
63509 .on('resize.restrictions', null);
63513 return utilRebind(restrictions, dispatch$$1, 'on');
63516 function uiFieldTextarea(field) {
63517 var dispatch$$1 = dispatch('change'),
63518 input = select(null);
63521 function textarea(selection$$1) {
63522 input = selection$$1.selectAll('textarea')
63525 input = input.enter()
63526 .append('textarea')
63527 .attr('id', 'preset-input-' + field.id)
63528 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
63529 .attr('maxlength', 255)
63530 .on('input', change(true))
63531 .on('blur', change())
63532 .on('change', change())
63537 function change(onInput) {
63538 return function() {
63540 t$$1[field.key] = utilGetSetValue(input) || undefined;
63541 dispatch$$1.call('change', this, t$$1, onInput);
63546 textarea.tags = function(tags) {
63547 utilGetSetValue(input, tags[field.key] || '');
63551 textarea.focus = function() {
63552 input.node().focus();
63556 return utilRebind(textarea, dispatch$$1, 'on');
63559 function uiFieldWikipedia(field, context) {
63560 var dispatch$$1 = dispatch('change'),
63561 wikipedia = services.wikipedia,
63562 wikidata = services.wikidata,
63563 link = select(null),
63564 lang = select(null),
63565 title = select(null),
63569 function wiki(selection$$1) {
63570 var langcombo = d3combobox()
63571 .fetcher(function(value, cb) {
63572 var v = value.toLowerCase();
63574 cb(dataWikipedia.filter(function(d) {
63575 return d[0].toLowerCase().indexOf(v) >= 0 ||
63576 d[1].toLowerCase().indexOf(v) >= 0 ||
63577 d[2].toLowerCase().indexOf(v) >= 0;
63578 }).map(function(d) {
63579 return { value: d[1] };
63583 var titlecombo = d3combobox()
63584 .fetcher(function(value, cb) {
63586 value = context.entity(entity.id).tags.name || '';
63589 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
63590 searchfn(language()[2], value, function(query, data$$1) {
63591 cb(data$$1.map(function(d) {
63592 return { value: d };
63598 lang = selection$$1.selectAll('input.wiki-lang')
63601 lang = lang.enter()
63603 .attr('type', 'text')
63604 .attr('class', 'wiki-lang')
63605 .attr('placeholder', t('translate.localized_translation_language'))
63608 utilGetSetValue(lang, language()[1]);
63612 .on('blur', changeLang)
63613 .on('change', changeLang);
63616 title = selection$$1.selectAll('input.wiki-title')
63619 title = title.enter()
63621 .attr('type', 'text')
63622 .attr('class', 'wiki-title')
63623 .attr('id', 'preset-input-' + field.id)
63629 .on('change', change);
63632 link = selection$$1.selectAll('a.wiki-link')
63635 link = link.enter()
63637 .attr('class', 'wiki-link button-input-action minor')
63638 .attr('tabindex', -1)
63639 .attr('target', '_blank')
63640 .call(svgIcon('#icon-out-link', 'inline'))
63645 function language() {
63646 var value = utilGetSetValue(lang).toLowerCase();
63647 var locale = utilDetect().locale.toLowerCase();
63648 var localeLanguage;
63649 return lodash.find(dataWikipedia, function(d) {
63650 if (d[2] === locale) localeLanguage = d;
63651 return d[0].toLowerCase() === value ||
63652 d[1].toLowerCase() === value ||
63654 }) || localeLanguage || ['English', 'English', 'en'];
63658 function changeLang() {
63659 utilGetSetValue(lang, language()[1]);
63669 function change(skipWikidata) {
63670 var value = utilGetSetValue(title),
63671 m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
63672 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
63677 // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
63678 value = decodeURIComponent(m[2]).replace(/_/g, ' ');
63681 // Best-effort `anchordecode:` implementation
63682 anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
63684 anchor = decodeURIComponent(m[3]);
63686 value += '#' + anchor.replace(/_/g, ' ');
63688 value = value.slice(0, 1).toUpperCase() + value.slice(1);
63689 utilGetSetValue(lang, l[1]);
63690 utilGetSetValue(title, value);
63693 syncTags.wikipedia = value ? language()[2] + ':' + value : undefined;
63694 if (!skipWikidata) {
63695 syncTags.wikidata = undefined;
63698 dispatch$$1.call('change', this, syncTags);
63701 if (skipWikidata || !value || !language()[2]) return;
63703 // attempt asynchronous update of wikidata tag..
63704 var initEntityId = entity.id,
63705 initWikipedia = context.entity(initEntityId).tags.wikipedia;
63707 wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
63708 if (!data$$1 || !Object.keys(data$$1).length) return;
63709 var qids = Object.keys(data$$1);
63711 // 1. most recent change was a tag change
63712 var annotation = t('operations.change_tags.annotation'),
63713 currAnnotation = context.history().undoAnnotation();
63714 if (currAnnotation !== annotation) return;
63716 // 2. same entity exists and still selected
63717 var selectedIds = context.selectedIDs(),
63718 currEntityId = selectedIds.length > 0 && selectedIds[0];
63719 if (currEntityId !== initEntityId) return;
63721 // 3. wikipedia value has not changed
63722 var currTags = lodash.clone(context.entity(currEntityId).tags);
63723 if (initWikipedia !== currTags.wikipedia) return;
63725 // ok to coalesce the update of wikidata tag into the previous tag change
63726 currTags.wikidata = qids && lodash.find(qids, function(id) {
63727 return id.match(/^Q\d+$/);
63730 context.overwrite(actionChangeTags(currEntityId, currTags), annotation);
63731 dispatch$$1.call('change', this, currTags);
63736 wiki.tags = function(tags) {
63737 var value = tags[field.key] || '',
63738 m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
63739 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
63740 anchor = m && m[3];
63742 // value in correct format
63744 utilGetSetValue(lang, l[1]);
63745 utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
63748 // Best-effort `anchorencode:` implementation
63749 anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
63751 anchor = anchor.replace(/ /g, '_');
63754 link.attr('href', 'https://' + m[1] + '.wikipedia.org/wiki/' +
63755 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : ''));
63757 // unrecognized value format
63759 utilGetSetValue(title, value);
63760 if (value && value !== '') {
63761 utilGetSetValue(lang, '');
63763 link.attr('href', 'https://en.wikipedia.org/wiki/Special:Search?search=' + value);
63768 wiki.entity = function(_) {
63769 if (!arguments.length) return entity;
63775 wiki.focus = function() {
63776 title.node().focus();
63780 return utilRebind(wiki, dispatch$$1, 'on');
63784 access: uiFieldAccess,
63785 address: uiFieldAddress,
63786 check: uiFieldCheck,
63787 defaultcheck: uiFieldCheck,
63788 combo: uiFieldCombo,
63789 typeCombo: uiFieldCombo,
63790 multiCombo: uiFieldCombo,
63791 networkCombo: uiFieldCombo,
63792 cycleway: uiFieldCycleway,
63795 number: uiFieldText,
63796 email: uiFieldText,
63798 localized: uiFieldLocalized,
63799 lanes: uiFieldLanes,
63800 maxspeed: uiFieldMaxspeed,
63801 radio: uiFieldRadio,
63802 restrictions: uiFieldRestrictions,
63803 textarea: uiFieldTextarea,
63804 wikipedia: uiFieldWikipedia
63807 function uiPreset(context) {
63808 var dispatch$$1 = dispatch('change'),
63816 // Field Constructor
63817 function UIField(field, entity, show) {
63818 field = lodash.clone(field);
63820 field.input = uiFields[field.type](field, context)
63821 .on('change', function(t$$1, onInput) {
63822 dispatch$$1.call('change', field, t$$1, onInput);
63825 if (field.input.entity) field.input.entity(entity);
63827 field.keys = field.keys || [field.key];
63831 field.shown = function() {
63832 return field.id === 'name' || field.show || lodash.some(field.keys, function(key) { return !!tags[key]; });
63835 field.modified = function() {
63836 var original = context.graph().base().entities[entity.id];
63837 return lodash.some(field.keys, function(key) {
63838 return original ? tags[key] !== original.tags[key] : tags[key];
63842 field.revert = function() {
63843 var original = context.graph().base().entities[entity.id],
63845 field.keys.forEach(function(key) {
63846 t$$1[key] = original ? original.tags[key] : undefined;
63851 field.present = function() {
63852 return lodash.some(field.keys, function(key) {
63857 field.remove = function() {
63859 field.keys.forEach(function(key) {
63860 t$$1[key] = undefined;
63869 function fieldKey(field) {
63874 function presets(selection$$1) {
63875 selection$$1.call(uiDisclosure()
63876 .title(t('inspector.all_fields'))
63877 .expanded(context.storage('preset_fields.expanded') !== 'false')
63878 .on('toggled', toggled)
63882 function toggled(expanded) {
63883 context.storage('preset_fields.expanded', expanded);
63888 function content(selection$$1) {
63890 var entity = context.entity(id),
63891 geometry = context.geometry(id),
63892 presets = context.presets();
63896 if (presets.field('name')) {
63897 fieldsArr.push(UIField(presets.field('name'), entity));
63900 preset.fields.forEach(function(field) {
63901 if (field.matchGeometry(geometry)) {
63902 fieldsArr.push(UIField(field, entity, true));
63906 if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
63907 fieldsArr.push(UIField(presets.field('restrictions'), entity, true));
63910 presets.universal().forEach(function(field) {
63911 if (preset.fields.indexOf(field) < 0) {
63912 fieldsArr.push(UIField(field, entity));
63917 var shown = fieldsArr.filter(function(field) { return field.shown(); }),
63918 notShown = fieldsArr.filter(function(field) { return !field.shown(); });
63921 var form = selection$$1.selectAll('.preset-form')
63924 form = form.enter()
63926 .attr('class', 'preset-form inspector-inner fillL3')
63930 var fields = form.selectAll('.form-field')
63931 .data(shown, fieldKey);
63937 var enter = fields.enter()
63939 .attr('class', function(field) {
63940 return 'form-field form-field-' + field.id;
63945 .attr('class', 'form-label')
63946 .attr('for', function(field) { return 'preset-input-' + field.id; })
63947 .text(function(field) { return field.label(); });
63951 .attr('class', 'form-label-button-wrap');
63953 wrap.append('button')
63954 .attr('class', 'remove-icon')
63955 .attr('tabindex', -1)
63956 .call(svgIcon('#operation-delete'));
63958 wrap.append('button')
63959 .attr('class', 'modified-icon')
63960 .attr('tabindex', -1)
63962 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
63970 fields.selectAll('.form-label-button-wrap .remove-icon')
63971 .on('click', remove);
63973 fields.selectAll('.modified-icon')
63974 .on('click', revert);
63978 .classed('modified', function(field) { return field.modified(); })
63979 .classed('present', function(field) { return field.present(); })
63980 .each(function(field) {
63981 var reference = uiTagReference(field.reference || { key: field.key }, context);
63983 if (state === 'hover') {
63984 reference.showing(false);
63989 .selectAll('input')
63990 .on('keydown', function() {
63991 // if user presses enter, and combobox is not active, accept edits..
63992 if (event.keyCode === 13 && select('.combobox').empty()) {
63993 context.enter(modeBrowse(context));
63996 .call(reference.body)
63997 .select('.form-label-button-wrap')
63998 .call(reference.button);
64000 field.input.tags(tags);
64003 notShown = notShown.map(function(field) {
64005 title: field.label(),
64006 value: field.label(),
64012 var more = selection$$1.selectAll('.more-fields')
64013 .data((notShown.length > 0) ? [0] : []);
64018 more = more.enter()
64020 .attr('class', 'more-fields')
64022 .text(t('inspector.add_fields'))
64026 var input = more.selectAll('.value')
64032 input = input.enter()
64034 .attr('class', 'value')
64035 .attr('type', 'text')
64039 .call(utilGetSetValue, '')
64040 .attr('placeholder', function() {
64041 var placeholder = [];
64042 for (var field in notShown) {
64043 placeholder.push(notShown[field].title);
64045 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
64047 .call(d3combobox().data(notShown)
64049 .on('accept', show));
64052 function show(field) {
64053 field = field.field;
64055 content(selection$$1);
64056 field.input.focus();
64060 function revert(field) {
64061 event.stopPropagation();
64062 event.preventDefault();
64063 dispatch$$1.call('change', field, field.revert());
64067 function remove(field) {
64068 event.stopPropagation();
64069 event.preventDefault();
64070 dispatch$$1.call('change', field, field.remove());
64075 presets.preset = function(_) {
64076 if (!arguments.length) return preset;
64077 if (preset && preset.id === _.id) return presets;
64084 presets.state = function(_) {
64085 if (!arguments.length) return state;
64091 presets.tags = function(_) {
64092 if (!arguments.length) return tags;
64094 // Don't reset fieldsArr here.
64099 presets.entityID = function(_) {
64100 if (!arguments.length) return id;
64101 if (id === _) return presets;
64108 return utilRebind(presets, dispatch$$1, 'on');
64111 function uiEntityEditor(context) {
64112 var dispatch$$1 = dispatch('choose'),
64114 coalesceChanges = false,
64121 var presetEditor = uiPreset(context)
64122 .on('change', changeTags);
64123 var rawTagEditor = uiRawTagEditor(context)
64124 .on('change', changeTags);
64127 function entityEditor(selection$$1) {
64128 var entity = context.entity(id),
64129 tags = lodash.clone(entity.tags);
64132 var header = selection$$1.selectAll('.header')
64136 var enter = header.enter()
64138 .attr('class', 'header fillL cf');
64142 .attr('class', 'fl preset-reset preset-choose')
64143 .call(svgIcon((textDirection === 'rtl') ? '#icon-forward' : '#icon-backward'));
64147 .attr('class', 'fr preset-close')
64148 .on('click', function() { context.enter(modeBrowse(context)); })
64149 .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
64153 .text(t('inspector.edit'));
64159 header.selectAll('.preset-reset')
64160 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
64164 var body = selection$$1.selectAll('.inspector-body')
64168 enter = body.enter()
64170 .attr('class', 'inspector-body');
64174 .attr('class', 'preset-list-item inspector-inner')
64176 .attr('class', 'preset-list-button-wrap')
64178 .attr('class', 'preset-list-button preset-reset')
64179 .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
64181 .attr('class', 'label');
64185 .attr('class', 'inspector-border inspector-preset');
64189 .attr('class', 'inspector-border raw-tag-editor inspector-inner');
64193 .attr('class', 'inspector-border raw-member-editor inspector-inner');
64197 .attr('class', 'raw-membership-editor inspector-inner');
64203 body.selectAll('.preset-list-button-wrap')
64204 .call(reference.button);
64206 body.selectAll('.preset-list-item')
64207 .call(reference.body);
64209 body.selectAll('.preset-reset')
64210 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
64212 body.select('.preset-list-item button')
64213 .call(uiPresetIcon()
64214 .geometry(context.geometry(id))
64215 .preset(activePreset));
64217 body.select('.preset-list-item .label')
64218 .text(activePreset.name());
64220 body.select('.inspector-preset')
64222 .preset(activePreset)
64227 body.select('.raw-tag-editor')
64229 .preset(activePreset)
64234 if (entity.type === 'relation') {
64235 body.select('.raw-member-editor')
64236 .style('display', 'block')
64237 .call(uiRawMemberEditor(context)
64240 body.select('.raw-member-editor')
64241 .style('display', 'none');
64244 body.select('.raw-membership-editor')
64245 .call(uiRawMembershipEditor(context)
64250 .on('change.entity-editor', historyChanged);
64253 function historyChanged() {
64254 if (state === 'hide') return;
64256 var entity = context.hasEntity(id),
64257 graph = context.graph();
64258 if (!entity) return;
64260 entityEditor.preset(context.presets().match(entity, graph));
64261 entityEditor.modified(base !== graph);
64262 entityEditor(selection$$1);
64267 function clean(o) {
64269 function cleanVal(k, v) {
64270 function keepSpaces(k) {
64271 var whitelist = ['opening_hours', 'service_times', 'collection_times',
64272 'operating_times', 'smoking_hours', 'happy_hours'];
64273 return lodash.some(whitelist, function(s) { return k.indexOf(s) !== -1; });
64276 var blacklist = ['description', 'note', 'fixme'];
64277 if (lodash.some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
64279 var cleaned = v.split(';')
64280 .map(function(s) { return s.trim(); })
64281 .join(keepSpaces(k) ? '; ' : ';');
64283 // The code below is not intended to validate websites and emails.
64284 // It is only intended to prevent obvious copy-paste errors. (#2323)
64286 // clean website- and email-like tags
64287 if (k.indexOf('website') !== -1 ||
64288 k.indexOf('email') !== -1 ||
64289 cleaned.indexOf('http') === 0) {
64291 .replace(/[\u200B-\u200F\uFEFF]/g, ''); // strip LRM and other zero width chars
64298 var out = {}, k, v;
64300 if (k && (v = o[k]) !== undefined) {
64301 out[k] = cleanVal(k, v);
64308 // Tag changes that fire on input can all get coalesced into a single
64309 // history operation when the user leaves the field. #2342
64310 function changeTags(changed, onInput) {
64311 var entity = context.entity(id),
64312 annotation = t('operations.change_tags.annotation'),
64313 tags = lodash.clone(entity.tags);
64315 lodash.forEach(changed, function(v, k) {
64316 if (v !== undefined || tags.hasOwnProperty(k)) {
64322 tags = clean(tags);
64325 if (!lodash.isEqual(entity.tags, tags)) {
64326 if (coalesceChanges) {
64327 context.overwrite(actionChangeTags(id, tags), annotation);
64329 context.perform(actionChangeTags(id, tags), annotation);
64330 coalesceChanges = !!onInput;
64336 entityEditor.modified = function(_) {
64337 if (!arguments.length) return modified;
64339 selectAll('button.preset-close use')
64340 .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
64344 entityEditor.state = function(_) {
64345 if (!arguments.length) return state;
64347 return entityEditor;
64351 entityEditor.entityID = function(_) {
64352 if (!arguments.length) return id;
64354 base = context.graph();
64355 entityEditor.preset(context.presets().match(context.entity(id), base));
64356 entityEditor.modified(false);
64357 coalesceChanges = false;
64358 return entityEditor;
64362 entityEditor.preset = function(_) {
64363 if (!arguments.length) return activePreset;
64364 if (_ !== activePreset) {
64366 reference = uiTagReference(activePreset.reference(context.geometry(id)), context)
64369 return entityEditor;
64373 return utilRebind(entityEditor, dispatch$$1, 'on');
64376 function uiPresetList(context) {
64377 var dispatch$$1 = dispatch('choose'),
64383 function presetList(selection$$1) {
64384 var entity = context.entity(id),
64385 geometry = context.geometry(id);
64387 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
64388 if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
64389 geometry = 'point';
64392 var presets = context.presets().matchGeometry(geometry);
64394 selection$$1.html('');
64396 var messagewrap = selection$$1
64398 .attr('class', 'header fillL cf');
64400 var message = messagewrap
64402 .text(t('inspector.choose'));
64404 if (context.entity(id).isUsed(context.graph())) {
64407 .attr('class', 'preset-choose')
64408 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
64409 .call(svgIcon((textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'));
64413 .attr('class', 'close')
64414 .on('click', function() {
64415 context.enter(modeBrowse(context));
64417 .call(svgIcon('#icon-close'));
64420 function keydown() {
64421 // hack to let delete shortcut work when search is autofocused
64422 if (search.property('value').length === 0 &&
64423 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
64424 event.keyCode === d3keybinding.keyCodes['⌦'])) {
64425 event.preventDefault();
64426 event.stopPropagation();
64427 operationDelete([id], context)();
64428 } else if (search.property('value').length === 0 &&
64429 (event.ctrlKey || event.metaKey) &&
64430 event.keyCode === d3keybinding.keyCodes.z) {
64431 event.preventDefault();
64432 event.stopPropagation();
64434 } else if (!event.ctrlKey && !event.metaKey) {
64435 select(this).on('keydown', null);
64439 function keypress() {
64441 var value = search.property('value');
64442 if (event.keyCode === 13 && value.length) {
64443 list.selectAll('.preset-list-item:first-child').datum().choose();
64447 function inputevent() {
64448 var value = search.property('value');
64449 list.classed('filtered', value.length);
64450 if (value.length) {
64451 var results = presets.search(value, geometry);
64452 message.text(t('inspector.results', {
64453 n: results.collection.length,
64456 list.call(drawList, results);
64458 list.call(drawList, context.presets().defaults(geometry, 36));
64459 message.text(t('inspector.choose'));
64463 var searchWrap = selection$$1
64465 .attr('class', 'search-header');
64467 var search = searchWrap
64469 .attr('class', 'preset-search-input')
64470 .attr('placeholder', t('inspector.search'))
64471 .attr('type', 'search')
64472 .on('keydown', keydown)
64473 .on('keypress', keypress)
64474 .on('input', inputevent);
64477 .call(svgIcon('#icon-search', 'pre-text'));
64480 search.node().focus();
64483 var listWrap = selection$$1
64485 .attr('class', 'inspector-body');
64487 var list = listWrap
64489 .attr('class', 'preset-list fillL cf')
64490 .call(drawList, context.presets().defaults(geometry, 36));
64494 function drawList(list, presets) {
64495 var collection = presets.collection.map(function(preset) {
64496 return preset.members ? CategoryItem(preset) : PresetItem(preset);
64499 var items = list.selectAll('.preset-list-item')
64500 .data(collection, function(d) { return d.preset.id; });
64509 .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
64510 .classed('current', function(item) { return item.preset === currentPreset; })
64511 .each(function(item) { select(this).call(item); })
64512 .style('opacity', 0)
64514 .style('opacity', 1);
64518 function CategoryItem(preset) {
64519 var box, sublist, shown = false;
64521 function item(selection$$1) {
64522 var wrap = selection$$1.append('div')
64523 .attr('class', 'preset-list-button-wrap category col12');
64527 .attr('class', 'preset-list-button')
64528 .classed('expanded', false)
64529 .call(uiPresetIcon()
64530 .geometry(context.geometry(id))
64532 .on('click', function() {
64533 var isExpanded = select(this).classed('expanded');
64534 var iconName = isExpanded ?
64535 (textDirection === 'rtl' ? '#icon-backward' : '#icon-forward') : '#icon-down';
64537 .classed('expanded', !isExpanded);
64538 select(this).selectAll('div.label svg.icon use')
64539 .attr('href', iconName);
64545 .attr('class', 'label');
64548 .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'))
64550 .html(function() { return preset.name() + '…'; });
64552 box = selection$$1.append('div')
64553 .attr('class', 'subgrid col12')
64554 .style('max-height', '0px')
64555 .style('opacity', 0);
64558 .attr('class', 'arrow');
64560 sublist = box.append('div')
64561 .attr('class', 'preset-list fillL3 cf fl');
64565 item.choose = function() {
64566 if (!box || !sublist) return;
64572 .style('opacity', '0')
64573 .style('max-height', '0px')
64574 .style('padding-bottom', '0px');
64577 sublist.call(drawList, preset.members);
64580 .style('opacity', '1')
64581 .style('max-height', 200 + preset.members.collection.length * 80 + 'px')
64582 .style('padding-bottom', '20px');
64586 item.preset = preset;
64592 function PresetItem(preset) {
64593 function item(selection$$1) {
64594 var wrap = selection$$1.append('div')
64595 .attr('class', 'preset-list-button-wrap col12');
64597 wrap.append('button')
64598 .attr('class', 'preset-list-button')
64599 .call(uiPresetIcon()
64600 .geometry(context.geometry(id))
64602 .on('click', item.choose)
64604 .attr('class', 'label')
64605 .text(preset.name());
64607 wrap.call(item.reference.button);
64608 selection$$1.call(item.reference.body);
64611 item.choose = function() {
64612 context.presets().choose(preset);
64615 actionChangePreset(id, currentPreset, preset),
64616 t('operations.change_tags.annotation')
64619 dispatch$$1.call('choose', this, preset);
64622 item.help = function() {
64623 event.stopPropagation();
64624 item.reference.toggle();
64627 item.preset = preset;
64628 item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
64634 presetList.autofocus = function(_) {
64635 if (!arguments.length) return autofocus;
64641 presetList.entityID = function(_) {
64642 if (!arguments.length) return id;
64644 presetList.preset(context.presets().match(context.entity(id), context.graph()));
64649 presetList.preset = function(_) {
64650 if (!arguments.length) return currentPreset;
64656 return utilRebind(presetList, dispatch$$1, 'on');
64659 function uiViewOnOSM(context) {
64662 function viewOnOSM(selection) {
64663 var entity = context.entity(id);
64665 selection.style('display', entity.isNew() ? 'none' : null);
64667 var link = selection.selectAll('.view-on-osm')
64670 var enter = link.enter()
64672 .attr('class', 'view-on-osm')
64673 .attr('target', '_blank')
64674 .call(svgIcon('#icon-out-link', 'inline'));
64678 .text(t('inspector.view_on_osm'));
64682 .attr('href', context.connection().entityURL(entity));
64686 viewOnOSM.entityID = function(_) {
64687 if (!arguments.length) return id;
64695 function uiInspector(context) {
64696 var presetList = uiPresetList(context),
64697 entityEditor = uiEntityEditor(context),
64700 newFeature = false;
64703 function inspector(selection$$1) {
64705 .entityID(entityID)
64706 .autofocus(newFeature)
64707 .on('choose', setPreset);
64711 .entityID(entityID)
64712 .on('choose', showList);
64714 var wrap = selection$$1.selectAll('.panewrap')
64717 var enter = wrap.enter()
64719 .attr('class', 'panewrap');
64723 .attr('class', 'preset-list-pane pane');
64727 .attr('class', 'entity-editor-pane pane');
64729 wrap = wrap.merge(enter);
64730 var presetPane = wrap.selectAll('.preset-list-pane');
64731 var editorPane = wrap.selectAll('.entity-editor-pane');
64733 var graph = context.graph(),
64734 entity = context.entity(entityID),
64735 showEditor = state === 'hover' ||
64736 entity.isUsed(graph) ||
64737 entity.isHighwayIntersection(graph);
64740 wrap.style('right', '0%');
64741 editorPane.call(entityEditor);
64743 wrap.style('right', '-100%');
64744 presetPane.call(presetList);
64747 var footer = selection$$1.selectAll('.footer')
64750 footer = footer.enter()
64752 .attr('class', 'footer')
64756 .call(uiViewOnOSM(context).entityID(entityID));
64759 function showList(preset) {
64761 .styleTween('right', function() { return value$1('0%', '-100%'); });
64764 .call(presetList.preset(preset).autofocus(true));
64768 function setPreset(preset) {
64770 .styleTween('right', function() { return value$1('-100%', '0%'); });
64773 .call(entityEditor.preset(preset));
64778 inspector.state = function(_) {
64779 if (!arguments.length) return state;
64781 entityEditor.state(state);
64786 inspector.entityID = function(_) {
64787 if (!arguments.length) return entityID;
64793 inspector.newFeature = function(_) {
64794 if (!arguments.length) return newFeature;
64803 function uiNotice(context) {
64805 return function(selection) {
64806 var div = selection
64808 .attr('class', 'notice');
64812 .attr('class', 'zoom-to notice')
64813 .on('click', function() { context.map().zoom(context.minEditableZoom()); });
64816 .call(svgIcon('#icon-plus', 'pre-text'))
64818 .attr('class', 'label')
64819 .text(t('zoom_in_edit'));
64822 function disableTooHigh() {
64823 div.style('display', context.editable() ? 'none' : 'block');
64827 .on('move.notice', lodash.debounce(disableTooHigh, 500));
64833 function uiSidebar(context) {
64834 var inspector = uiInspector(context),
64838 function sidebar(selection) {
64839 var featureListWrap = selection
64841 .attr('class', 'feature-list-pane')
64842 .call(uiFeatureList(context));
64845 .call(uiNotice(context));
64847 var inspectorWrap = selection
64849 .attr('class', 'inspector-hidden inspector-wrap fr');
64852 function hover(id) {
64853 if (!current && context.hasEntity(id)) {
64855 .classed('inspector-hidden', true);
64858 .classed('inspector-hidden', false)
64859 .classed('inspector-hover', true);
64861 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
64870 } else if (!current) {
64872 .classed('inspector-hidden', false);
64874 .classed('inspector-hidden', true);
64881 sidebar.hover = lodash.throttle(hover, 200);
64884 sidebar.select = function(id, newFeature) {
64885 if (!current && id) {
64887 .classed('inspector-hidden', true);
64890 .classed('inspector-hidden', false)
64891 .classed('inspector-hover', false);
64893 if (inspector.entityID() !== id || inspector.state() !== 'select') {
64897 .newFeature(newFeature);
64903 } else if (!current) {
64905 .classed('inspector-hidden', false);
64907 .classed('inspector-hidden', true);
64914 sidebar.show = function(component) {
64916 .classed('inspector-hidden', true);
64918 .classed('inspector-hidden', true);
64920 if (current) current.remove();
64921 current = selection
64923 .attr('class', 'sidebar-component')
64928 sidebar.hide = function() {
64930 .classed('inspector-hidden', false);
64932 .classed('inspector-hidden', true);
64934 if (current) current.remove();
64940 sidebar.hover = function() {};
64941 sidebar.hover.cancel = function() {};
64942 sidebar.select = function() {};
64943 sidebar.show = function() {};
64944 sidebar.hide = function() {};
64949 function uiSpinner(context) {
64950 var connection = context.connection();
64953 return function(selection) {
64954 var img = selection
64956 .attr('src', context.imagePath('loader-black.gif'))
64957 .style('opacity', 0);
64960 .on('loading.spinner', function() {
64962 .style('opacity', 1);
64966 .on('loaded.spinner', function() {
64968 .style('opacity', 0);
64973 function uiSplash(context) {
64975 return function(selection$$1) {
64976 if (context.storage('sawSplash'))
64979 context.storage('sawSplash', true);
64981 var modalSelection = uiModal(selection$$1);
64983 modalSelection.select('.modal')
64984 .attr('class', 'modal-splash modal col6');
64986 var introModal = modalSelection.select('.content')
64988 .attr('class', 'fillL');
64992 .attr('class','modal-section cf')
64993 .append('h3').text(t('splash.welcome'));
64997 .attr('class','modal-section')
64999 .html(t('splash.text', {
65000 version: context.version,
65001 website: '<a href="http://ideditor.com/">ideditor.com</a>',
65002 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
65005 var buttons = introModal
65007 .attr('class', 'modal-actions cf');
65011 .attr('class', 'col6 walkthrough')
65012 .text(t('splash.walkthrough'))
65013 .on('click', function() {
65014 select(document.body).call(uiIntro(context));
65015 modalSelection.close();
65020 .attr('class', 'col6 start')
65021 .text(t('splash.start'))
65022 .on('click', modalSelection.close);
65024 modalSelection.select('button.close')
65025 .attr('class','hide');
65030 function uiStatus(context) {
65031 var connection = context.connection();
65033 return function(selection$$1) {
65035 function update() {
65036 connection.status(function(err, apiStatus) {
65037 selection$$1.html('');
65040 if (apiStatus === 'rateLimited') {
65042 .text(t('status.rateLimit'))
65044 .attr('class', 'api-status-login')
65045 .attr('target', '_blank')
65046 .call(svgIcon('#icon-out-link', 'inline'))
65049 .on('click.login', function() {
65050 event.preventDefault();
65051 connection.authenticate();
65054 // TODO: nice messages for different error types
65055 selection$$1.text(t('status.error'));
65058 } else if (apiStatus === 'readonly') {
65059 selection$$1.text(t('status.readonly'));
65060 } else if (apiStatus === 'offline') {
65061 selection$$1.text(t('status.offline'));
65064 selection$$1.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
65069 .on('change', function() { update(selection$$1); });
65071 window.setInterval(update, 90000);
65072 update(selection$$1);
65076 function uiUndoRedo(context) {
65080 action: function() { if (!(context.inIntro() || saving())) context.undo(); },
65081 annotation: function() { return context.history().undoAnnotation(); }
65085 action: function() {if (!(context.inIntro() || saving())) context.redo(); },
65086 annotation: function() { return context.history().redoAnnotation(); }
65090 function saving() {
65091 return context.mode().id === 'save';
65095 return function(selection$$1) {
65096 var tooltipBehavior = tooltip()
65097 .placement('bottom')
65099 .title(function (d) {
65100 return uiTooltipHtml(d.annotation() ?
65101 t(d.id + '.tooltip', {action: d.annotation()}) :
65102 t(d.id + '.nothing'), d.cmd);
65105 var buttons = selection$$1.selectAll('button')
65109 .attr('class', 'col6 disabled')
65110 .on('click', function(d) { return d.action(); })
65111 .call(tooltipBehavior);
65113 buttons.each(function(d) {
65114 var iconName = d.id;
65115 if (textDirection === 'rtl') {
65116 if (iconName === 'undo') {
65118 } else if (iconName === 'redo') {
65123 .call(svgIcon('#icon-' + iconName));
65126 var keybinding = d3keybinding('undo')
65127 .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
65128 .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
65134 .on('change.undo_redo', update);
65137 .on('enter.undo_redo', update);
65139 function update() {
65141 .property('disabled', saving())
65142 .classed('disabled', function(d) { return !d.annotation(); })
65144 var selection$$1 = select(this);
65145 if (selection$$1.property('tooltipVisible')) {
65146 selection$$1.call(tooltipBehavior.show);
65153 function uiZoom(context) {
65157 title: t('zoom.in'),
65158 action: context.zoomIn,
65163 title: t('zoom.out'),
65164 action: context.zoomOut,
65169 function zoomIn() {
65170 event.preventDefault();
65171 if (!context.inIntro()) context.zoomIn();
65175 function zoomOut() {
65176 event.preventDefault();
65177 if (!context.inIntro()) context.zoomOut();
65181 function zoomInFurther() {
65182 event.preventDefault();
65183 if (!context.inIntro()) context.zoomInFurther();
65187 function zoomOutFurther() {
65188 event.preventDefault();
65189 if (!context.inIntro()) context.zoomOutFurther();
65193 return function(selection$$1) {
65194 var button = selection$$1.selectAll('button')
65198 .attr('tabindex', -1)
65199 .attr('class', function(d) { return d.id; })
65200 .on('click.editor', function(d) { d.action(); })
65202 .placement((textDirection === 'rtl') ? 'right' : 'left')
65204 .title(function(d) {
65205 return uiTooltipHtml(d.title, d.key);
65209 button.each(function(d) {
65211 .call(svgIcon('#icon-' + d.icon, 'light'));
65214 var keybinding = d3keybinding('zoom');
65216 lodash.each(['=','ffequals','plus','ffplus'], function(key) {
65217 keybinding.on([key, '⇧' + key], zoomIn);
65218 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomInFurther);
65220 lodash.each(['-','ffminus','dash'], function(key) {
65221 keybinding.on([key, '⇧' + key], zoomOut);
65222 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomOutFurther);
65230 function uiInit(context) {
65231 var uiInitCounter = 0;
65234 function render(container) {
65236 .attr('dir', textDirection);
65238 var map$$1 = context.map();
65240 var hash = behaviorHash(context);
65243 if (!hash.hadHash) {
65244 map$$1.centerZoom([0, 0], 2);
65249 .attr('id', 'defs')
65250 .call(svgDefs(context));
65254 .attr('id', 'sidebar')
65255 .attr('class', 'col4')
65258 var content = container
65260 .attr('id', 'content')
65261 .attr('class', 'active');
65266 .attr('class', 'fillD');
65271 .attr('dir', 'ltr')
65275 .call(uiMapInMap(context));
65279 .call(uiInfo(context));
65283 .attr('class', 'spacer col4');
65285 var limiter = bar.append('div')
65286 .attr('class', 'limiter');
65290 .attr('class', 'button-wrap joined col3')
65291 .call(uiModes(context), limiter);
65295 .attr('class', 'button-wrap joined col1')
65296 .call(uiUndoRedo(context));
65300 .attr('class', 'button-wrap col1')
65301 .call(uiSave(context));
65305 .attr('class', 'full-screen')
65306 .call(uiFullScreen(context));
65310 .attr('class', 'spinner')
65311 .call(uiSpinner(context));
65315 .attr('class', 'map-controls');
65319 .attr('class', 'map-control zoombuttons')
65320 .call(uiZoom(context));
65324 .attr('class', 'map-control geolocate-control')
65325 .call(uiGeolocate(context));
65329 .attr('class', 'map-control background-control')
65330 .call(uiBackground(context));
65334 .attr('class', 'map-control map-data-control')
65335 .call(uiMapData(context));
65339 .attr('class', 'map-control help-control')
65340 .call(uiHelp(context));
65342 var about = content
65344 .attr('id', 'about');
65348 .attr('id', 'attrib')
65349 .attr('dir', 'ltr')
65350 .call(uiAttribution(context));
65354 .attr('id', 'footer')
65355 .attr('class', 'fillD');
65359 .attr('class', 'api-status')
65360 .call(uiStatus(context));
65364 .attr('id', 'scale-block')
65365 .call(uiScale(context));
65367 var aboutList = footer
65369 .attr('id', 'info-block')
65371 .attr('id', 'about-list');
65373 if (!context.embed()) {
65374 aboutList.call(uiAccount(context));
65380 .attr('target', '_blank')
65381 .attr('tabindex', -1)
65382 .attr('href', 'https://github.com/openstreetmap/iD')
65383 .text(context.version);
65385 var issueLinks = aboutList
65390 .attr('target', '_blank')
65391 .attr('tabindex', -1)
65392 .attr('href', 'https://github.com/openstreetmap/iD/issues')
65393 .call(svgIcon('#icon-bug', 'light'))
65394 .call(tooltip().title(t('report_a_bug')).placement('top'));
65398 .attr('target', '_blank')
65399 .attr('tabindex', -1)
65400 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
65401 .call(svgIcon('#icon-translate', 'light'))
65402 .call(tooltip().title(t('help_translate')).placement('top'));
65406 .attr('class', 'feature-warning')
65407 .attr('tabindex', -1)
65408 .call(uiFeatureInfo(context));
65412 .attr('class', 'user-list')
65413 .attr('tabindex', -1)
65414 .call(uiContributors(context));
65417 window.onbeforeunload = function() {
65418 return context.save();
65421 window.onunload = function() {
65422 context.history().unlock();
65425 var mapDimensions = map$$1.dimensions();
65428 function onResize() {
65429 mapDimensions = utilGetDimensions(content, true);
65430 map$$1.dimensions(mapDimensions);
65434 .on('resize.editor', onResize);
65439 return function() {
65440 event.preventDefault();
65441 if (!context.inIntro()) {
65442 context.pan(d, 100);
65451 var keybinding = d3keybinding('main')
65452 .on('⌫', function() { event.preventDefault(); })
65453 .on('←', pan([pa, 0]))
65454 .on('↑', pan([0, pa]))
65455 .on('→', pan([-pa, 0]))
65456 .on('↓', pan([0, -pa]))
65457 .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
65458 .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
65459 .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
65460 .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
65465 context.enter(modeBrowse(context));
65467 if (!uiInitCounter++) {
65468 context.container()
65469 .call(uiSplash(context))
65470 .call(uiRestore(context));
65473 var authenticating = uiLoading(context)
65474 .message(t('loading_auth'))
65477 context.connection()
65478 .on('authLoading.ui', function() {
65479 context.container()
65480 .call(authenticating);
65482 .on('authDone.ui', function() {
65483 authenticating.close();
65490 var renderCallback;
65492 function ui(node, callback) {
65493 renderCallback = callback;
65494 var container = select(node);
65495 context.container(container);
65496 context.loadLocale(function(err) {
65507 ui.restart = function(arg) {
65508 context.locale(arg);
65509 context.loadLocale(function(err) {
65511 context.container().selectAll('*').remove();
65512 render(context.container());
65513 if (renderCallback) renderCallback();
65519 ui.sidebar = uiSidebar(context);
65524 function uiCommit(context) {
65525 var dispatch$$1 = dispatch('cancel', 'save');
65528 function commit(selection$$1) {
65529 var changes = context.history().changes(),
65530 summary = context.history().difference().summary();
65534 .attr('class', 'header fillL')
65536 .text(t('commit.title'));
65538 var body = selection$$1
65540 .attr('class', 'body');
65542 var commentSection = body
65544 .attr('class', 'modal-section form-field commit-form');
65548 .attr('class', 'form-label')
65549 .text(t('commit.message_label'));
65551 var commentField = commentSection
65552 .append('textarea')
65553 .attr('placeholder', t('commit.description_placeholder'))
65554 .attr('maxlength', 255)
65555 .property('value', context.storage('comment') || '')
65556 .on('input.save', checkComment)
65557 .on('change.save', checkComment)
65558 .on('blur.save', function() {
65559 context.storage('comment', this.value);
65563 commentField.node().select();
65565 context.connection().userChangesets(function (err, changesets) {
65568 var comments = changesets.map(function(changeset) {
65570 title: changeset.tags.comment,
65571 value: changeset.tags.comment
65577 .caseSensitive(true)
65578 .data(lodash.uniqBy(comments, 'title'))
65582 var clippyArea = commentSection.append('div')
65583 .attr('class', 'clippy-area');
65585 var changeSetInfo = commentSection.append('div')
65586 .attr('class', 'changeset-info');
65588 changeSetInfo.append('a')
65589 .attr('target', '_blank')
65590 .attr('tabindex', -1)
65591 .call(svgIcon('#icon-out-link', 'inline'))
65592 .attr('href', t('commit.about_changeset_comments_link'))
65594 .text(t('commit.about_changeset_comments'));
65598 var warnings = body.selectAll('div.warning-section')
65599 .data([context.history().validate(changes)]);
65601 warnings = warnings.enter()
65603 .attr('class', 'modal-section warning-section fillL2')
65604 .style('display', function(d) { return lodash.isEmpty(d) ? 'none' : null; })
65605 .style('background', '#ffb')
65610 .text(t('commit.warnings'));
65614 .attr('class', 'changeset-list');
65616 var warningLi = warnings.select('ul').selectAll('li')
65617 .data(function(d) { return d; });
65619 warningLi = warningLi.enter()
65621 .on('mouseover', mouseover)
65622 .on('mouseout', mouseout)
65623 .on('click', warningClick)
65627 .call(svgIcon('#icon-alert', 'pre-text'));
65631 .text(function(d) { return d.message; });
65633 warningLi.filter(function(d) { return d.tooltip; })
65635 .title(function(d) { return d.tooltip; })
65640 // Upload Explanation
65641 var saveSection = body
65643 .attr('class','modal-section save-section fillL cf');
65645 var prose = saveSection
65647 .attr('class', 'commit-info')
65648 .html(t('commit.upload_explanation'));
65651 context.connection().userDetails(function(err, user) {
65654 var userLink = select(document.createElement('div'));
65656 if (user.image_url) {
65659 .attr('src', user.image_url)
65660 .attr('class', 'icon pre-text user-icon');
65665 .attr('class','user-info')
65666 .text(user.display_name)
65667 .attr('href', context.connection().userURL(user.display_name))
65668 .attr('tabindex', -1)
65669 .attr('target', '_blank');
65672 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
65677 var buttonSection = saveSection
65679 .attr('class','buttons fillL cf');
65681 var cancelButton = buttonSection
65683 .attr('class', 'secondary-action col5 button cancel-button')
65684 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
65688 .attr('class', 'label')
65689 .text(t('commit.cancel'));
65691 var saveButton = buttonSection
65693 .attr('class', 'action col5 button save-button')
65694 .attr('disabled', function() {
65695 var n = select('.commit-form textarea').node();
65696 return (n && n.value.length) ? null : true;
65698 .on('click.save', function() {
65699 dispatch$$1.call('save', this, {
65700 comment: commentField.node().value
65706 .attr('class', 'label')
65707 .text(t('commit.save'));
65711 var changeSection = body
65713 .attr('class', 'commit-section modal-section fillL2');
65715 changeSection.append('h3')
65716 .text(t('commit.changes', { count: summary.length }));
65718 var li = changeSection
65720 .attr('class', 'changeset-list')
65726 .on('mouseover', mouseover)
65727 .on('mouseout', mouseout)
65728 .on('click', zoomToEntity)
65731 li.each(function(d) {
65733 .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
65737 .attr('class', 'change-type')
65738 .text(function(d) { return t('commit.' + d.changeType) + ' '; });
65740 li.append('strong')
65741 .attr('class', 'entity-type')
65742 .text(function(d) {
65743 var matched = context.presets().match(d.entity, d.graph);
65744 return (matched && matched.name()) || utilDisplayType(d.entity.id);
65748 .attr('class', 'entity-name')
65749 .text(function(d) {
65750 var name = utilDisplayName(d.entity) || '',
65752 if (name !== '') string += ':';
65753 return string += ' ' + name;
65756 li.style('opacity', 0)
65758 .style('opacity', 1);
65761 // Call checkComment off the bat, in case a changeset
65762 // comment is recovered from localStorage
65763 utilTriggerEvent(commentField, 'input');
65766 function mouseover(d) {
65768 context.surface().selectAll(
65769 utilEntityOrMemberSelector([d.entity.id], context.graph())
65770 ).classed('hover', true);
65775 function mouseout() {
65776 context.surface().selectAll('.hover')
65777 .classed('hover', false);
65781 function warningClick(d) {
65783 context.map().zoomTo(d.entity);
65785 modeSelect(context, [d.entity.id]).suppressMenu(true)
65791 function zoomToEntity(change) {
65792 var entity = change.entity;
65793 if (change.changeType !== 'deleted' &&
65794 context.graph().entity(entity.id).geometry(context.graph()) !== 'vertex') {
65795 context.map().zoomTo(entity);
65796 context.surface().selectAll(
65797 utilEntityOrMemberSelector([entity.id], context.graph()))
65798 .classed('hover', true);
65803 function checkComment() {
65804 selectAll('.save-section .save-button')
65805 .attr('disabled', (this.value.length ? null : true));
65807 var googleWarning = clippyArea
65810 .data(this.value.match(/google/i) ? [true] : []);
65812 googleWarning.exit()
65815 googleWarning.enter()
65817 .attr('target', '_blank')
65818 .attr('tabindex', -1)
65819 .call(svgIcon('#icon-alert', 'inline'))
65820 .attr('href', t('commit.google_warning_link'))
65822 .text(t('commit.google_warning'));
65826 return utilRebind(commit, dispatch$$1, 'on');
65829 function uiConfirm(selection) {
65830 var modalSelection = uiModal(selection);
65832 modalSelection.select('.modal')
65833 .classed('modal-alert', true);
65835 var section = modalSelection.select('.content');
65837 section.append('div')
65838 .attr('class', 'modal-section header');
65840 section.append('div')
65841 .attr('class', 'modal-section message-text');
65843 var buttons = section.append('div')
65844 .attr('class', 'modal-section buttons cf');
65847 modalSelection.okButton = function() {
65850 .attr('class', 'action col4')
65851 .on('click.confirm', function() {
65852 modalSelection.remove();
65854 .text(t('confirm.okay'));
65856 return modalSelection;
65860 return modalSelection;
65863 function uiConflicts(context) {
65864 var dispatch$$1 = dispatch('download', 'cancel', 'save'),
65868 function conflicts(selection$$1) {
65869 var header = selection$$1
65871 .attr('class', 'header fillL');
65875 .attr('class', 'fr')
65876 .on('click', function() { dispatch$$1.call('cancel'); })
65877 .call(svgIcon('#icon-close'));
65881 .text(t('save.conflict.header'));
65883 var body = selection$$1
65885 .attr('class', 'body fillL');
65889 .attr('class', 'conflicts-help')
65890 .text(t('save.conflict.help'))
65892 .attr('class', 'conflicts-download')
65893 .text(t('save.conflict.download_changes'))
65894 .on('click.download', function() { dispatch$$1.call('download'); });
65898 .attr('class', 'conflict-container fillL3')
65899 .call(showConflict, 0);
65903 .attr('class', 'conflicts-done')
65904 .attr('opacity', 0)
65905 .style('display', 'none')
65906 .text(t('save.conflict.done'));
65910 .attr('class','buttons col12 joined conflicts-buttons');
65914 .attr('disabled', list.length > 1)
65915 .attr('class', 'action conflicts-button col6')
65916 .text(t('save.title'))
65917 .on('click.try_again', function() { dispatch$$1.call('save'); });
65921 .attr('class', 'secondary-action conflicts-button col6')
65922 .text(t('confirm.cancel'))
65923 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
65927 function showConflict(selection$$1, index) {
65928 if (index < 0 || index >= list.length) return;
65930 var parent = select(selection$$1.node().parentNode);
65932 // enable save button if this is the last conflict being reviewed..
65933 if (index === list.length - 1) {
65934 window.setTimeout(function() {
65935 parent.select('.conflicts-button')
65936 .attr('disabled', null);
65938 parent.select('.conflicts-done')
65940 .attr('opacity', 1)
65941 .style('display', 'block');
65945 var item = selection$$1
65946 .selectAll('.conflict')
65947 .data([list[index]]);
65949 var enter = item.enter()
65951 .attr('class', 'conflict');
65955 .attr('class', 'conflict-count')
65956 .text(t('save.conflict.count', { num: index + 1, total: list.length }));
65960 .attr('class', 'conflict-description')
65962 .text(function(d) { return d.name; })
65963 .on('click', function(d) {
65964 zoomToEntity(d.id);
65965 event.preventDefault();
65968 var details = enter
65970 .attr('class', 'conflict-detail-container');
65974 .attr('class', 'conflict-detail-list')
65976 .data(function(d) { return d.details || []; })
65979 .attr('class', 'conflict-detail-item')
65980 .html(function(d) { return d; });
65984 .attr('class', 'conflict-choices')
65989 .attr('class', 'conflict-nav-buttons joined cf')
65990 .selectAll('button')
65991 .data(['previous', 'next'])
65994 .text(function(d) { return t('save.conflict.' + d); })
65995 .attr('class', 'conflict-nav-button action col6')
65996 .attr('disabled', function(d, i) {
65997 return (i === 0 && index === 0) ||
65998 (i === 1 && index === list.length - 1) || null;
66000 .on('click', function(d, i) {
66001 var container = parent.select('.conflict-container'),
66002 sign = (i === 0 ? -1 : 1);
66005 .selectAll('.conflict')
66009 .call(showConflict, index + sign);
66011 event.preventDefault();
66019 function addChoices(selection$$1) {
66020 var choices = selection$$1
66022 .attr('class', 'layer-list')
66024 .data(function(d) { return d.choices || []; });
66026 var enter = choices.enter()
66028 .attr('class', 'layer');
66035 .attr('type', 'radio')
66036 .attr('name', function(d) { return d.id; })
66037 .on('change', function(d, i) {
66038 var ul = this.parentNode.parentNode.parentNode;
66039 ul.__data__.chosen = i;
66045 .text(function(d) { return d.text; });
66048 .each(function(d, i) {
66049 var ul = this.parentNode;
66050 if (ul.__data__.chosen === i) choose(ul, d);
66055 function choose(ul, datum) {
66056 if (event) event.preventDefault();
66060 .classed('active', function(d) { return d === datum; })
66061 .selectAll('input')
66062 .property('checked', function(d) { return d === datum; });
66064 var extent$$1 = geoExtent$$1(),
66067 entity = context.graph().hasEntity(datum.id);
66068 if (entity) extent$$1._extend(entity.extent(context.graph()));
66072 entity = context.graph().hasEntity(datum.id);
66073 if (entity) extent$$1._extend(entity.extent(context.graph()));
66075 zoomToEntity(datum.id, extent$$1);
66079 function zoomToEntity(id, extent$$1) {
66080 context.surface().selectAll('.hover')
66081 .classed('hover', false);
66083 var entity = context.graph().hasEntity(id);
66086 context.map().trimmedExtent(extent$$1);
66088 context.map().zoomTo(entity);
66090 context.surface().selectAll(
66091 utilEntityOrMemberSelector([entity.id], context.graph()))
66092 .classed('hover', true);
66097 // The conflict list should be an array of objects like:
66100 // name: entityName(local),
66101 // details: merge.conflicts(),
66104 // choice(id, keepMine, forceLocal),
66105 // choice(id, keepTheirs, forceRemote)
66108 conflicts.list = function(_) {
66109 if (!arguments.length) return list;
66115 return utilRebind(conflicts, dispatch$$1, 'on');
66118 function uiFlash(selection) {
66119 var modalSelection = uiModal(selection);
66121 modalSelection.select('.modal')
66122 .classed('modal-flash', true);
66124 modalSelection.select('.content')
66125 .classed('modal-section', true)
66127 .attr('class', 'description');
66129 modalSelection.on('click.flash', function() {
66130 modalSelection.remove();
66133 setTimeout(function() {
66134 modalSelection.remove();
66139 return modalSelection;
66142 function uiLasso(context) {
66143 var group, polygon;
66145 lasso.coordinates = [];
66147 function lasso(selection$$1) {
66148 context.container()
66149 .classed('lasso', true);
66151 group = selection$$1
66153 .attr('class', 'lasso hide');
66157 .attr('class', 'lasso-path');
66160 .call(uiToggle(true));
66166 polygon.data([lasso.coordinates])
66167 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
66172 lasso.extent = function () {
66173 return lasso.coordinates.reduce(function(extent$$1, point) {
66174 return extent$$1.extend(geoExtent$$1(point));
66175 }, geoExtent$$1());
66179 lasso.p = function(_) {
66180 if (!arguments.length) return lasso;
66181 lasso.coordinates.push(_);
66187 lasso.close = function() {
66189 group.call(uiToggle(false, function() {
66190 select(this).remove();
66193 context.container().classed('lasso', false);
66200 function uiRadialMenu(context, operations) {
66206 var radialMenu = function(selection$$1) {
66207 if (!operations.length) return;
66209 selection$$1.node().parentNode.focus();
66211 function click(operation) {
66212 event.stopPropagation();
66213 if (operation.disabled()) return;
66215 radialMenu.close();
66218 menu = selection$$1
66220 .attr('class', 'radial-menu')
66221 .attr('transform', 'translate(' + center + ')')
66222 .attr('opacity', 0);
66226 .attr('opacity', 1);
66231 a1 = a0 + (operations.length - 1) * a;
66235 .attr('class', 'radial-menu-background')
66236 .attr('d', 'M' + r * Math.sin(a0) + ',' +
66238 ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
66239 (r * Math.sin(a1) + 1e-3) + ',' +
66240 (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
66241 .attr('stroke-width', 50)
66242 .attr('stroke-linecap', 'round');
66244 var button = menu.selectAll()
66248 .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
66249 .classed('disabled', function(d) { return d.disabled(); })
66250 .attr('transform', function(d, i) {
66251 return 'translate(' + geoRoundCoords([
66252 r * Math.sin(a0 + i * a),
66253 r * Math.cos(a0 + i * a)]).join(',') + ')';
66259 .on('click', click)
66260 .on('mousedown', mousedown)
66261 .on('mouseover', mouseover)
66262 .on('mouseout', mouseout);
66266 .attr('transform', 'translate(-10,-10)')
66267 .attr('width', '20')
66268 .attr('height', '20')
66269 .attr('xlink:href', function(d) { return '#operation-' + d.id; });
66271 tooltip = select(document.body)
66273 .attr('class', 'tooltip-inner radial-menu-tooltip');
66275 function mousedown() {
66276 event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
66279 function mouseover(d, i) {
66280 var rect = context.surfaceRect(),
66281 angle = a0 + i * a,
66282 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
66283 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
66284 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
66285 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
66288 .style('top', null)
66289 .style('left', null)
66290 .style('bottom', null)
66291 .style('right', null)
66292 .style('display', 'block')
66293 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
66297 .style('right', right)
66298 .style('top', top);
66299 } else if (i >= 4) {
66301 .style('left', left)
66302 .style('bottom', bottom);
66305 .style('left', left)
66306 .style('top', top);
66310 function mouseout() {
66311 tooltip.style('display', 'none');
66316 radialMenu.close = function() {
66319 .style('pointer-events', 'none')
66321 .attr('opacity', 0)
66331 radialMenu.center = function(_) {
66332 if (!arguments.length) return center;
66341 function uiSelectionList(context, selectedIDs) {
66343 function selectEntity(entity) {
66344 context.enter(modeSelect(context, [entity.id]).suppressMenu(true));
66348 function deselectEntity(entity) {
66349 event.stopPropagation();
66350 var index = selectedIDs.indexOf(entity.id);
66352 selectedIDs.splice(index, 1);
66354 context.enter(modeSelect(context, selectedIDs).suppressMenu(true));
66358 function selectionList(selection$$1) {
66359 selection$$1.classed('selection-list-pane', true);
66361 var header = selection$$1
66363 .attr('class', 'header fillL cf');
66367 .text(t('inspector.multiselect'));
66369 var listWrap = selection$$1
66371 .attr('class', 'inspector-body');
66373 var list = listWrap
66375 .attr('class', 'feature-list cf');
66377 context.history().on('change.selection-list', drawList);
66381 function drawList() {
66382 var entities = selectedIDs
66383 .map(function(id) { return context.hasEntity(id); })
66384 .filter(function(entity) { return entity; });
66386 var items = list.selectAll('.feature-list-item')
66387 .data(entities, osmEntity$$1.key);
66393 var enter = items.enter()
66395 .attr('class', 'feature-list-item')
66396 .on('click', selectEntity);
66400 .attr('class', 'label');
66404 .attr('class', 'close')
66405 .on('click', deselectEntity)
66406 .call(svgIcon('#icon-close'));
66410 .attr('class', 'entity-geom-icon')
66411 .call(svgIcon('', 'pre-text'));
66415 .attr('class', 'entity-type');
66419 .attr('class', 'entity-name');
66422 items = items.merge(enter);
66424 items.selectAll('.entity-geom-icon use')
66425 .attr('href', function() {
66426 var entity = this.parentNode.parentNode.__data__;
66427 return '#icon-' + context.geometry(entity.id);
66430 items.selectAll('.entity-type')
66431 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
66433 items.selectAll('.entity-name')
66434 .text(function(entity) { return utilDisplayName(entity); });
66438 return selectionList;
66441 function uiSourceSwitch(context) {
66446 event.preventDefault();
66448 if (context.history().hasChanges() &&
66449 !window.confirm(t('source_switch.lose_changes'))) return;
66451 var live = select(this)
66454 context.connection()
66455 .switch(live ? keys$$1[1] : keys$$1[0]);
66457 context.enter(modeBrowse(context));
66461 .text(live ? t('source_switch.dev') : t('source_switch.live'))
66462 .classed('live', !live);
66465 var sourceSwitch = function(selection$$1) {
66469 .text(t('source_switch.live'))
66470 .classed('live', true)
66471 .attr('tabindex', -1)
66472 .on('click', click);
66476 sourceSwitch.keys = function(_) {
66477 if (!arguments.length) return keys$$1;
66479 return sourceSwitch;
66483 return sourceSwitch;
66486 function uiSuccess(context) {
66487 var dispatch$$1 = dispatch('cancel'),
66491 function success(selection$$1) {
66492 var message = (changeset.comment || t('success.edited_osm')).substring(0, 130) +
66493 ' ' + context.connection().changesetURL(changeset.id);
66495 var header = selection$$1
66497 .attr('class', 'header fillL');
66501 .attr('class', 'fr')
66502 .on('click', function() { dispatch$$1.call('cancel'); })
66503 .call(svgIcon('#icon-close'));
66507 .text(t('success.just_edited'));
66509 var body = selection$$1
66511 .attr('class', 'body save-success fillL');
66515 .html(t('success.help_html'));
66519 .attr('class', 'details')
66520 .attr('target', '_blank')
66521 .attr('tabindex', -1)
66522 .call(svgIcon('#icon-out-link', 'inline'))
66523 .attr('href', t('success.help_link_url'))
66525 .text(t('success.help_link_text'));
66527 var changesetURL = context.connection().changesetURL(changeset.id);
66531 .attr('class', 'button col12 osm')
66532 .attr('target', '_blank')
66533 .attr('href', changesetURL)
66534 .text(t('success.view_on_osm'));
66537 facebook: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL),
66538 twitter: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message),
66539 google: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL)
66542 body.selectAll('.button.social')
66543 .data(entries(sharing))
66546 .attr('class', 'button social col4')
66547 .attr('target', '_blank')
66548 .attr('href', function(d) { return d.value; })
66550 .title(function(d) { return t('success.' + d.key); })
66551 .placement('bottom'))
66552 .each(function(d) { select(this).call(svgIcon('#logo-' + d.key, 'social')); });
66556 success.changeset = function(_) {
66557 if (!arguments.length) return changeset;
66563 return utilRebind(success, dispatch$$1, 'on');
66566 function coreHistory(context) {
66567 var imageryUsed = ['Bing'],
66568 dispatch$$1 = dispatch('change', 'undone', 'redone'),
66569 lock = utilSessionMutex('lock'),
66571 stack$$1, index, tree$$1;
66574 // internal _act, accepts list of actions and eased time
66575 function _act(actions, t) {
66576 actions = Array.prototype.slice.call(actions);
66580 if (!lodash.isFunction(lodash.last(actions))) {
66581 annotation = actions.pop();
66584 stack$$1[index].transform = context.projection.transform();
66585 stack$$1[index].selectedIDs = context.selectedIDs();
66587 var graph = stack$$1[index].graph;
66588 for (var i = 0; i < actions.length; i++) {
66589 graph = actions[i](graph, t);
66594 annotation: annotation,
66595 imageryUsed: imageryUsed
66600 // internal _perform with eased time
66601 function _perform(args, t) {
66602 var previous = stack$$1[index].graph;
66603 stack$$1 = stack$$1.slice(0, index + 1);
66604 stack$$1.push(_act(args, t));
66606 return change(previous);
66610 // internal _replace with eased time
66611 function _replace(args, t) {
66612 var previous = stack$$1[index].graph;
66613 // assert(index == stack.length - 1)
66614 stack$$1[index] = _act(args, t);
66615 return change(previous);
66619 // internal _overwrite with eased time
66620 function _overwrite(args, t) {
66621 var previous = stack$$1[index].graph;
66626 stack$$1 = stack$$1.slice(0, index + 1);
66627 stack$$1.push(_act(args, t));
66629 return change(previous);
66633 // determine diffrence and dispatch a change event
66634 function change(previous) {
66635 var difference = coreDifference(previous, history.graph());
66636 dispatch$$1.call('change', this, difference);
66641 // iD uses namespaced keys so multiple installations do not conflict
66642 function getKey(n) {
66643 return 'iD_' + window.location.origin + '_' + n;
66649 graph: function() {
66650 return stack$$1[index].graph;
66655 return stack$$1[0].graph;
66659 merge: function(entities, extent$$1) {
66660 stack$$1[0].graph.rebase(entities, lodash.map(stack$$1, 'graph'), false);
66661 tree$$1.rebase(entities, false);
66663 dispatch$$1.call('change', this, undefined, extent$$1);
66667 perform: function() {
66668 // complete any transition already in progress
66669 select(document).interrupt('history.perform');
66671 var transitionable = false,
66672 action0 = arguments[0];
66674 if (arguments.length === 1 ||
66675 arguments.length === 2 && !lodash.isFunction(arguments[1])) {
66676 transitionable = !!action0.transitionable;
66679 if (transitionable) {
66680 var origArguments = arguments;
66682 .transition('history.perform')
66683 .duration(duration)
66685 .tween('history.tween', function() {
66686 return function(t) {
66687 if (t < 1) _overwrite([action0], t);
66690 .on('start', function() {
66691 _perform([action0], 0);
66693 .on('end interrupt', function() {
66694 _overwrite(origArguments, 1);
66698 return _perform(arguments);
66703 replace: function() {
66704 select(document).interrupt('history.perform');
66705 return _replace(arguments, 1);
66709 // Same as calling pop and then perform
66710 overwrite: function() {
66711 select(document).interrupt('history.perform');
66712 return _overwrite(arguments, 1);
66717 select(document).interrupt('history.perform');
66719 var previous = stack$$1[index].graph;
66723 return change(previous);
66729 select(document).interrupt('history.perform');
66731 var previous = stack$$1[index].graph;
66733 // Pop to the next annotated state.
66734 while (index > 0) {
66736 if (stack$$1[index].annotation) break;
66739 dispatch$$1.call('undone', this, stack$$1[index]);
66740 return change(previous);
66745 select(document).interrupt('history.perform');
66747 var previous = stack$$1[index].graph;
66748 while (index < stack$$1.length - 1) {
66750 if (stack$$1[index].annotation) break;
66753 dispatch$$1.call('redone', this, stack$$1[index]);
66754 return change(previous);
66758 undoAnnotation: function() {
66761 if (stack$$1[i].annotation) return stack$$1[i].annotation;
66767 redoAnnotation: function() {
66769 while (i <= stack$$1.length - 1) {
66770 if (stack$$1[i].annotation) return stack$$1[i].annotation;
66776 intersects: function(extent$$1) {
66777 return tree$$1.intersects(extent$$1, stack$$1[index].graph);
66781 difference: function() {
66782 var base = stack$$1[0].graph,
66783 head = stack$$1[index].graph;
66784 return coreDifference(base, head);
66788 changes: function(action) {
66789 var base = stack$$1[0].graph,
66790 head = stack$$1[index].graph;
66793 head = action(head);
66796 var difference = coreDifference(base, head);
66799 modified: difference.modified(),
66800 created: difference.created(),
66801 deleted: difference.deleted()
66806 validate: function(changes) {
66807 return lodash(Validations)
66808 .map(function(fn) { return fn()(changes, stack$$1[index].graph); })
66814 hasChanges: function() {
66815 return this.difference().length() > 0;
66819 imageryUsed: function(sources) {
66821 imageryUsed = sources;
66824 return lodash(stack$$1.slice(1, index + 1))
66825 .map('imageryUsed')
66828 .without(undefined, 'Custom')
66834 reset: function() {
66835 stack$$1 = [{graph: coreGraph$$1()}];
66837 tree$$1 = coreTree(stack$$1[0].graph);
66838 dispatch$$1.call('change');
66843 toJSON: function() {
66844 if (!this.hasChanges()) return;
66846 var allEntities = {},
66848 base = stack$$1[0];
66850 var s = stack$$1.map(function(i) {
66851 var modified = [], deleted = [];
66853 lodash.forEach(i.graph.entities, function(entity, id) {
66855 var key = osmEntity$$1.key(entity);
66856 allEntities[key] = entity;
66857 modified.push(key);
66862 // make sure that the originals of changed or deleted entities get merged
66863 // into the base of the stack after restoring the data from JSON.
66864 if (id in base.graph.entities) {
66865 baseEntities[id] = base.graph.entities[id];
66867 // get originals of parent entities too
66868 lodash.forEach(base.graph._parentWays[id], function(parentId) {
66869 if (parentId in base.graph.entities) {
66870 baseEntities[parentId] = base.graph.entities[parentId];
66877 if (modified.length) x.modified = modified;
66878 if (deleted.length) x.deleted = deleted;
66879 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
66880 if (i.annotation) x.annotation = i.annotation;
66885 return JSON.stringify({
66887 entities: lodash.values(allEntities),
66888 baseEntities: lodash.values(baseEntities),
66890 nextIDs: osmEntity$$1.id.next,
66896 fromJSON: function(json$$1, loadChildNodes) {
66897 var h = JSON.parse(json$$1),
66898 loadComplete = true;
66900 osmEntity$$1.id.next = h.nextIDs;
66903 if (h.version === 2 || h.version === 3) {
66904 var allEntities = {};
66906 h.entities.forEach(function(entity) {
66907 allEntities[osmEntity$$1.key(entity)] = osmEntity$$1(entity);
66910 if (h.version === 3) {
66911 // This merges originals for changed entities into the base of
66912 // the stack even if the current stack doesn't have them (for
66913 // example when iD has been restarted in a different region)
66914 var baseEntities = h.baseEntities.map(function(d) { return osmEntity$$1(d); });
66915 stack$$1[0].graph.rebase(baseEntities, lodash.map(stack$$1, 'graph'), true);
66916 tree$$1.rebase(baseEntities, true);
66918 // When we restore a modified way, we also need to fetch any missing
66919 // childnodes that would normally have been downloaded with it.. #2142
66920 if (loadChildNodes) {
66921 var missing = lodash(baseEntities)
66922 .filter({ type: 'way' })
66926 .reject(function(n) { return stack$$1[0].graph.hasEntity(n); })
66929 if (!lodash.isEmpty(missing)) {
66930 loadComplete = false;
66931 context.redrawEnable(false);
66933 var loading = uiLoading(context).blocking(true);
66934 context.container().call(loading);
66936 var childNodesLoaded = function(err, result) {
66938 var visible = lodash.groupBy(result.data, 'visible');
66939 if (!lodash.isEmpty(visible.true)) {
66940 missing = lodash.difference(missing, lodash.map(visible.true, 'id'));
66941 stack$$1[0].graph.rebase(visible.true, lodash.map(stack$$1, 'graph'), true);
66942 tree$$1.rebase(visible.true, true);
66945 // fetch older versions of nodes that were deleted..
66946 lodash.each(visible.false, function(entity) {
66947 context.connection()
66948 .loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
66952 if (err || lodash.isEmpty(missing)) {
66954 context.redrawEnable(true);
66955 dispatch$$1.call('change');
66959 context.connection().loadMultiple(missing, childNodesLoaded);
66964 stack$$1 = h.stack.map(function(d) {
66965 var entities = {}, entity;
66968 d.modified.forEach(function(key) {
66969 entity = allEntities[key];
66970 entities[entity.id] = entity;
66975 d.deleted.forEach(function(id) {
66976 entities[id] = undefined;
66981 graph: coreGraph$$1(stack$$1[0].graph).load(entities),
66982 annotation: d.annotation,
66983 imageryUsed: d.imageryUsed
66987 } else { // original version
66988 stack$$1 = h.stack.map(function(d) {
66991 for (var i in d.entities) {
66992 var entity = d.entities[i];
66993 entities[i] = entity === 'undefined' ? undefined : osmEntity$$1(entity);
66996 d.graph = coreGraph$$1(stack$$1[0].graph).load(entities);
67001 if (loadComplete) {
67002 dispatch$$1.call('change');
67010 if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
67015 clearSaved: function() {
67016 context.debouncedSave.cancel();
67017 if (lock.locked()) context.storage(getKey('saved_history'), null);
67023 return lock.lock();
67027 unlock: function() {
67032 // is iD not open in another window and it detects that
67033 // there's a history stored in localStorage that's recoverable?
67034 restorableChanges: function() {
67035 return lock.locked() && !!context.storage(getKey('saved_history'));
67039 // load history from a version stored in localStorage
67040 restore: function() {
67041 if (!lock.locked()) return;
67043 var json$$1 = context.storage(getKey('saved_history'));
67044 if (json$$1) history.fromJSON(json$$1, true);
67055 return utilRebind(history, dispatch$$1, 'on');
67058 function presetCollection(collection) {
67059 var maxSearchResults = 50,
67060 maxSuggestionResults = 10;
67064 collection: collection,
67067 item: function(id) {
67068 return lodash.find(collection, function(d) {
67069 return d.id === id;
67074 matchGeometry: function(geometry) {
67075 return presetCollection(collection.filter(function(d) {
67076 return d.matchGeometry(geometry);
67081 search: function(value, geometry) {
67082 if (!value) return this;
67084 function leading(a) {
67085 var index = a.indexOf(value);
67086 return index === 0 || a[index - 1] === ' ';
67089 function suggestionName(name) {
67090 var nameArray = name.split(' - ');
67091 if (nameArray.length > 1) {
67092 name = nameArray.slice(0, nameArray.length - 1).join(' - ');
67094 return name.toLowerCase();
67098 value = value.toLowerCase();
67100 var searchable = lodash.filter(collection, function(a) {
67101 return a.searchable !== false && a.suggestion !== true;
67103 suggestions = lodash.filter(collection, function(a) {
67104 return a.suggestion === true;
67108 // matches value to preset.name
67109 var leading_name = lodash.filter(searchable, function(a) {
67110 return leading(a.name().toLowerCase());
67111 }).sort(function(a, b) {
67112 var i = a.name().toLowerCase().indexOf(value) - b.name().toLowerCase().indexOf(value);
67113 if (i === 0) return a.name().length - b.name().length;
67117 // matches value to preset.terms values
67118 var leading_terms = lodash.filter(searchable, function(a) {
67119 return lodash.some(a.terms() || [], leading);
67122 // matches value to preset.tags values
67123 var leading_tag_values = lodash.filter(searchable, function(a) {
67124 return lodash.some(lodash.without(lodash.values(a.tags || {}), '*'), leading);
67128 // finds close matches to value in preset.name
67129 var similar_name = searchable.map(function(a) {
67132 dist: utilEditDistance(value, a.name())
67134 }).filter(function(a) {
67135 return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
67136 }).sort(function(a, b) {
67137 return a.dist - b.dist;
67138 }).map(function(a) {
67142 // finds close matches to value in preset.terms
67143 var similar_terms = lodash.filter(searchable, function(a) {
67144 return lodash.some(a.terms() || [], function(b) {
67145 return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
67149 var leading_suggestions = lodash.filter(suggestions, function(a) {
67150 return leading(suggestionName(a.name()));
67151 }).sort(function(a, b) {
67152 a = suggestionName(a.name());
67153 b = suggestionName(b.name());
67154 var i = a.indexOf(value) - b.indexOf(value);
67155 if (i === 0) return a.length - b.length;
67159 var similar_suggestions = suggestions.map(function(a) {
67162 dist: utilEditDistance(value, suggestionName(a.name()))
67164 }).filter(function(a) {
67165 return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
67166 }).sort(function(a, b) {
67167 return a.dist - b.dist;
67168 }).map(function(a) {
67172 var other = presets.item(geometry);
67174 var results = leading_name.concat(
67176 leading_tag_values,
67177 leading_suggestions.slice(0, maxSuggestionResults + 5),
67180 similar_suggestions.slice(0, maxSuggestionResults)
67181 ).slice(0, maxSearchResults - 1);
67183 return presetCollection(lodash.uniq(results.concat(other)));
67191 function presetCategory(id, category, all) {
67192 category = lodash.clone(category);
67197 category.members = presetCollection(category.members.map(function(id) {
67198 return all.item(id);
67202 category.matchGeometry = function(geometry) {
67203 return category.geometry.indexOf(geometry) >= 0;
67207 category.matchScore = function() {
67212 category.name = function() {
67213 return t('presets.categories.' + id + '.name', {'default': id});
67217 category.terms = function() {
67225 function presetField(id, field) {
67226 field = lodash.clone(field);
67231 field.matchGeometry = function(geometry) {
67232 return !field.geometry || field.geometry === geometry;
67236 field.t = function(scope, options) {
67237 return t('presets.fields.' + id + '.' + scope, options);
67241 field.label = function() {
67242 return field.t('label', {'default': id});
67246 var placeholder = field.placeholder;
67247 field.placeholder = function() {
67248 return field.t('placeholder', {'default': placeholder});
67255 function presetPreset(id, preset, fields) {
67256 preset = lodash.clone(preset);
67259 preset.fields = (preset.fields || []).map(getFields);
67260 preset.geometry = (preset.geometry || []);
67263 function getFields(f) {
67268 preset.matchGeometry = function(geometry) {
67269 return preset.geometry.indexOf(geometry) >= 0;
67273 var matchScore = preset.matchScore || 1;
67274 preset.matchScore = function(entity) {
67275 var tags = preset.tags,
67278 for (var t$$1 in tags) {
67279 if (entity.tags[t$$1] === tags[t$$1]) {
67280 score += matchScore;
67281 } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
67282 score += matchScore / 2;
67292 preset.t = function(scope, options) {
67293 return t('presets.presets.' + id + '.' + scope, options);
67297 var name = preset.name || '';
67298 preset.name = function() {
67299 if (preset.suggestion) {
67300 id = id.split('/');
67301 id = id[0] + '/' + id[1];
67302 return name + ' - ' + t('presets.presets.' + id + '.name');
67304 return preset.t('name', {'default': name});
67308 preset.terms = function() {
67309 return preset.t('terms', {'default': ''}).toLowerCase().trim().split(/\s*,+\s*/);
67313 preset.isFallback = function() {
67314 var tagCount = Object.keys(preset.tags).length;
67315 return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
67319 preset.reference = function(geometry) {
67320 var key = Object.keys(preset.tags)[0],
67321 value = preset.tags[key];
67323 if (geometry === 'relation' && key === 'type') {
67324 if (value in preset.tags) {
67326 value = preset.tags[key];
67328 return { rtype: value };
67332 if (value === '*') {
67333 return { key: key };
67335 return { key: key, value: value };
67340 var removeTags = preset.removeTags || preset.tags;
67341 preset.removeTags = function(tags, geometry) {
67342 tags = lodash.omit(tags, lodash.keys(removeTags));
67344 for (var f in preset.fields) {
67345 var field = preset.fields[f];
67346 if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
67347 delete tags[field.key];
67356 var applyTags = preset.addTags || preset.tags;
67357 preset.applyTags = function(tags, geometry) {
67360 tags = lodash.clone(tags);
67362 for (k in applyTags) {
67363 if (applyTags[k] === '*') {
67366 tags[k] = applyTags[k];
67370 // Add area=yes if necessary.
67371 // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
67372 // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
67373 // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
67374 if (geometry === 'area') {
67375 var needsAreaTag = true;
67376 if (preset.geometry.indexOf('line') === -1) {
67377 for (k in applyTags) {
67378 if (k in areaKeys) {
67379 needsAreaTag = false;
67384 if (needsAreaTag) {
67389 for (var f in preset.fields) {
67390 var field = preset.fields[f];
67391 if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
67392 tags[field.key] = field.default;
67403 function presetIndex() {
67404 // a presetCollection with methods for
67405 // loading new data and returning defaults
67407 var all = presetCollection([]),
67408 defaults = { area: all, line: all, point: all, vertex: all, relation: all },
67411 recent = presetCollection([]);
67413 // Index of presets by (geometry, tag key).
67422 all.match = function(entity, resolver) {
67423 var geometry = entity.geometry(resolver);
67425 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
67426 if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
67427 geometry = 'point';
67430 var geometryMatches = index[geometry],
67434 for (var k in entity.tags) {
67435 var keyMatches = geometryMatches[k];
67436 if (!keyMatches) continue;
67438 for (var i = 0; i < keyMatches.length; i++) {
67439 var score = keyMatches[i].matchScore(entity);
67440 if (score > best) {
67442 match = keyMatches[i];
67447 return match || all.item(geometry);
67451 // Because of the open nature of tagging, iD will never have a complete
67452 // list of tags used in OSM, so we want it to have logic like "assume
67453 // that a closed way with an amenity tag is an area, unless the amenity
67454 // is one of these specific types". This function computes a structure
67455 // that allows testing of such conditions, based on the presets designated
67456 // as as supporting (or not supporting) the area geometry.
67458 // The returned object L is a whitelist/blacklist of tags. A closed way
67459 // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
67460 // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
67461 // and the subkeys form the blacklist.
67462 all.areaKeys = function() {
67464 ignore = ['barrier', 'highway', 'footway', 'railway', 'type'],
67465 presets = lodash.reject(all.collection, 'suggestion');
67468 presets.forEach(function(d) {
67469 for (var key in d.tags) break;
67471 if (ignore.indexOf(key) !== -1) return;
67473 if (d.geometry.indexOf('area') !== -1) {
67474 areaKeys[key] = areaKeys[key] || {};
67479 presets.forEach(function(d) {
67480 for (var key in d.tags) break;
67482 if (ignore.indexOf(key) !== -1) return;
67484 var value = d.tags[key];
67485 if (d.geometry.indexOf('area') === -1 &&
67486 d.geometry.indexOf('line') !== -1 &&
67487 key in areaKeys && value !== '*') {
67488 areaKeys[key][value] = true;
67496 all.init = function() {
67497 var d = data.presets;
67500 lodash.forEach(d.fields, function(d, id) {
67501 fields[id] = presetField(id, d);
67502 if (d.universal) universal.push(fields[id]);
67507 lodash.forEach(d.presets, function(d, id) {
67508 all.collection.push(presetPreset(id, d, fields));
67512 if (d.categories) {
67513 lodash.forEach(d.categories, function(d, id) {
67514 all.collection.push(presetCategory(id, d, all));
67519 var getItem = lodash.bind(all.item, all);
67521 area: presetCollection(d.defaults.area.map(getItem)),
67522 line: presetCollection(d.defaults.line.map(getItem)),
67523 point: presetCollection(d.defaults.point.map(getItem)),
67524 vertex: presetCollection(d.defaults.vertex.map(getItem)),
67525 relation: presetCollection(d.defaults.relation.map(getItem))
67529 for (var i = 0; i < all.collection.length; i++) {
67530 var preset = all.collection[i],
67531 geometry = preset.geometry;
67533 for (var j = 0; j < geometry.length; j++) {
67534 var g = index[geometry[j]];
67535 for (var k in preset.tags) {
67536 (g[k] = g[k] || []).push(preset);
67544 all.field = function(id) {
67548 all.universal = function() {
67552 all.defaults = function(geometry, n) {
67553 var rec = recent.matchGeometry(geometry).collection.slice(0, 4),
67554 def = lodash.uniq(rec.concat(defaults[geometry].collection)).slice(0, n - 1);
67555 return presetCollection(lodash.uniq(rec.concat(def).concat(all.item(geometry))));
67558 all.choose = function(preset) {
67559 if (!preset.isFallback()) {
67560 recent = presetCollection(lodash.uniq([preset].concat(recent.collection)));
67570 function setAreaKeys(value) {
67575 function coreContext() {
67577 // create a special translation that contains the keys in place of the strings
67578 var tkeys = lodash.cloneDeep(en);
67581 function traverser(v, k, obj) {
67583 if (lodash.isObject(v)) {
67584 lodash.forOwn(v, traverser);
67585 } else if (lodash.isString(v)) {
67586 obj[k] = parents.join('.');
67591 lodash.forOwn(tkeys, traverser);
67592 addTranslation('_tkeys_', tkeys);
67594 addTranslation('en', en);
67597 var dispatch$$1 = dispatch('enter', 'exit', 'change'),
67600 // https://github.com/openstreetmap/iD/issues/772
67601 // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
67603 try { storage = localStorage; } catch (e) {} // eslint-disable-line no-empty
67604 storage = storage || (function() {
67607 getItem: function(k) { return s[k]; },
67608 setItem: function(k, v) { s[k] = v; },
67609 removeItem: function(k) { delete s[k]; }
67613 context.storage = function(k, v) {
67615 if (arguments.length === 1) return storage.getItem(k);
67616 else if (v === null) storage.removeItem(k);
67617 else storage.setItem(k, v);
67619 // localstorage quota exceeded
67620 /* eslint-disable no-console */
67621 if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
67622 /* eslint-enable no-console */
67627 /* Straight accessors. Avoid using these if you can. */
67628 var ui, connection, history;
67629 context.ui = function() { return ui; };
67630 context.connection = function() { return connection; };
67631 context.history = function() { return history; };
67635 function entitiesLoaded(err, result) {
67636 if (!err) history.merge(result.data, result.extent);
67639 context.preauth = function(options) {
67640 connection.switch(options);
67644 context.loadTiles = function(projection, dimensions, callback) {
67645 function done(err, result) {
67646 entitiesLoaded(err, result);
67647 if (callback) callback(err, result);
67649 connection.loadTiles(projection, dimensions, done);
67652 context.loadEntity = function(id, callback) {
67653 function done(err, result) {
67654 entitiesLoaded(err, result);
67655 if (callback) callback(err, result);
67657 connection.loadEntity(id, done);
67660 context.zoomToEntity = function(id, zoomTo) {
67661 if (zoomTo !== false) {
67662 this.loadEntity(id, function(err, result) {
67664 var entity = lodash.find(result.data, function(e) { return e.id === id; });
67665 if (entity) { map$$1.zoomTo(entity); }
67669 map$$1.on('drawn.zoomToEntity', function() {
67670 if (!context.hasEntity(id)) return;
67671 map$$1.on('drawn.zoomToEntity', null);
67672 context.on('enter.zoomToEntity', null);
67673 context.enter(modeSelect(context, [id]));
67676 context.on('enter.zoomToEntity', function() {
67677 if (mode.id !== 'browse') {
67678 map$$1.on('drawn.zoomToEntity', null);
67679 context.on('enter.zoomToEntity', null);
67684 var minEditableZoom = 16;
67685 context.minEditableZoom = function(_) {
67686 if (!arguments.length) return minEditableZoom;
67687 minEditableZoom = _;
67688 connection.tileZoom(_);
67694 var inIntro = false;
67695 context.inIntro = function(_) {
67696 if (!arguments.length) return inIntro;
67701 context.save = function() {
67702 // no history save, no message onbeforeunload
67703 if (inIntro || select('.modal').size()) return;
67706 if (mode && mode.id === 'save') {
67709 canSave = context.selectedIDs().every(function(id) {
67710 var entity = context.hasEntity(id);
67711 return entity && !entity.isDegenerate();
67718 if (history.hasChanges()) {
67719 return t('save.unsaved_changes');
67725 context.hasEntity = function(id) {
67726 return history.graph().hasEntity(id);
67728 context.entity = function(id) {
67729 return history.graph().entity(id);
67731 context.childNodes = function(way) {
67732 return history.graph().childNodes(way);
67734 context.geometry = function(id) {
67735 return context.entity(id).geometry(history.graph());
67741 context.mode = function() {
67744 context.enter = function(newMode) {
67747 dispatch$$1.call('exit', this, mode);
67752 dispatch$$1.call('enter', this, mode);
67755 context.selectedIDs = function() {
67756 if (mode && mode.selectedIDs) {
67757 return mode.selectedIDs();
67765 context.install = function(behavior) {
67766 context.surface().call(behavior);
67768 context.uninstall = function(behavior) {
67769 context.surface().call(behavior.off);
67774 var copyIDs = [], copyGraph;
67775 context.copyGraph = function() { return copyGraph; };
67776 context.copyIDs = function(_) {
67777 if (!arguments.length) return copyIDs;
67779 copyGraph = history.graph();
67786 context.background = function() { return background; };
67791 context.features = function() { return features; };
67792 context.hasHiddenConnections = function(id) {
67793 var graph = history.graph(),
67794 entity = graph.entity(id);
67795 return features.hasHiddenConnections(entity, graph);
67801 context.presets = function() { return presets; };
67806 context.map = function() { return map$$1; };
67807 context.layers = function() { return map$$1.layers; };
67808 context.surface = function() { return map$$1.surface; };
67809 context.editable = function() { return map$$1.editable(); };
67811 context.surfaceRect = function() {
67812 // Work around a bug in Firefox.
67813 // http://stackoverflow.com/questions/18153989/
67814 // https://bugzilla.mozilla.org/show_bug.cgi?id=530985
67815 return context.surface().node().parentNode.getBoundingClientRect();
67827 context.debugFlags = function() {
67830 context.setDebug = function(flag, val) {
67831 if (arguments.length === 1) val = true;
67832 debugFlags[flag] = val;
67833 dispatch$$1.call('change');
67836 context.getDebug = function(flag) {
67837 return flag && debugFlags[flag];
67842 var container, embed;
67843 context.container = function(_) {
67844 if (!arguments.length) return container;
67846 container.classed('id-container', true);
67849 context.embed = function(_) {
67850 if (!arguments.length) return embed;
67857 var assetPath = '';
67858 context.assetPath = function(_) {
67859 if (!arguments.length) return assetPath;
67865 context.assetMap = function(_) {
67866 if (!arguments.length) return assetMap;
67871 context.asset = function(_) {
67872 var filename = assetPath + _;
67873 return assetMap[filename] || filename;
67876 context.imagePath = function(_) {
67877 return context.asset('img/' + _);
67882 // `locale` variable contains a "requested locale".
67883 // It won't become the `currentLocale` until after loadLocale() is called.
67884 var locale, localePath;
67886 context.locale = function(loc, path$$1) {
67887 if (!arguments.length) return currentLocale;
67889 localePath = path$$1;
67893 context.loadLocale = function(callback) {
67894 if (locale && locale !== 'en' && dataLocales.hasOwnProperty(locale)) {
67895 localePath = localePath || context.asset('locales/' + locale + '.json');
67896 json(localePath, function(err, result) {
67898 addTranslation(locale, result[locale]);
67918 /* reset (aka flush) */
67919 context.reset = context.flush = function() {
67920 context.debouncedSave.cancel();
67921 lodash.each(services, function(service) {
67922 if (service && typeof service.reset === 'function') {
67923 service.reset(context);
67933 context.version = '2.1.2';
67935 context.projection = geoRawMercator();
67937 locale = utilDetect().locale;
67938 if (locale && !dataLocales.hasOwnProperty(locale)) {
67939 locale = locale.split('-')[0];
67942 history = coreHistory(context);
67943 context.graph = history.graph;
67944 context.changes = history.changes;
67945 context.intersects = history.intersects;
67947 // Debounce save, since it's a synchronous localStorage write,
67948 // and history changes can happen frequently (e.g. when dragging).
67949 context.debouncedSave = lodash.debounce(context.save, 350);
67950 function withDebouncedSave(fn) {
67951 return function() {
67952 var result = fn.apply(history, arguments);
67953 context.debouncedSave();
67958 context.perform = withDebouncedSave(history.perform);
67959 context.replace = withDebouncedSave(history.replace);
67960 context.pop = withDebouncedSave(history.pop);
67961 context.overwrite = withDebouncedSave(history.overwrite);
67962 context.undo = withDebouncedSave(history.undo);
67963 context.redo = withDebouncedSave(history.redo);
67965 ui = uiInit(context);
67967 connection = services.osm;
67968 background = rendererBackground(context);
67969 features = rendererFeatures(context);
67970 presets = presetIndex();
67972 map$$1 = rendererMap(context);
67973 context.mouse = map$$1.mouse;
67974 context.extent = map$$1.extent;
67975 context.pan = map$$1.pan;
67976 context.zoomIn = map$$1.zoomIn;
67977 context.zoomOut = map$$1.zoomOut;
67978 context.zoomInFurther = map$$1.zoomInFurther;
67979 context.zoomOutFurther = map$$1.zoomOutFurther;
67980 context.redrawEnable = map$$1.redrawEnable;
67982 lodash.each(services, function(service) {
67983 if (service && typeof service.init === 'function') {
67984 service.init(context);
67990 areaKeys = presets.areaKeys();
67993 return utilRebind(context, dispatch$$1, 'on');
67996 function osmWay() {
67997 if (!(this instanceof osmWay)) {
67998 return (new osmWay()).initialize(arguments);
67999 } else if (arguments.length) {
68000 this.initialize(arguments);
68005 osmEntity$$1.way = osmWay;
68007 osmWay.prototype = Object.create(osmEntity$$1.prototype);
68010 lodash.extend(osmWay.prototype, {
68015 copy: function(resolver, copies) {
68016 if (copies[this.id])
68017 return copies[this.id];
68019 var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
68021 var nodes = this.nodes.map(function(id) {
68022 return resolver.entity(id).copy(resolver, copies).id;
68025 copy = copy.update({ nodes: nodes });
68026 copies[this.id] = copy;
68032 extent: function(resolver) {
68033 return resolver.transient(this, 'extent', function() {
68034 var extent$$1 = geoExtent$$1();
68035 for (var i = 0; i < this.nodes.length; i++) {
68036 var node = resolver.hasEntity(this.nodes[i]);
68038 extent$$1._extend(node.extent());
68046 first: function() {
68047 return this.nodes[0];
68052 return this.nodes[this.nodes.length - 1];
68056 contains: function(node) {
68057 return this.nodes.indexOf(node) >= 0;
68061 affix: function(node) {
68062 if (this.nodes[0] === node) return 'prefix';
68063 if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
68067 layer: function() {
68068 // explicit layer tag, clamp between -10, 10..
68069 if (isFinite(this.tags.layer)) {
68070 return Math.max(-10, Math.min(+(this.tags.layer), 10));
68073 // implied layer tag..
68074 if (this.tags.location === 'overground') return 1;
68075 if (this.tags.location === 'underground') return -1;
68076 if (this.tags.location === 'underwater') return -10;
68078 if (this.tags.power === 'line') return 10;
68079 if (this.tags.power === 'minor_line') return 10;
68080 if (this.tags.aerialway) return 10;
68081 if (this.tags.bridge) return 1;
68082 if (this.tags.cutting) return -1;
68083 if (this.tags.tunnel) return -1;
68084 if (this.tags.waterway) return -1;
68085 if (this.tags.man_made === 'pipeline') return -10;
68086 if (this.tags.boundary) return -10;
68091 isOneWay: function() {
68092 // explicit oneway tag..
68093 if (['yes', '1', '-1'].indexOf(this.tags.oneway) !== -1) { return true; }
68094 if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; }
68096 // implied oneway tag..
68097 for (var key in this.tags) {
68098 if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
68105 lanes: function() {
68106 return osmLanes(this);
68110 isClosed: function() {
68111 return this.nodes.length > 1 && this.first() === this.last();
68115 isConvex: function(resolver) {
68116 if (!this.isClosed() || this.isDegenerate()) return null;
68118 var nodes = lodash.uniq(resolver.childNodes(this)),
68119 coords = lodash.map(nodes, 'loc'),
68120 curr = 0, prev = 0;
68122 for (var i = 0; i < coords.length; i++) {
68123 var o = coords[(i+1) % coords.length],
68125 b = coords[(i+2) % coords.length],
68126 res = geoCross(o, a, b);
68128 curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
68131 } else if (prev && curr !== prev) {
68140 isArea: function() {
68141 if (this.tags.area === 'yes')
68143 if (!this.isClosed() || this.tags.area === 'no')
68145 for (var key in this.tags) {
68146 if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
68154 isDegenerate: function() {
68155 return lodash.uniq(this.nodes).length < (this.isArea() ? 3 : 2);
68159 areAdjacent: function(n1, n2) {
68160 for (var i = 0; i < this.nodes.length; i++) {
68161 if (this.nodes[i] === n1) {
68162 if (this.nodes[i - 1] === n2) return true;
68163 if (this.nodes[i + 1] === n2) return true;
68170 geometry: function(graph) {
68171 return graph.transient(this, 'geometry', function() {
68172 return this.isArea() ? 'area' : 'line';
68177 // If this way is not closed, append the beginning node to the end of the nodelist to close it.
68178 close: function() {
68179 if (this.isClosed() || !this.nodes.length) return this;
68181 var nodes = this.nodes.slice();
68182 nodes = nodes.filter(noRepeatNodes);
68183 nodes.push(nodes[0]);
68184 return this.update({ nodes: nodes });
68188 // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
68189 unclose: function() {
68190 if (!this.isClosed()) return this;
68192 var nodes = this.nodes.slice(),
68193 connector = this.first(),
68194 i = nodes.length - 1;
68196 // remove trailing connectors..
68197 while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68198 nodes.splice(i, 1);
68199 i = nodes.length - 1;
68202 nodes = nodes.filter(noRepeatNodes);
68203 return this.update({ nodes: nodes });
68207 // Adds a node (id) in front of the node which is currently at position index.
68208 // If index is undefined, the node will be added to the end of the way for linear ways,
68209 // or just before the final connecting node for circular ways.
68210 // Consecutive duplicates are eliminated including existing ones.
68211 // Circularity is always preserved when adding a node.
68212 addNode: function(id, index) {
68213 var nodes = this.nodes.slice(),
68214 isClosed = this.isClosed(),
68215 max$$1 = isClosed ? nodes.length - 1 : nodes.length;
68217 if (index === undefined) {
68221 if (index < 0 || index > max$$1) {
68222 throw new RangeError('index ' + index + ' out of range 0..' + max$$1);
68225 // If this is a closed way, remove all connector nodes except the first one
68226 // (there may be duplicates) and adjust index if necessary..
68228 var connector = this.first();
68230 // leading connectors..
68232 while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
68233 nodes.splice(i, 1);
68234 if (index > i) index--;
68237 // trailing connectors..
68238 i = nodes.length - 1;
68239 while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68240 nodes.splice(i, 1);
68241 if (index > i) index--;
68242 i = nodes.length - 1;
68246 nodes.splice(index, 0, id);
68247 nodes = nodes.filter(noRepeatNodes);
68249 // If the way was closed before, append a connector node to keep it closed..
68250 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68251 nodes.push(nodes[0]);
68254 return this.update({ nodes: nodes });
68258 // Replaces the node which is currently at position index with the given node (id).
68259 // Consecutive duplicates are eliminated including existing ones.
68260 // Circularity is preserved when updating a node.
68261 updateNode: function(id, index) {
68262 var nodes = this.nodes.slice(),
68263 isClosed = this.isClosed(),
68264 max$$1 = nodes.length - 1;
68266 if (index === undefined || index < 0 || index > max$$1) {
68267 throw new RangeError('index ' + index + ' out of range 0..' + max$$1);
68270 // If this is a closed way, remove all connector nodes except the first one
68271 // (there may be duplicates) and adjust index if necessary..
68273 var connector = this.first();
68275 // leading connectors..
68277 while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
68278 nodes.splice(i, 1);
68279 if (index > i) index--;
68282 // trailing connectors..
68283 i = nodes.length - 1;
68284 while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68285 nodes.splice(i, 1);
68286 if (index === i) index = 0; // update leading connector instead
68287 i = nodes.length - 1;
68291 nodes.splice(index, 1, id);
68292 nodes = nodes.filter(noRepeatNodes);
68294 // If the way was closed before, append a connector node to keep it closed..
68295 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68296 nodes.push(nodes[0]);
68299 return this.update({nodes: nodes});
68303 // Replaces each occurrence of node id needle with replacement.
68304 // Consecutive duplicates are eliminated including existing ones.
68305 // Circularity is preserved.
68306 replaceNode: function(needle, replacement) {
68307 var nodes = this.nodes.slice(),
68308 isClosed = this.isClosed();
68310 for (var i = 0; i < nodes.length; i++) {
68311 if (nodes[i] === needle) {
68312 nodes[i] = replacement;
68316 nodes = nodes.filter(noRepeatNodes);
68318 // If the way was closed before, append a connector node to keep it closed..
68319 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68320 nodes.push(nodes[0]);
68323 return this.update({nodes: nodes});
68327 // Removes each occurrence of node id needle with replacement.
68328 // Consecutive duplicates are eliminated including existing ones.
68329 // Circularity is preserved.
68330 removeNode: function(id) {
68331 var nodes = this.nodes.slice(),
68332 isClosed = this.isClosed();
68335 .filter(function(node) { return node !== id; })
68336 .filter(noRepeatNodes);
68338 // If the way was closed before, append a connector node to keep it closed..
68339 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68340 nodes.push(nodes[0]);
68343 return this.update({nodes: nodes});
68347 asJXON: function(changeset_id) {
68350 '@id': this.osmId(),
68351 '@version': this.version || 0,
68352 nd: lodash.map(this.nodes, function(id) {
68353 return { keyAttributes: { ref: osmEntity$$1.id.toOSM(id) } };
68355 tag: lodash.map(this.tags, function(v, k) {
68356 return { keyAttributes: { k: k, v: v } };
68360 if (changeset_id) {
68361 r.way['@changeset'] = changeset_id;
68367 asGeoJSON: function(resolver) {
68368 return resolver.transient(this, 'GeoJSON', function() {
68369 var coordinates = lodash.map(resolver.childNodes(this), 'loc');
68370 if (this.isArea() && this.isClosed()) {
68373 coordinates: [coordinates]
68377 type: 'LineString',
68378 coordinates: coordinates
68385 area: function(resolver) {
68386 return resolver.transient(this, 'area', function() {
68387 var nodes = resolver.childNodes(this);
68391 coordinates: [lodash.map(nodes, 'loc')]
68394 if (!this.isClosed() && nodes.length) {
68395 json$$1.coordinates[0].push(nodes[0].loc);
68398 var area$$1 = area(json$$1);
68400 // Heuristic for detecting counterclockwise winding order. Assumes
68401 // that OpenStreetMap polygons are not hemisphere-spanning.
68402 if (area$$1 > 2 * Math.PI) {
68403 json$$1.coordinates[0] = json$$1.coordinates[0].reverse();
68404 area$$1 = area(json$$1);
68407 return isNaN(area$$1) ? 0 : area$$1;
68413 // Filter function to eliminate consecutive duplicates.
68414 function noRepeatNodes(node, i, arr) {
68415 return i === 0 || node !== arr[i - 1];
68418 function osmTurn(turn) {
68419 if (!(this instanceof osmTurn))
68420 return new osmTurn(turn);
68421 lodash.extend(this, turn);
68425 function osmIntersection(graph, vertexId) {
68426 var vertex = graph.entity(vertexId),
68427 parentWays = graph.parentWays(vertex),
68431 function addHighway(way, adjacentNodeId) {
68432 if (highways[adjacentNodeId]) {
68433 coincident.push(adjacentNodeId);
68435 highways[adjacentNodeId] = way;
68439 // Pre-split ways that would need to be split in
68440 // order to add a restriction. The real split will
68441 // happen when the restriction is added.
68442 parentWays.forEach(function(way) {
68443 if (!way.tags.highway || way.isArea() || way.isDegenerate())
68446 var isFirst = (vertexId === way.first()),
68447 isLast = (vertexId === way.last()),
68448 isAffix = (isFirst || isLast),
68449 isClosingNode = (isFirst && isLast);
68451 if (isAffix && !isClosingNode) {
68452 var index = (isFirst ? 1 : way.nodes.length - 2);
68453 addHighway(way, way.nodes[index]);
68456 var splitIndex, wayA, wayB, indexA, indexB;
68457 if (isClosingNode) {
68458 splitIndex = Math.ceil(way.nodes.length / 2); // split at midpoint
68459 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
68460 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
68462 indexB = way.nodes.length - 2;
68464 splitIndex = lodash.indexOf(way.nodes, vertex.id, 1); // split at vertexid
68465 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
68466 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
68467 indexA = splitIndex - 1;
68468 indexB = splitIndex + 1;
68470 graph = graph.replace(wayA).replace(wayB);
68471 addHighway(wayA, way.nodes[indexA]);
68472 addHighway(wayB, way.nodes[indexB]);
68476 // remove any ways from this intersection that are coincident
68477 // (i.e. any adjacent node used by more than one intersecting way)
68478 coincident.forEach(function (n) {
68479 delete highways[n];
68483 var intersection = {
68484 highways: highways,
68485 ways: lodash.values(highways),
68490 intersection.adjacentNodeId = function(fromWayId) {
68491 return lodash.find(lodash.keys(highways), function(k) {
68492 return highways[k].id === fromWayId;
68497 intersection.turns = function(fromNodeId) {
68498 var start = highways[fromNodeId];
68502 if (start.first() === vertex.id && start.tags.oneway === 'yes')
68504 if (start.last() === vertex.id && start.tags.oneway === '-1')
68507 function withRestriction(turn) {
68508 graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
68509 if (relation.tags.type !== 'restriction')
68512 var f = relation.memberByRole('from'),
68513 t = relation.memberByRole('to'),
68514 v = relation.memberByRole('via');
68516 if (f && f.id === turn.from.way &&
68517 v && v.id === turn.via.node &&
68518 t && t.id === turn.to.way) {
68519 turn.restriction = relation.id;
68520 } else if (/^only_/.test(relation.tags.restriction) &&
68521 f && f.id === turn.from.way &&
68522 v && v.id === turn.via.node &&
68523 t && t.id !== turn.to.way) {
68524 turn.restriction = relation.id;
68525 turn.indirect_restriction = true;
68529 return osmTurn(turn);
68535 way: start.id.split(/-(a|b)/)[0]
68537 via = { node: vertex.id },
68540 lodash.each(highways, function(end, adjacentNodeId) {
68545 if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
68546 turns.push(withRestriction({
68550 node: adjacentNodeId,
68551 way: end.id.split(/-(a|b)/)[0]
68557 if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
68558 turns.push(withRestriction({
68562 node: adjacentNodeId,
68563 way: end.id.split(/-(a|b)/)[0]
68571 if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
68572 turns.push(withRestriction({
68583 return intersection;
68587 function osmInferRestriction(graph, from, via, to, projection) {
68588 var fromWay = graph.entity(from.way),
68589 fromNode = graph.entity(from.node),
68590 toWay = graph.entity(to.way),
68591 toNode = graph.entity(to.node),
68592 viaNode = graph.entity(via.node),
68593 fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
68594 (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
68595 toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
68596 (toWay.tags.oneway === '-1' && toWay.last() === via.node),
68597 angle = geoAngle(viaNode, fromNode, projection) -
68598 geoAngle(viaNode, toNode, projection);
68600 angle = angle * 180 / Math.PI;
68605 if (fromNode === toNode)
68606 return 'no_u_turn';
68607 if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
68608 return 'no_u_turn';
68610 return 'no_right_turn';
68612 return 'no_left_turn';
68614 return 'no_straight_on';
68617 function actionAddMember(relationId, member, memberIndex) {
68618 return function(graph) {
68619 var relation = graph.entity(relationId);
68621 if (isNaN(memberIndex) && member.type === 'way') {
68622 var members = relation.indexedMembers();
68623 members.push(member);
68625 var joined = osmJoinWays(members, graph);
68626 for (var i = 0; i < joined.length; i++) {
68627 var segment = joined[i];
68628 for (var j = 0; j < segment.length && segment.length >= 2; j++) {
68629 if (segment[j] !== member)
68633 memberIndex = segment[j + 1].index;
68634 } else if (j === segment.length - 1) {
68635 memberIndex = segment[j - 1].index + 1;
68637 memberIndex = Math.min(segment[j - 1].index + 1, segment[j + 1].index + 1);
68643 return graph.replace(relation.addMember(member, memberIndex));
68647 function actionAddMidpoint(midpoint, node) {
68648 return function(graph) {
68649 graph = graph.replace(node.move(midpoint.loc));
68651 var parents = lodash.intersection(
68652 graph.parentWays(graph.entity(midpoint.edge[0])),
68653 graph.parentWays(graph.entity(midpoint.edge[1])));
68655 parents.forEach(function(way) {
68656 for (var i = 0; i < way.nodes.length - 1; i++) {
68657 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
68658 graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
68660 // Add only one midpoint on doubled-back segments,
68661 // turning them into self-intersections.
68671 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
68672 function actionAddVertex(wayId, nodeId, index) {
68673 return function(graph) {
68674 return graph.replace(graph.entity(wayId).addNode(nodeId, index));
68678 function actionChangeMember(relationId, member, memberIndex) {
68679 return function(graph) {
68680 return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
68684 function actionChangePreset(entityId, oldPreset, newPreset) {
68685 return function(graph) {
68686 var entity = graph.entity(entityId),
68687 geometry = entity.geometry(graph),
68688 tags = entity.tags;
68690 if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
68691 if (newPreset) tags = newPreset.applyTags(tags, geometry);
68693 return graph.replace(entity.update({tags: tags}));
68697 function actionChangeTags(entityId, tags) {
68698 return function(graph) {
68699 var entity = graph.entity(entityId);
68700 return graph.replace(entity.update({tags: tags}));
68704 function actionCircularize(wayId, projection, maxAngle) {
68705 maxAngle = (maxAngle || 20) * Math.PI / 180;
68708 var action = function(graph, t) {
68709 if (t === null || !isFinite(t)) t = 1;
68710 t = Math.min(Math.max(+t, 0), 1);
68712 var way = graph.entity(wayId),
68715 graph.childNodes(way).forEach(function(node) {
68716 if (!origNodes[node.id]) origNodes[node.id] = node;
68719 if (!way.isConvex(graph)) {
68720 graph = action.makeConvex(graph);
68723 var nodes = lodash.uniq(graph.childNodes(way)),
68724 keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
68725 points = nodes.map(function(n) { return projection(n.loc); }),
68726 keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
68727 centroid = (points.length === 2) ? geoInterp(points[0], points[1], 0.5) : d3polygonCentroid(points),
68728 radius = median(points, function(p) { return geoEuclideanDistance(centroid, p); }),
68729 sign = d3polygonArea(points) > 0 ? 1 : -1,
68732 // we need atleast two key nodes for the algorithm to work
68733 if (!keyNodes.length) {
68734 keyNodes = [nodes[0]];
68735 keyPoints = [points[0]];
68738 if (keyNodes.length === 1) {
68739 var index = nodes.indexOf(keyNodes[0]),
68740 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
68742 keyNodes.push(nodes[oppositeIndex]);
68743 keyPoints.push(points[oppositeIndex]);
68746 // key points and nodes are those connected to the ways,
68747 // they are projected onto the circle, inbetween nodes are moved
68748 // to constant intervals between key nodes, extra inbetween nodes are
68749 // added if necessary.
68750 for (var i = 0; i < keyPoints.length; i++) {
68751 var nextKeyNodeIndex = (i + 1) % keyNodes.length,
68752 startNode = keyNodes[i],
68753 endNode = keyNodes[nextKeyNodeIndex],
68754 startNodeIndex = nodes.indexOf(startNode),
68755 endNodeIndex = nodes.indexOf(endNode),
68756 numberNewPoints = -1,
68757 indexRange = endNodeIndex - startNodeIndex,
68759 inBetweenNodes = [],
68760 startAngle, endAngle, totalAngle, eachAngle,
68761 angle, loc, node, origNode, j;
68763 if (indexRange < 0) {
68764 indexRange += nodes.length;
68767 // position this key node
68768 var distance = geoEuclideanDistance(centroid, keyPoints[i]);
68769 if (distance === 0) { distance = 1e-4; }
68771 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
68772 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius
68774 loc = projection.invert(keyPoints[i]);
68775 node = keyNodes[i];
68776 origNode = origNodes[node.id];
68777 node = node.move(geoInterp(origNode.loc, loc, t));
68778 graph = graph.replace(node);
68780 // figure out the between delta angle we want to match to
68781 startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
68782 endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
68783 totalAngle = endAngle - startAngle;
68785 // detects looping around -pi/pi
68786 if (totalAngle * sign > 0) {
68787 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
68792 eachAngle = totalAngle / (indexRange + numberNewPoints);
68793 } while (Math.abs(eachAngle) > maxAngle);
68796 // move existing nodes
68797 for (j = 1; j < indexRange; j++) {
68798 angle = startAngle + j * eachAngle;
68799 loc = projection.invert([
68800 centroid[0] + Math.cos(angle) * radius,
68801 centroid[1] + Math.sin(angle) * radius
68804 node = nodes[(j + startNodeIndex) % nodes.length];
68805 origNode = origNodes[node.id];
68806 nearNodes[node.id] = angle;
68808 node = node.move(geoInterp(origNode.loc, loc, t));
68809 graph = graph.replace(node);
68812 // add new inbetween nodes if necessary
68813 for (j = 0; j < numberNewPoints; j++) {
68814 angle = startAngle + (indexRange + j) * eachAngle;
68815 loc = projection.invert([
68816 centroid[0] + Math.cos(angle) * radius,
68817 centroid[1] + Math.sin(angle) * radius
68820 // choose a nearnode to use as the original
68821 var min$$1 = Infinity;
68822 for (var nodeId in nearNodes) {
68823 var nearAngle = nearNodes[nodeId],
68824 dist = Math.abs(nearAngle - angle);
68825 if (dist < min$$1) {
68827 origNode = origNodes[nodeId];
68831 node = osmNode({ loc: geoInterp(origNode.loc, loc, t) });
68832 graph = graph.replace(node);
68834 nodes.splice(endNodeIndex + j, 0, node);
68835 inBetweenNodes.push(node.id);
68838 // Check for other ways that share these keyNodes..
68839 // If keyNodes are adjacent in both ways,
68840 // we can add inBetween nodes to that shared way too..
68841 if (indexRange === 1 && inBetweenNodes.length) {
68842 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
68843 endIndex1 = way.nodes.lastIndexOf(endNode.id),
68844 wayDirection1 = (endIndex1 - startIndex1);
68845 if (wayDirection1 < -1) { wayDirection1 = 1; }
68847 /* eslint-disable no-loop-func */
68848 lodash.each(lodash.without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
68849 if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
68850 var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
68851 endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
68852 wayDirection2 = (endIndex2 - startIndex2),
68853 insertAt = endIndex2;
68854 if (wayDirection2 < -1) { wayDirection2 = 1; }
68856 if (wayDirection1 !== wayDirection2) {
68857 inBetweenNodes.reverse();
68858 insertAt = startIndex2;
68860 for (j = 0; j < inBetweenNodes.length; j++) {
68861 sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
68863 graph = graph.replace(sharedWay);
68866 /* eslint-enable no-loop-func */
68871 // update the way to have all the new nodes
68872 ids = nodes.map(function(n) { return n.id; });
68875 way = way.update({nodes: ids});
68876 graph = graph.replace(way);
68882 action.makeConvex = function(graph) {
68883 var way = graph.entity(wayId),
68884 nodes = lodash.uniq(graph.childNodes(way)),
68885 points = nodes.map(function(n) { return projection(n.loc); }),
68886 sign = d3polygonArea(points) > 0 ? 1 : -1,
68887 hull = d3polygonHull(points);
68889 // D3 convex hulls go counterclockwise..
68895 for (var i = 0; i < hull.length - 1; i++) {
68896 var startIndex = points.indexOf(hull[i]),
68897 endIndex = points.indexOf(hull[i+1]),
68898 indexRange = (endIndex - startIndex);
68900 if (indexRange < 0) {
68901 indexRange += nodes.length;
68904 // move interior nodes to the surface of the convex hull..
68905 for (var j = 1; j < indexRange; j++) {
68906 var point = geoInterp(hull[i], hull[i+1], j / indexRange),
68907 node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
68908 graph = graph.replace(node);
68915 action.disabled = function(graph) {
68916 if (!graph.entity(wayId).isClosed())
68917 return 'not_closed';
68921 action.transitionable = true;
68927 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
68928 function actionDeleteWay(wayId) {
68931 function canDeleteNode(node, graph) {
68932 return !graph.parentWays(node).length &&
68933 !graph.parentRelations(node).length &&
68934 !node.hasInterestingTags();
68938 var action = function(graph) {
68939 var way = graph.entity(wayId);
68941 graph.parentRelations(way)
68942 .forEach(function(parent) {
68943 parent = parent.removeMembersWithID(wayId);
68944 graph = graph.replace(parent);
68946 if (parent.isDegenerate()) {
68947 graph = actionDeleteRelation(parent.id)(graph);
68951 lodash.uniq(way.nodes).forEach(function(nodeId) {
68952 graph = graph.replace(way.removeNode(nodeId));
68954 var node = graph.entity(nodeId);
68955 if (canDeleteNode(node, graph)) {
68956 graph = graph.remove(node);
68960 return graph.remove(way);
68967 function actionDeleteMultiple(ids) {
68969 way: actionDeleteWay,
68970 node: actionDeleteNode,
68971 relation: actionDeleteRelation
68975 var action = function(graph) {
68976 ids.forEach(function(id) {
68977 if (graph.hasEntity(id)) { // It may have been deleted aready.
68978 graph = actions[graph.entity(id).type](id)(graph);
68989 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
68990 function actionDeleteRelation(relationId) {
68993 function canDeleteEntity(entity, graph) {
68994 return !graph.parentWays(entity).length &&
68995 !graph.parentRelations(entity).length &&
68996 !entity.hasInterestingTags();
69000 var action = function(graph) {
69001 var relation = graph.entity(relationId);
69003 graph.parentRelations(relation)
69004 .forEach(function(parent) {
69005 parent = parent.removeMembersWithID(relationId);
69006 graph = graph.replace(parent);
69008 if (parent.isDegenerate()) {
69009 graph = actionDeleteRelation(parent.id)(graph);
69013 lodash.uniq(lodash.map(relation.members, 'id')).forEach(function(memberId) {
69014 graph = graph.replace(relation.removeMembersWithID(memberId));
69016 var entity = graph.entity(memberId);
69017 if (canDeleteEntity(entity, graph)) {
69018 graph = actionDeleteMultiple([memberId])(graph);
69022 return graph.remove(relation);
69029 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
69030 function actionDeleteNode(nodeId) {
69031 var action = function(graph) {
69032 var node = graph.entity(nodeId);
69034 graph.parentWays(node)
69035 .forEach(function(parent) {
69036 parent = parent.removeNode(nodeId);
69037 graph = graph.replace(parent);
69039 if (parent.isDegenerate()) {
69040 graph = actionDeleteWay(parent.id)(graph);
69044 graph.parentRelations(node)
69045 .forEach(function(parent) {
69046 parent = parent.removeMembersWithID(nodeId);
69047 graph = graph.replace(parent);
69049 if (parent.isDegenerate()) {
69050 graph = actionDeleteRelation(parent.id)(graph);
69054 return graph.remove(node);
69061 // Connect the ways at the given nodes.
69063 // The last node will survive. All other nodes will be replaced with
69064 // the surviving node in parent ways, and then removed.
69066 // Tags and relation memberships of of non-surviving nodes are merged
69067 // to the survivor.
69069 // This is the inverse of `iD.actionDisconnect`.
69072 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
69073 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
69075 function actionConnect(nodeIds) {
69076 return function(graph) {
69077 var survivor = graph.entity(lodash.last(nodeIds));
69079 for (var i = 0; i < nodeIds.length - 1; i++) {
69080 var node = graph.entity(nodeIds[i]);
69082 /* eslint-disable no-loop-func */
69083 graph.parentWays(node).forEach(function(parent) {
69084 if (!parent.areAdjacent(node.id, survivor.id)) {
69085 graph = graph.replace(parent.replaceNode(node.id, survivor.id));
69089 graph.parentRelations(node).forEach(function(parent) {
69090 graph = graph.replace(parent.replaceMember(node, survivor));
69092 /* eslint-enable no-loop-func */
69094 survivor = survivor.mergeTags(node.tags);
69095 graph = actionDeleteNode(node.id)(graph);
69098 graph = graph.replace(survivor);
69104 function actionCopyEntities(ids, fromGraph) {
69108 var action = function(graph) {
69109 ids.forEach(function(id) {
69110 fromGraph.entity(id).copy(fromGraph, copies);
69113 for (var id in copies) {
69114 graph = graph.replace(copies[id]);
69121 action.copies = function() {
69129 function actionDeleteMember(relationId, memberIndex) {
69130 return function(graph) {
69131 var relation = graph.entity(relationId)
69132 .removeMember(memberIndex);
69134 graph = graph.replace(relation);
69136 if (relation.isDegenerate())
69137 graph = actionDeleteRelation(relation.id)(graph);
69143 function actionDeprecateTags(entityId) {
69145 return function(graph) {
69146 var entity = graph.entity(entityId),
69147 newtags = lodash.clone(entity.tags),
69151 // This handles dataDeprecated tags with a single condition
69152 for (var i = 0; i < dataDeprecated.length; i++) {
69154 rule = dataDeprecated[i];
69155 var match = lodash.toPairs(rule.old)[0],
69156 replacements = rule.replace ? lodash.toPairs(rule.replace) : null;
69158 if (entity.tags[match[0]] && match[1] === '*') {
69160 var value = entity.tags[match[0]];
69161 if (replacements && !newtags[replacements[0][0]]) {
69162 newtags[replacements[0][0]] = value;
69164 delete newtags[match[0]];
69167 } else if (entity.tags[match[0]] === match[1]) {
69168 newtags = lodash.assign({}, rule.replace || {}, lodash.omit(newtags, match[0]));
69174 return graph.replace(entity.update({tags: newtags}));
69181 function actionDiscardTags(difference) {
69183 return function(graph) {
69184 function discardTags(entity) {
69185 if (!lodash.isEmpty(entity.tags)) {
69187 lodash.each(entity.tags, function(v, k) {
69188 if (v) tags[k] = v;
69191 graph = graph.replace(entity.update({
69192 tags: lodash.omit(tags, dataDiscarded)
69197 difference.modified().forEach(discardTags);
69198 difference.created().forEach(discardTags);
69204 // Disconect the ways at the given node.
69206 // Optionally, disconnect only the given ways.
69208 // For testing convenience, accepts an ID to assign to the (first) new node.
69209 // Normally, this will be undefined and the way will automatically
69210 // be assigned a new ID.
69212 // This is the inverse of `iD.actionConnect`.
69215 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
69216 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
69218 function actionDisconnect(nodeId, newNodeId) {
69222 var action = function(graph) {
69223 var node = graph.entity(nodeId),
69224 connections = action.connections(graph);
69226 connections.forEach(function(connection) {
69227 var way = graph.entity(connection.wayID),
69228 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
69230 graph = graph.replace(newNode);
69231 if (connection.index === 0 && way.isArea()) {
69232 // replace shared node with shared node..
69233 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
69234 } else if (way.isClosed() && connection.index === way.nodes.length - 1) {
69235 // replace closing node with new new node..
69236 graph = graph.replace(way.unclose().addNode(newNode.id));
69238 // replace shared node with multiple new nodes..
69239 graph = graph.replace(way.updateNode(newNode.id, connection.index));
69247 action.connections = function(graph) {
69248 var candidates = [],
69250 parentWays = graph.parentWays(graph.entity(nodeId));
69252 parentWays.forEach(function(way) {
69253 if (wayIds && wayIds.indexOf(way.id) === -1) {
69257 if (way.isArea() && (way.nodes[0] === nodeId)) {
69258 candidates.push({ wayID: way.id, index: 0 });
69260 way.nodes.forEach(function(waynode, index) {
69261 if (waynode === nodeId) {
69262 candidates.push({ wayID: way.id, index: index });
69268 return keeping ? candidates : candidates.slice(1);
69272 action.disabled = function(graph) {
69273 var connections = action.connections(graph);
69274 if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
69275 return 'not_connected';
69277 var parentWays = graph.parentWays(graph.entity(nodeId)),
69278 seenRelationIds = {},
69281 parentWays.forEach(function(way) {
69282 if (wayIds && wayIds.indexOf(way.id) === -1)
69285 var relations = graph.parentRelations(way);
69286 relations.forEach(function(relation) {
69287 if (relation.id in seenRelationIds) {
69288 sharedRelation = relation;
69290 seenRelationIds[relation.id] = true;
69295 if (sharedRelation)
69300 action.limitWays = function(_) {
69301 if (!arguments.length) return wayIds;
69310 // Join ways at the end node they share.
69312 // This is the inverse of `iD.actionSplit`.
69315 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
69316 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
69318 function actionJoin(ids) {
69320 function groupEntitiesByGeometry(graph) {
69321 var entities = ids.map(function(id) { return graph.entity(id); });
69322 return lodash.extend({line: []}, lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
69326 var action = function(graph) {
69327 var ways = ids.map(graph.entity, graph),
69328 survivor = ways[0];
69330 // Prefer to keep an existing way.
69331 for (var i = 0; i < ways.length; i++) {
69332 if (!ways[i].isNew()) {
69333 survivor = ways[i];
69338 var joined = osmJoinWays(ways, graph)[0];
69340 survivor = survivor.update({nodes: lodash.map(joined.nodes, 'id')});
69341 graph = graph.replace(survivor);
69343 joined.forEach(function(way) {
69344 if (way.id === survivor.id)
69347 graph.parentRelations(way).forEach(function(parent) {
69348 graph = graph.replace(parent.replaceMember(way, survivor));
69351 survivor = survivor.mergeTags(way.tags);
69353 graph = graph.replace(survivor);
69354 graph = actionDeleteWay(way.id)(graph);
69361 action.disabled = function(graph) {
69362 var geometries = groupEntitiesByGeometry(graph);
69363 if (ids.length < 2 || ids.length !== geometries.line.length)
69364 return 'not_eligible';
69366 var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
69367 if (joined.length > 1)
69368 return 'not_adjacent';
69370 var nodeIds = lodash.map(joined[0].nodes, 'id').slice(1, -1),
69373 conflicting = false;
69375 joined[0].forEach(function(way) {
69376 var parents = graph.parentRelations(way);
69377 parents.forEach(function(parent) {
69378 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
69382 for (var k in way.tags) {
69383 if (!(k in tags)) {
69384 tags[k] = way.tags[k];
69385 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
69386 conflicting = true;
69392 return 'restriction';
69395 return 'conflicting_tags';
69402 function actionMerge(ids) {
69404 function groupEntitiesByGeometry(graph) {
69405 var entities = ids.map(function(id) { return graph.entity(id); });
69406 return lodash.extend({point: [], area: [], line: [], relation: []},
69407 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
69411 var action = function(graph) {
69412 var geometries = groupEntitiesByGeometry(graph),
69413 target = geometries.area[0] || geometries.line[0],
69414 points = geometries.point;
69416 points.forEach(function(point) {
69417 target = target.mergeTags(point.tags);
69418 graph = graph.replace(target);
69420 graph.parentRelations(point).forEach(function(parent) {
69421 graph = graph.replace(parent.replaceMember(point, target));
69424 var nodes = lodash.uniq(graph.childNodes(target)),
69425 removeNode = point;
69427 for (var i = 0; i < nodes.length; i++) {
69428 var node = nodes[i];
69429 if (graph.parentWays(node).length > 1 ||
69430 graph.parentRelations(node).length ||
69431 node.hasInterestingTags()) {
69435 // Found an uninteresting child node on the target way.
69436 // Move orig point into its place to preserve point's history. #3683
69437 graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
69438 target = target.replaceNode(node.id, point.id);
69439 graph = graph.replace(target);
69444 graph = graph.remove(removeNode);
69451 action.disabled = function(graph) {
69452 var geometries = groupEntitiesByGeometry(graph);
69453 if (geometries.point.length === 0 ||
69454 (geometries.area.length + geometries.line.length) !== 1 ||
69455 geometries.relation.length !== 0)
69456 return 'not_eligible';
69463 function actionMergePolygon(ids, newRelationId) {
69465 function groupEntities(graph) {
69466 var entities = ids.map(function (id) { return graph.entity(id); });
69467 return lodash.extend({
69471 }, lodash.groupBy(entities, function(entity) {
69472 if (entity.type === 'way' && entity.isClosed()) {
69473 return 'closedWay';
69474 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
69475 return 'multipolygon';
69483 var action = function(graph) {
69484 var entities = groupEntities(graph);
69486 // An array representing all the polygons that are part of the multipolygon.
69488 // Each element is itself an array of objects with an id property, and has a
69489 // locs property which is an array of the locations forming the polygon.
69490 var polygons = entities.multipolygon.reduce(function(polygons, m) {
69491 return polygons.concat(osmJoinWays(m.members, graph));
69492 }, []).concat(entities.closedWay.map(function(d) {
69493 var member = [{id: d.id}];
69494 member.nodes = graph.childNodes(d);
69498 // contained is an array of arrays of boolean values,
69499 // where contained[j][k] is true iff the jth way is
69500 // contained by the kth way.
69501 var contained = polygons.map(function(w, i) {
69502 return polygons.map(function(d, n) {
69503 if (i === n) return null;
69504 return geoPolygonContainsPolygon(
69505 lodash.map(d.nodes, 'loc'),
69506 lodash.map(w.nodes, 'loc'));
69510 // Sort all polygons as either outer or inner ways
69514 while (polygons.length) {
69515 extractUncontained(polygons);
69516 polygons = polygons.filter(isContained);
69517 contained = contained.filter(isContained).map(filterContained);
69520 function isContained(d, i) {
69521 return lodash.some(contained[i]);
69524 function filterContained(d) {
69525 return d.filter(isContained);
69528 function extractUncontained(polygons) {
69529 polygons.forEach(function(d, i) {
69530 if (!isContained(d, i)) {
69531 d.forEach(function(member) {
69535 role: outer ? 'outer' : 'inner'
69543 // Move all tags to one relation
69544 var relation = entities.multipolygon[0] ||
69545 osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
69547 entities.multipolygon.slice(1).forEach(function(m) {
69548 relation = relation.mergeTags(m.tags);
69549 graph = graph.remove(m);
69552 entities.closedWay.forEach(function(way) {
69553 function isThisOuter(m) {
69554 return m.id === way.id && m.role !== 'inner';
69556 if (members.some(isThisOuter)) {
69557 relation = relation.mergeTags(way.tags);
69558 graph = graph.replace(way.update({ tags: {} }));
69562 return graph.replace(relation.update({
69564 tags: lodash.omit(relation.tags, 'area')
69569 action.disabled = function(graph) {
69570 var entities = groupEntities(graph);
69571 if (entities.other.length > 0 ||
69572 entities.closedWay.length + entities.multipolygon.length < 2)
69573 return 'not_eligible';
69574 if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
69575 return 'incomplete_relation';
69582 // Copyright (c) 2006, 2008 Tony Garnock-Jones <tonyg@lshift.net>
69583 // Copyright (c) 2006, 2008 LShift Ltd. <query@lshift.net>
69585 // Permission is hereby granted, free of charge, to any person
69586 // obtaining a copy of this software and associated documentation files
69587 // (the "Software"), to deal in the Software without restriction,
69588 // including without limitation the rights to use, copy, modify, merge,
69589 // publish, distribute, sublicense, and/or sell copies of the Software,
69590 // and to permit persons to whom the Software is furnished to do so,
69591 // subject to the following conditions:
69593 // The above copyright notice and this permission notice shall be
69594 // included in all copies or substantial portions of the Software.
69596 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
69597 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
69598 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
69599 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
69600 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
69601 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
69602 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
69605 // source: https://bitbucket.org/lshift/synchrotron/src
69606 function longest_common_subsequence(file1, file2) {
69607 /* Text diff algorithm following Hunt and McIlroy 1976.
69608 * J. W. Hunt and M. D. McIlroy, An algorithm for differential file
69609 * comparison, Bell Telephone Laboratories CSTR #41 (1976)
69610 * http://www.cs.dartmouth.edu/~doug/
69612 * Expects two arrays of strings.
69614 var equivalenceClasses;
69619 var c, i, j, jX, r, s;
69621 equivalenceClasses = {};
69622 for (j = 0; j < file2.length; j++) {
69624 if (equivalenceClasses[line]) {
69625 equivalenceClasses[line].push(j);
69627 equivalenceClasses[line] = [j];
69631 candidates = [{file1index: -1,
69635 for (i = 0; i < file1.length; i++) {
69637 file2indices = equivalenceClasses[line] || [];
69642 for (jX = 0; jX < file2indices.length; jX++) {
69643 j = file2indices[jX];
69645 for (s = 0; s < candidates.length; s++) {
69646 if ((candidates[s].file2index < j) &&
69647 ((s === candidates.length - 1) ||
69648 (candidates[s + 1].file2index > j)))
69652 if (s < candidates.length) {
69653 newCandidate = {file1index: i,
69655 chain: candidates[s]};
69656 if (r === candidates.length) {
69657 candidates.push(c);
69663 if (r === candidates.length) {
69664 break; // no point in examining further (j)s
69672 // At this point, we know the LCS: it's in the reverse of the
69673 // linked-list through .chain of
69674 // candidates[candidates.length - 1].
69676 return candidates[candidates.length - 1];
69689 function diff_indices(file1, file2) {
69690 // We apply the LCS to give a simple representation of the
69691 // offsets and lengths of mismatched chunks in the input
69692 // files. This is used by diff3_merge_indices below.
69695 var tail1 = file1.length;
69696 var tail2 = file2.length;
69698 for (var candidate = longest_common_subsequence(file1, file2);
69699 candidate !== null;
69700 candidate = candidate.chain)
69702 var mismatchLength1 = tail1 - candidate.file1index - 1;
69703 var mismatchLength2 = tail2 - candidate.file2index - 1;
69704 tail1 = candidate.file1index;
69705 tail2 = candidate.file2index;
69707 if (mismatchLength1 || mismatchLength2) {
69708 result.push({file1: [tail1 + 1, mismatchLength1],
69709 file2: [tail2 + 1, mismatchLength2]});
69717 function diff3_merge_indices (a, o, b) {
69718 // Given three files, A, O, and B, where both A and B are
69719 // independently derived from O, returns a fairly complicated
69720 // internal representation of merge decisions it's taken. The
69721 // interested reader may wish to consult
69723 // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. "A
69724 // Formal Investigation of Diff3." In Arvind and Prasad,
69725 // editors, Foundations of Software Technology and Theoretical
69726 // Computer Science (FSTTCS), December 2007.
69728 // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
69731 var m1 = diff_indices(o, a);
69732 var m2 = diff_indices(o, b);
69735 function addHunk(h, side) {
69736 hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
69738 for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
69739 for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
69743 var commonOffset = 0;
69744 function copyCommon(targetOffset) {
69745 if (targetOffset > commonOffset) {
69746 result.push([1, commonOffset, targetOffset - commonOffset]);
69747 commonOffset = targetOffset;
69751 for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
69752 var firstHunkIndex = hunkIndex;
69753 var hunk = hunks[hunkIndex];
69754 var regionLhs = hunk[0];
69755 var regionRhs = regionLhs + hunk[2];
69756 while (hunkIndex < hunks.length - 1) {
69757 var maybeOverlapping = hunks[hunkIndex + 1];
69758 var maybeLhs = maybeOverlapping[0];
69759 if (maybeLhs > regionRhs) break;
69760 regionRhs = maybeLhs + maybeOverlapping[2];
69764 copyCommon(regionLhs);
69765 if (firstHunkIndex === hunkIndex) {
69766 // The "overlap" was only one hunk long, meaning that
69767 // there's no conflict here. Either a and o were the
69768 // same, or b and o were the same.
69770 result.push([hunk[1], hunk[3], hunk[4]]);
69773 // A proper conflict. Determine the extents of the
69774 // regions involved from a, o and b. Effectively merge
69775 // all the hunks on the left into one giant hunk, and
69776 // do the same for the right; then, correct for skew
69777 // in the regions of o that each side changed, and
69778 // report appropriate spans for the three sides.
69780 0: [a.length, -1, o.length, -1],
69781 2: [b.length, -1, o.length, -1]
69783 for (i = firstHunkIndex; i <= hunkIndex; i++) {
69785 var side = hunk[1];
69786 var r = regions[side];
69787 var oLhs = hunk[0];
69788 var oRhs = oLhs + hunk[2];
69789 var abLhs = hunk[3];
69790 var abRhs = abLhs + hunk[4];
69791 r[0] = Math.min(abLhs, r[0]);
69792 r[1] = Math.max(abRhs, r[1]);
69793 r[2] = Math.min(oLhs, r[2]);
69794 r[3] = Math.max(oRhs, r[3]);
69796 var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
69797 var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
69798 var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
69799 var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
69802 regionLhs, regionRhs - regionLhs,
69803 bLhs, bRhs - bLhs]);
69805 commonOffset = regionRhs;
69808 copyCommon(o.length);
69812 function diff3_merge (a, o, b, excludeFalseConflicts) {
69813 // Applies the output of Diff3.diff3_merge_indices to actually
69814 // construct the merged file; the returned result alternates
69815 // between "ok" and "conflict" blocks.
69818 var files = [a, o, b];
69819 var indices = diff3_merge_indices(a, o, b);
69822 function flushOk() {
69823 if (okLines.length) {
69824 result.push({ok: okLines});
69828 function pushOk(xs) {
69829 for (var j = 0; j < xs.length; j++) {
69830 okLines.push(xs[j]);
69834 function isTrueConflict(rec) {
69835 if (rec[2] !== rec[6]) return true;
69838 for (var j = 0; j < rec[2]; j++) {
69839 if (a[j + aoff] !== b[j + boff]) return true;
69844 for (var i = 0; i < indices.length; i++) {
69845 var x = indices[i];
69848 if (excludeFalseConflicts && !isTrueConflict(x)) {
69849 pushOk(files[0].slice(x[1], x[1] + x[2]));
69852 result.push({conflict: {a: a.slice(x[1], x[1] + x[2]),
69854 o: o.slice(x[3], x[3] + x[4]),
69856 b: b.slice(x[5], x[5] + x[6]),
69860 pushOk(files[side].slice(x[1], x[1] + x[2]));
69868 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
69869 var option = 'safe', // 'safe', 'force_local', 'force_remote'
69874 return lodash.isFunction(formatUser) ? formatUser(d) : d;
69878 function mergeLocation(remote, target) {
69879 function pointEqual(a, b) {
69880 var epsilon = 1e-6;
69881 return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
69884 if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
69887 if (option === 'force_remote') {
69888 return target.update({loc: remote.loc});
69891 conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
69896 function mergeNodes(base, remote, target) {
69897 if (option === 'force_local' || lodash.isEqual(target.nodes, remote.nodes)) {
69900 if (option === 'force_remote') {
69901 return target.update({nodes: remote.nodes});
69904 var ccount = conflicts.length,
69905 o = base.nodes || [],
69906 a = target.nodes || [],
69907 b = remote.nodes || [],
69909 hunks = diff3_merge(a, o, b, true);
69911 for (var i = 0; i < hunks.length; i++) {
69912 var hunk = hunks[i];
69914 nodes.push.apply(nodes, hunk.ok);
69916 // for all conflicts, we can assume c.a !== c.b
69917 // because `diff3_merge` called with `true` option to exclude false conflicts..
69918 var c = hunk.conflict;
69919 if (lodash.isEqual(c.o, c.a)) { // only changed remotely
69920 nodes.push.apply(nodes, c.b);
69921 } else if (lodash.isEqual(c.o, c.b)) { // only changed locally
69922 nodes.push.apply(nodes, c.a);
69923 } else { // changed both locally and remotely
69924 conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
69930 return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
69934 function mergeChildren(targetWay, children, updates, graph) {
69935 function isUsed(node, targetWay) {
69936 var parentWays = lodash.map(graph.parentWays(node), 'id');
69937 return node.hasInterestingTags() ||
69938 lodash.without(parentWays, targetWay.id).length > 0 ||
69939 graph.parentRelations(node).length > 0;
69942 var ccount = conflicts.length;
69944 for (var i = 0; i < children.length; i++) {
69945 var id = children[i],
69946 node = graph.hasEntity(id);
69948 // remove unused childNodes..
69949 if (targetWay.nodes.indexOf(id) === -1) {
69950 if (node && !isUsed(node, targetWay)) {
69951 updates.removeIds.push(id);
69956 // restore used childNodes..
69957 var local = localGraph.hasEntity(id),
69958 remote = remoteGraph.hasEntity(id),
69961 if (option === 'force_remote' && remote && remote.visible) {
69962 updates.replacements.push(remote);
69964 } else if (option === 'force_local' && local) {
69965 target = osmEntity$$1(local);
69967 target = target.update({ version: remote.version });
69969 updates.replacements.push(target);
69971 } else if (option === 'safe' && local && remote && local.version !== remote.version) {
69972 target = osmEntity$$1(local, { version: remote.version });
69973 if (remote.visible) {
69974 target = mergeLocation(remote, target);
69976 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
69979 if (conflicts.length !== ccount) break;
69980 updates.replacements.push(target);
69988 function updateChildren(updates, graph) {
69989 for (var i = 0; i < updates.replacements.length; i++) {
69990 graph = graph.replace(updates.replacements[i]);
69992 if (updates.removeIds.length) {
69993 graph = actionDeleteMultiple(updates.removeIds)(graph);
69999 function mergeMembers(remote, target) {
70000 if (option === 'force_local' || lodash.isEqual(target.members, remote.members)) {
70003 if (option === 'force_remote') {
70004 return target.update({members: remote.members});
70007 conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
70012 function mergeTags(base, remote, target) {
70013 function ignoreKey(k) {
70014 return lodash.includes(dataDiscarded, k);
70017 if (option === 'force_local' || lodash.isEqual(target.tags, remote.tags)) {
70020 if (option === 'force_remote') {
70021 return target.update({tags: remote.tags});
70024 var ccount = conflicts.length,
70025 o = base.tags || {},
70026 a = target.tags || {},
70027 b = remote.tags || {},
70028 keys = lodash.reject(lodash.union(lodash.keys(o), lodash.keys(a), lodash.keys(b)), ignoreKey),
70029 tags = lodash.clone(a),
70032 for (var i = 0; i < keys.length; i++) {
70035 if (o[k] !== b[k] && a[k] !== b[k]) { // changed remotely..
70036 if (o[k] !== a[k]) { // changed locally..
70037 conflicts.push(t('merge_remote_changes.conflict.tags',
70038 { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
70040 } else { // unchanged locally, accept remote change..
70041 if (b.hasOwnProperty(k)) {
70051 return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
70055 // `graph.base()` is the common ancestor of the two graphs.
70056 // `localGraph` contains user's edits up to saving
70057 // `remoteGraph` contains remote edits to modified nodes
70058 // `graph` must be a descendent of `localGraph` and may include
70059 // some conflict resolution actions performed on it.
70061 // --- ... --- `localGraph` -- ... -- `graph`
70063 // `graph.base()` --- ... --- `remoteGraph`
70065 var action = function(graph) {
70066 var updates = { replacements: [], removeIds: [] },
70067 base = graph.base().entities[id],
70068 local = localGraph.entity(id),
70069 remote = remoteGraph.entity(id),
70070 target = osmEntity$$1(local, { version: remote.version });
70073 if (!remote.visible) {
70074 if (option === 'force_remote') {
70075 return actionDeleteMultiple([id])(graph);
70077 } else if (option === 'force_local') {
70078 if (target.type === 'way') {
70079 target = mergeChildren(target, lodash.uniq(local.nodes), updates, graph);
70080 graph = updateChildren(updates, graph);
70082 return graph.replace(target);
70085 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
70086 return graph; // do nothing
70091 if (target.type === 'node') {
70092 target = mergeLocation(remote, target);
70094 } else if (target.type === 'way') {
70095 // pull in any child nodes that may not be present locally..
70096 graph.rebase(remoteGraph.childNodes(remote), [graph], false);
70097 target = mergeNodes(base, remote, target);
70098 target = mergeChildren(target, lodash.union(local.nodes, remote.nodes), updates, graph);
70100 } else if (target.type === 'relation') {
70101 target = mergeMembers(remote, target);
70104 target = mergeTags(base, remote, target);
70106 if (!conflicts.length) {
70107 graph = updateChildren(updates, graph).replace(target);
70114 action.withOption = function(opt) {
70120 action.conflicts = function() {
70128 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
70129 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
70130 function actionMove(moveIds, tryDelta, projection, cache) {
70131 var delta = tryDelta;
70133 function vecAdd(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
70134 function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
70136 function setupCache(graph) {
70137 function canMove(nodeId) {
70138 // Allow movement of any node that is in the selectedIDs list..
70139 if (moveIds.indexOf(nodeId) !== -1) return true;
70141 // Allow movement of a vertex where 2 ways meet..
70142 var parents = lodash.map(graph.parentWays(graph.entity(nodeId)), 'id');
70143 if (parents.length < 3) return true;
70145 // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
70146 var parentsMoving = lodash.every(parents, function(id) { return cache.moving[id]; });
70147 if (!parentsMoving) delete cache.moving[nodeId];
70149 return parentsMoving;
70152 function cacheEntities(ids) {
70153 ids.forEach(function(id) {
70154 if (cache.moving[id]) return;
70155 cache.moving[id] = true;
70157 var entity = graph.hasEntity(id);
70158 if (!entity) return;
70160 if (entity.type === 'node') {
70161 cache.nodes.push(id);
70162 cache.startLoc[id] = entity.loc;
70163 } else if (entity.type === 'way') {
70164 cache.ways.push(id);
70165 cacheEntities(entity.nodes);
70167 cacheEntities(entity.members.map(function(member) {
70174 function cacheIntersections(ids) {
70175 function isEndpoint(way, id) { return !way.isClosed() && !!way.affix(id); }
70177 ids.forEach(function(id) {
70178 // consider only intersections with 1 moved and 1 unmoved way.
70179 var childNodes = graph.childNodes(graph.entity(id));
70180 childNodes.forEach(function(node) {
70181 var parents = graph.parentWays(node);
70182 if (parents.length !== 2) return;
70184 var moved = graph.entity(id),
70185 unmoved = lodash.find(parents, function(way) { return !cache.moving[way.id]; });
70186 if (!unmoved) return;
70188 // exclude ways that are overly connected..
70189 if (lodash.intersection(moved.nodes, unmoved.nodes).length > 2) return;
70191 if (moved.isArea() || unmoved.isArea()) return;
70193 cache.intersection[node.id] = {
70196 unmovedId: unmoved.id,
70197 movedIsEP: isEndpoint(moved, node.id),
70198 unmovedIsEP: isEndpoint(unmoved, node.id)
70210 cache.intersection = {};
70211 cache.replacedVertex = {};
70212 cache.startLoc = {};
70216 cacheEntities(moveIds);
70217 cacheIntersections(cache.ways);
70218 cache.nodes = lodash.filter(cache.nodes, canMove);
70225 // Place a vertex where the moved vertex used to be, to preserve way shape..
70226 function replaceMovedVertex(nodeId, wayId, graph, delta) {
70227 var way = graph.entity(wayId),
70228 moved = graph.entity(nodeId),
70229 movedIndex = way.nodes.indexOf(nodeId),
70230 len, prevIndex, nextIndex;
70232 if (way.isClosed()) {
70233 len = way.nodes.length - 1;
70234 prevIndex = (movedIndex + len - 1) % len;
70235 nextIndex = (movedIndex + len + 1) % len;
70237 len = way.nodes.length;
70238 prevIndex = movedIndex - 1;
70239 nextIndex = movedIndex + 1;
70242 var prev = graph.hasEntity(way.nodes[prevIndex]),
70243 next = graph.hasEntity(way.nodes[nextIndex]);
70245 // Don't add orig vertex at endpoint..
70246 if (!prev || !next) return graph;
70248 var key = wayId + '_' + nodeId,
70249 orig = cache.replacedVertex[key];
70252 cache.replacedVertex[key] = orig;
70253 cache.startLoc[orig.id] = cache.startLoc[nodeId];
70258 start = projection(cache.startLoc[nodeId]);
70259 end = projection.invert(vecAdd(start, delta));
70261 end = cache.startLoc[nodeId];
70263 orig = orig.move(end);
70265 var angle = Math.abs(geoAngle(orig, prev, projection) -
70266 geoAngle(orig, next, projection)) * 180 / Math.PI;
70268 // Don't add orig vertex if it would just make a straight line..
70269 if (angle > 175 && angle < 185) return graph;
70271 // Don't add orig vertex if another point is already nearby (within 10m)
70272 if (geoSphericalDistance(prev.loc, orig.loc) < 10 ||
70273 geoSphericalDistance(orig.loc, next.loc) < 10) return graph;
70275 // moving forward or backward along way?
70276 var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
70277 p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
70278 d1 = geoPathLength(p1),
70279 d2 = geoPathLength(p2),
70280 insertAt = (d1 < d2) ? movedIndex : nextIndex;
70282 // moving around closed loop?
70283 if (way.isClosed() && insertAt === 0) insertAt = len;
70285 way = way.addNode(orig.id, insertAt);
70286 return graph.replace(orig).replace(way);
70290 // Reorder nodes around intersections that have moved..
70291 function unZorroIntersection(intersection, graph) {
70292 var vertex = graph.entity(intersection.nodeId),
70293 way1 = graph.entity(intersection.movedId),
70294 way2 = graph.entity(intersection.unmovedId),
70295 isEP1 = intersection.movedIsEP,
70296 isEP2 = intersection.unmovedIsEP;
70298 // don't move the vertex if it is the endpoint of both ways.
70299 if (isEP1 && isEP2) return graph;
70301 var nodes1 = lodash.without(graph.childNodes(way1), vertex),
70302 nodes2 = lodash.without(graph.childNodes(way2), vertex);
70304 if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
70305 if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
70307 var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection),
70308 edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection),
70311 // snap vertex to nearest edge (or some point between them)..
70312 if (!isEP1 && !isEP2) {
70313 var epsilon = 1e-4, maxIter = 10;
70314 for (var i = 0; i < maxIter; i++) {
70315 loc = geoInterp(edge1.loc, edge2.loc, 0.5);
70316 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
70317 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
70318 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
70320 } else if (!isEP1) {
70326 graph = graph.replace(vertex.move(loc));
70328 // if zorro happened, reorder nodes..
70329 if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
70330 way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
70331 graph = graph.replace(way1);
70333 if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
70334 way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
70335 graph = graph.replace(way2);
70342 function cleanupIntersections(graph) {
70343 lodash.each(cache.intersection, function(obj) {
70344 graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, delta);
70345 graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
70346 graph = unZorroIntersection(obj, graph);
70353 // check if moving way endpoint can cross an unmoved way, if so limit delta..
70354 function limitDelta(graph) {
70355 lodash.each(cache.intersection, function(obj) {
70356 // Don't limit movement if this is vertex joins 2 endpoints..
70357 if (obj.movedIsEP && obj.unmovedIsEP) return;
70358 // Don't limit movement if this vertex is not an endpoint anyway..
70359 if (!obj.movedIsEP) return;
70361 var node = graph.entity(obj.nodeId),
70362 start = projection(node.loc),
70363 end = vecAdd(start, delta),
70364 movedNodes = graph.childNodes(graph.entity(obj.movedId)),
70365 movedPath = lodash.map(lodash.map(movedNodes, 'loc'),
70366 function(loc) { return vecAdd(projection(loc), delta); }),
70367 unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)),
70368 unmovedPath = lodash.map(lodash.map(unmovedNodes, 'loc'), projection),
70369 hits = geoPathIntersections(movedPath, unmovedPath);
70371 for (var i = 0; i < hits.length; i++) {
70372 if (lodash.isEqual(hits[i], end)) continue;
70373 var edge = geoChooseEdge(unmovedNodes, end, projection);
70374 delta = vecSub(projection(edge.loc), start);
70380 var action = function(graph) {
70381 if (delta[0] === 0 && delta[1] === 0) return graph;
70385 if (!lodash.isEmpty(cache.intersection)) {
70389 lodash.each(cache.nodes, function(id) {
70390 var node = graph.entity(id),
70391 start = projection(node.loc),
70392 end = vecAdd(start, delta);
70393 graph = graph.replace(node.move(projection.invert(end)));
70396 if (!lodash.isEmpty(cache.intersection)) {
70397 graph = cleanupIntersections(graph);
70404 action.delta = function() {
70412 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
70413 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
70414 function actionMoveNode(nodeId, loc) {
70415 return function(graph) {
70416 return graph.replace(graph.entity(nodeId).move(loc));
70420 function actionNoop() {
70421 return function(graph) {
70427 * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
70429 function actionOrthogonalize(wayId, projection) {
70430 var threshold = 12, // degrees within right or straight to alter
70431 lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
70432 upperThreshold = Math.cos(threshold * Math.PI / 180);
70435 var action = function(graph, t) {
70436 if (t === null || !isFinite(t)) t = 1;
70437 t = Math.min(Math.max(+t, 0), 1);
70439 var way = graph.entity(wayId),
70440 nodes = graph.childNodes(way),
70441 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); }),
70442 corner = {i: 0, dotp: 1},
70444 node, loc, score, motions, i, j;
70446 if (points.length === 3) { // move only one vertex for right triangle
70447 for (i = 0; i < 1000; i++) {
70448 motions = points.map(calcMotion);
70449 points[corner.i] = addPoints(points[corner.i], motions[corner.i]);
70450 score = corner.dotp;
70451 if (score < epsilon) {
70456 node = graph.entity(nodes[corner.i].id);
70457 loc = projection.invert(points[corner.i]);
70458 graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
70462 originalPoints = lodash.clone(points);
70465 for (i = 0; i < 1000; i++) {
70466 motions = points.map(calcMotion);
70467 for (j = 0; j < motions.length; j++) {
70468 points[j] = addPoints(points[j],motions[j]);
70470 var newScore = squareness(points);
70471 if (newScore < score) {
70472 best = lodash.clone(points);
70475 if (score < epsilon) {
70482 for (i = 0; i < points.length; i++) {
70483 // only move the points that actually moved
70484 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
70485 loc = projection.invert(points[i]);
70486 node = graph.entity(nodes[i].id);
70487 graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
70491 // remove empty nodes on straight sections
70492 for (i = 0; t === 1 && i < points.length; i++) {
70493 node = graph.entity(nodes[i].id);
70495 if (graph.parentWays(node).length > 1 ||
70496 graph.parentRelations(node).length ||
70497 node.hasInterestingTags()) {
70501 var dotp = normalizedDotProduct(i, points);
70502 if (dotp < -1 + epsilon) {
70503 graph = actionDeleteNode(node.id)(graph);
70511 function calcMotion(b, i, array) {
70512 var a = array[(i - 1 + array.length) % array.length],
70513 c = array[(i + 1) % array.length],
70514 p = subtractPoints(a, b),
70515 q = subtractPoints(c, b),
70518 scale = 2 * Math.min(geoEuclideanDistance(p, [0, 0]), geoEuclideanDistance(q, [0, 0]));
70519 p = normalizePoint(p, 1.0);
70520 q = normalizePoint(q, 1.0);
70522 dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
70524 // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
70525 if (array.length > 3) {
70526 if (dotp < -0.707106781186547) {
70529 } else if (dotp && Math.abs(dotp) < corner.dotp) {
70531 corner.dotp = Math.abs(dotp);
70534 return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
70539 function squareness(points) {
70540 return points.reduce(function(sum, val, i, array) {
70541 var dotp = normalizedDotProduct(i, array);
70543 dotp = filterDotProduct(dotp);
70544 return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
70549 function normalizedDotProduct(i, points) {
70550 var a = points[(i - 1 + points.length) % points.length],
70552 c = points[(i + 1) % points.length],
70553 p = subtractPoints(a, b),
70554 q = subtractPoints(c, b);
70556 p = normalizePoint(p, 1.0);
70557 q = normalizePoint(q, 1.0);
70559 return p[0] * q[0] + p[1] * q[1];
70563 function subtractPoints(a, b) {
70564 return [a[0] - b[0], a[1] - b[1]];
70568 function addPoints(a, b) {
70569 return [a[0] + b[0], a[1] + b[1]];
70573 function normalizePoint(point, scale) {
70574 var vector = [0, 0];
70575 var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
70576 if (length !== 0) {
70577 vector[0] = point[0] / length;
70578 vector[1] = point[1] / length;
70581 vector[0] *= scale;
70582 vector[1] *= scale;
70588 function filterDotProduct(dotp) {
70589 if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
70597 action.disabled = function(graph) {
70598 var way = graph.entity(wayId),
70599 nodes = graph.childNodes(way),
70600 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); });
70602 if (squareness(points)) {
70606 return 'not_squarish';
70610 action.transitionable = true;
70616 // Split a way at the given node.
70618 // Optionally, split only the given ways, if multiple ways share
70621 // This is the inverse of `iD.actionJoin`.
70623 // For testing convenience, accepts an ID to assign to the new way.
70624 // Normally, this will be undefined and the way will automatically
70625 // be assigned a new ID.
70628 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
70630 function actionSplit(nodeId, newWayIds) {
70633 // if the way is closed, we need to search for a partner node
70634 // to split the way at.
70636 // The following looks for a node that is both far away from
70637 // the initial node in terms of way segment length and nearby
70638 // in terms of beeline-distance. This assures that areas get
70639 // split on the most "natural" points (independent of the number
70641 // For example: bone-shaped areas get split across their waist
70642 // line, circles across the diameter.
70643 function splitArea(nodes, idxA, graph) {
70644 var lengths = new Array(nodes.length),
70650 function wrap(index) {
70651 return utilWrap(index, nodes.length);
70654 function dist(nA, nB) {
70655 return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
70658 // calculate lengths
70660 for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
70661 length += dist(nodes[i], nodes[wrap(i-1)]);
70662 lengths[i] = length;
70666 for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
70667 length += dist(nodes[i], nodes[wrap(i+1)]);
70668 if (length < lengths[i])
70669 lengths[i] = length;
70672 // determine best opposite node to split
70673 for (i = 0; i < nodes.length; i++) {
70674 var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
70685 function split(graph, wayA, newWayId) {
70686 var wayB = osmWay({id: newWayId, tags: wayA.tags}),
70689 isArea = wayA.isArea(),
70690 isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
70692 if (wayA.isClosed()) {
70693 var nodes = wayA.nodes.slice(0, -1),
70694 idxA = lodash.indexOf(nodes, nodeId),
70695 idxB = splitArea(nodes, idxA, graph);
70698 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
70699 nodesB = nodes.slice(idxB, idxA + 1);
70701 nodesA = nodes.slice(idxA, idxB + 1);
70702 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
70705 var idx = lodash.indexOf(wayA.nodes, nodeId, 1);
70706 nodesA = wayA.nodes.slice(0, idx + 1);
70707 nodesB = wayA.nodes.slice(idx);
70710 wayA = wayA.update({nodes: nodesA});
70711 wayB = wayB.update({nodes: nodesB});
70713 graph = graph.replace(wayA);
70714 graph = graph.replace(wayB);
70716 graph.parentRelations(wayA).forEach(function(relation) {
70717 if (relation.isRestriction()) {
70718 var via = relation.memberByRole('via');
70719 if (via && wayB.contains(via.id)) {
70720 relation = relation.updateMember({id: wayB.id}, relation.memberById(wayA.id).index);
70721 graph = graph.replace(relation);
70724 if (relation === isOuter) {
70725 graph = graph.replace(relation.mergeTags(wayA.tags));
70726 graph = graph.replace(wayA.update({tags: {}}));
70727 graph = graph.replace(wayB.update({tags: {}}));
70733 role: relation.memberById(wayA.id).role
70736 graph = actionAddMember(relation.id, member)(graph);
70740 if (!isOuter && isArea) {
70741 var multipolygon = osmRelation({
70742 tags: lodash.extend({}, wayA.tags, {type: 'multipolygon'}),
70744 {id: wayA.id, role: 'outer', type: 'way'},
70745 {id: wayB.id, role: 'outer', type: 'way'}
70748 graph = graph.replace(multipolygon);
70749 graph = graph.replace(wayA.update({tags: {}}));
70750 graph = graph.replace(wayB.update({tags: {}}));
70757 var action = function(graph) {
70758 var candidates = action.ways(graph);
70759 for (var i = 0; i < candidates.length; i++) {
70760 graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
70766 action.ways = function(graph) {
70767 var node = graph.entity(nodeId),
70768 parents = graph.parentWays(node),
70769 hasLines = lodash.some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
70771 return parents.filter(function(parent) {
70772 if (wayIds && wayIds.indexOf(parent.id) === -1)
70775 if (!wayIds && hasLines && parent.geometry(graph) !== 'line')
70778 if (parent.isClosed()) {
70782 for (var i = 1; i < parent.nodes.length - 1; i++) {
70783 if (parent.nodes[i] === nodeId) {
70793 action.disabled = function(graph) {
70794 var candidates = action.ways(graph);
70795 if (candidates.length === 0 || (wayIds && wayIds.length !== candidates.length))
70796 return 'not_eligible';
70800 action.limitWays = function(_) {
70801 if (!arguments.length) return wayIds;
70810 // Create a restriction relation for `turn`, which must have the following structure:
70813 // from: { node: <node ID>, way: <way ID> },
70814 // via: { node: <node ID> },
70815 // to: { node: <node ID>, way: <way ID> },
70816 // restriction: <'no_right_turn', 'no_left_turn', etc.>
70819 // This specifies a restriction of type `restriction` when traveling from
70820 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
70821 // (The action does not check that these entities form a valid intersection.)
70823 // If `restriction` is not provided, it is automatically determined by
70824 // osmInferRestriction.
70826 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
70827 // and `to.node` are used to determine which portion of the split ways become
70828 // members of the restriction.
70830 // For testing convenience, accepts an ID to assign to the new relation.
70831 // Normally, this will be undefined and the relation will automatically
70832 // be assigned a new ID.
70834 function actionRestrictTurn(turn, projection, restrictionId) {
70836 return function(graph) {
70837 var from = graph.entity(turn.from.way),
70838 via = graph.entity(turn.via.node),
70839 to = graph.entity(turn.to.way);
70841 function isClosingNode(way, nodeId) {
70842 return nodeId === way.first() && nodeId === way.last();
70845 function split(toOrFrom) {
70846 var newID = toOrFrom.newID || osmWay().id;
70847 graph = actionSplit(via.id, [newID])
70848 .limitWays([toOrFrom.way])(graph);
70850 var a = graph.entity(newID),
70851 b = graph.entity(toOrFrom.way);
70853 if (a.nodes.indexOf(toOrFrom.node) !== -1) {
70860 if (!from.affix(via.id) || isClosingNode(from, via.id)) {
70861 if (turn.from.node === turn.to.node) {
70863 from = to = split(turn.from)[0];
70864 } else if (turn.from.way === turn.to.way) {
70865 // Straight-on or circular
70866 var s = split(turn.from);
70871 from = split(turn.from)[0];
70875 if (!to.affix(via.id) || isClosingNode(to, via.id)) {
70876 to = split(turn.to)[0];
70879 return graph.replace(osmRelation({
70882 type: 'restriction',
70883 restriction: turn.restriction ||
70884 osmInferRestriction(
70892 {id: from.id, type: 'way', role: 'from'},
70893 {id: via.id, type: 'node', role: 'via'},
70894 {id: to.id, type: 'way', role: 'to'}
70900 function actionRevert(id) {
70901 var action = function(graph) {
70902 var entity = graph.hasEntity(id),
70903 base = graph.base().entities[id];
70905 if (entity && !base) { // entity will be removed..
70906 if (entity.type === 'node') {
70907 graph.parentWays(entity)
70908 .forEach(function(parent) {
70909 parent = parent.removeNode(id);
70910 graph = graph.replace(parent);
70912 if (parent.isDegenerate()) {
70913 graph = actionDeleteWay(parent.id)(graph);
70918 graph.parentRelations(entity)
70919 .forEach(function(parent) {
70920 parent = parent.removeMembersWithID(id);
70921 graph = graph.replace(parent);
70923 if (parent.isDegenerate()) {
70924 graph = actionDeleteRelation(parent.id)(graph);
70929 return graph.revert(id);
70935 function actionRotate(rotateIds, pivot, angle, projection) {
70937 var action = function(graph) {
70938 return graph.update(function(graph) {
70939 utilGetAllNodes(rotateIds, graph).forEach(function(node) {
70940 var point = geoRotate([projection(node.loc)], angle, pivot)[0];
70941 graph = graph.replace(node.move(projection.invert(point)));
70950 * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
70952 function actionStraighten(wayId, projection) {
70954 function positionAlongWay(n, s, e) {
70955 return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1])) /
70956 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
70960 var action = function(graph, t) {
70961 if (t === null || !isFinite(t)) t = 1;
70962 t = Math.min(Math.max(+t, 0), 1);
70964 var way = graph.entity(wayId),
70965 nodes = graph.childNodes(way),
70966 points = nodes.map(function(n) { return projection(n.loc); }),
70967 startPoint = points[0],
70968 endPoint = points[points.length-1],
70972 for (i = 1; i < points.length-1; i++) {
70973 var node = nodes[i],
70976 if (t < 1 || graph.parentWays(node).length > 1 ||
70977 graph.parentRelations(node).length ||
70978 node.hasInterestingTags()) {
70980 var u = positionAlongWay(point, startPoint, endPoint),
70982 startPoint[0] + u * (endPoint[0] - startPoint[0]),
70983 startPoint[1] + u * (endPoint[1] - startPoint[1])
70985 loc2 = projection.invert(p);
70987 graph = graph.replace(node.move(geoInterp(node.loc, loc2, t)));
70991 if (toDelete.indexOf(node) === -1) {
70992 toDelete.push(node);
70997 for (i = 0; i < toDelete.length; i++) {
70998 graph = actionDeleteNode(toDelete[i].id)(graph);
71005 action.disabled = function(graph) {
71006 // check way isn't too bendy
71007 var way = graph.entity(wayId),
71008 nodes = graph.childNodes(way),
71009 points = nodes.map(function(n) { return projection(n.loc); }),
71010 startPoint = points[0],
71011 endPoint = points[points.length-1],
71012 threshold = 0.2 * geoEuclideanDistance(startPoint, endPoint),
71015 if (threshold === 0) {
71016 return 'too_bendy';
71019 for (i = 1; i < points.length-1; i++) {
71020 var point = points[i],
71021 u = positionAlongWay(point, startPoint, endPoint),
71022 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
71023 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
71024 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
71026 // to bendy if point is off by 20% of total start/end distance in projected space
71027 if (isNaN(dist) || dist > threshold) {
71028 return 'too_bendy';
71034 action.transitionable = true;
71040 // Remove the effects of `turn.restriction` on `turn`, which must have the
71041 // following structure:
71044 // from: { node: <node ID>, way: <way ID> },
71045 // via: { node: <node ID> },
71046 // to: { node: <node ID>, way: <way ID> },
71047 // restriction: <relation ID>
71050 // In the simple case, `restriction` is a reference to a `no_*` restriction
71051 // on the turn itself. In this case, it is simply deleted.
71053 // The more complex case is where `restriction` references an `only_*`
71054 // restriction on a different turn in the same intersection. In that case,
71055 // that restriction is also deleted, but at the same time restrictions on
71056 // the turns other than the first two are created.
71058 function actionUnrestrictTurn(turn) {
71059 return function(graph) {
71060 return actionDeleteRelation(turn.restriction)(graph);
71064 /* Reflect the given area around its axis of symmetry */
71065 function actionReflect(reflectIds, projection) {
71066 var useLongAxis = true;
71069 // http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points
71070 // http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756
71071 function getSmallestSurroundingRectangle(graph, nodes) {
71072 var points = nodes.map(function(n) { return projection(n.loc); }),
71073 hull = d3polygonHull(points),
71074 centroid = d3polygonCentroid(hull),
71075 minArea = Infinity,
71080 for (var i = 0; i < hull.length - 1; i++) {
71081 var c2 = hull[i + 1],
71082 angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]),
71083 poly = geoRotate(hull, -angle, centroid),
71084 extent$$1 = poly.reduce(function(extent$$1, point) {
71085 return extent$$1.extend(geoExtent$$1(point));
71086 }, geoExtent$$1()),
71087 area$$1 = extent$$1.area();
71089 if (area$$1 < minArea) {
71091 ssrExtent = extent$$1;
71098 poly: geoRotate(ssrExtent.polygon(), ssrAngle, centroid),
71104 var action = function(graph, t) {
71105 if (t === null || !isFinite(t)) t = 1;
71106 t = Math.min(Math.max(+t, 0), 1);
71108 var nodes = utilGetAllNodes(reflectIds, graph),
71109 ssr = getSmallestSurroundingRectangle(graph, nodes);
71111 // Choose line pq = axis of symmetry.
71112 // The shape's surrounding rectangle has 2 axes of symmetry.
71113 // Reflect across the longer axis by default.
71114 var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ],
71115 q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ],
71116 p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ],
71117 q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ],
71120 var isLong = (geoEuclideanDistance(p1, q1) > geoEuclideanDistance(p2, q2));
71121 if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) {
71129 // reflect c across pq
71130 // http://math.stackexchange.com/questions/65503/point-reflection-over-a-line
71131 var dx = q[0] - p[0];
71132 var dy = q[1] - p[1];
71133 var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
71134 var b = 2 * dx * dy / (dx * dx + dy * dy);
71135 for (var i = 0; i < nodes.length; i++) {
71136 var node = nodes[i];
71137 var c = projection(node.loc);
71139 a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
71140 b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
71142 var loc2 = projection.invert(c2);
71143 node = node.move(geoInterp(node.loc, loc2, t));
71144 graph = graph.replace(node);
71151 action.useLongAxis = function(_) {
71152 if (!arguments.length) return useLongAxis;
71158 action.transitionable = true;
71166 var index$17 = Object.freeze({
71167 d3combobox: d3combobox,
71168 d3geoTile: d3geoTile,
71169 d3keybinding: d3keybinding
71172 /* export some legacy symbols: */
71173 var Connection = services.osm;
71179 var iD = Object.freeze({
71180 Connection: Connection,
71184 Context: coreContext,
71185 setAreaKeys: setAreaKeys,
71186 Difference: coreDifference,
71187 Graph: coreGraph$$1,
71188 History: coreHistory,
71190 Entity: osmEntity$$1,
71192 Relation: osmRelation,
71194 BackgroundSource: rendererBackgroundSource,
71195 Background: rendererBackground,
71196 Features: rendererFeatures,
71198 TileLayer: rendererTileLayer,
71199 Detect: utilDetect,
71200 actionAddEntity: actionAddEntity,
71201 actionAddMember: actionAddMember,
71202 actionAddMidpoint: actionAddMidpoint,
71203 actionAddVertex: actionAddVertex,
71204 actionChangeMember: actionChangeMember,
71205 actionChangePreset: actionChangePreset,
71206 actionChangeTags: actionChangeTags,
71207 actionCircularize: actionCircularize,
71208 actionConnect: actionConnect,
71209 actionCopyEntities: actionCopyEntities,
71210 actionDeleteMember: actionDeleteMember,
71211 actionDeleteMultiple: actionDeleteMultiple,
71212 actionDeleteNode: actionDeleteNode,
71213 actionDeleteRelation: actionDeleteRelation,
71214 actionDeleteWay: actionDeleteWay,
71215 actionDeprecateTags: actionDeprecateTags,
71216 actionDiscardTags: actionDiscardTags,
71217 actionDisconnect: actionDisconnect,
71218 actionJoin: actionJoin,
71219 actionMerge: actionMerge,
71220 actionMergePolygon: actionMergePolygon,
71221 actionMergeRemoteChanges: actionMergeRemoteChanges,
71222 actionMove: actionMove,
71223 actionMoveNode: actionMoveNode,
71224 actionNoop: actionNoop,
71225 actionOrthogonalize: actionOrthogonalize,
71226 actionRestrictTurn: actionRestrictTurn,
71227 actionReverse: actionReverse,
71228 actionRevert: actionRevert,
71229 actionRotate: actionRotate,
71230 actionSplit: actionSplit,
71231 actionStraighten: actionStraighten,
71232 actionUnrestrictTurn: actionUnrestrictTurn,
71233 actionReflect: actionReflect,
71234 behaviorAddWay: behaviorAddWay,
71235 behaviorBreathe: behaviorBreathe,
71236 behaviorCopy: behaviorCopy,
71237 behaviorDrag: behaviorDrag,
71238 behaviorDrawWay: behaviorDrawWay,
71239 behaviorDraw: behaviorDraw,
71240 behaviorEdit: behaviorEdit,
71241 behaviorHash: behaviorHash,
71242 behaviorHover: behaviorHover,
71243 behaviorLasso: behaviorLasso,
71244 behaviorOperation: behaviorOperation,
71245 behaviorPaste: behaviorPaste,
71246 behaviorSelect: behaviorSelect,
71247 behaviorTail: behaviorTail,
71248 coreContext: coreContext,
71249 coreDifference: coreDifference,
71250 coreGraph: coreGraph$$1,
71251 coreHistory: coreHistory,
71252 coreTree: coreTree,
71253 dataFeatureIcons: dataFeatureIcons,
71255 dataWikipedia: dataWikipedia,
71256 dataSuggestions: dataSuggestions,
71257 dataAddressFormats: dataAddressFormats,
71258 dataDeprecated: dataDeprecated,
71259 dataDiscarded: dataDiscarded,
71260 dataLocales: dataLocales,
71261 dataPhoneFormats: dataPhoneFormats,
71262 dataImperial: dataImperial,
71263 dataDriveLeft: dataDriveLeft,
71265 geoAngle: geoAngle,
71266 geoChooseEdge: geoChooseEdge,
71267 geoCross: geoCross,
71268 geoEdgeEqual: geoEdgeEqual,
71269 geoEuclideanDistance: geoEuclideanDistance,
71270 geoExtent: geoExtent$$1,
71271 geoInterp: geoInterp,
71272 geoRawMercator: geoRawMercator,
71273 geoRoundCoords: geoRoundCoords,
71274 geoRotate: geoRotate,
71275 geoLatToMeters: geoLatToMeters,
71276 geoLineIntersection: geoLineIntersection,
71277 geoLonToMeters: geoLonToMeters,
71278 geoMetersToLat: geoMetersToLat,
71279 geoMetersToLon: geoMetersToLon,
71280 geoMetersToOffset: geoMetersToOffset,
71281 geoOffsetToMeters: geoOffsetToMeters,
71282 geoPathIntersections: geoPathIntersections,
71283 geoPathLength: geoPathLength,
71284 geoPointInPolygon: geoPointInPolygon,
71285 geoPolygonContainsPolygon: geoPolygonContainsPolygon,
71286 geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
71287 geoSphericalDistance: geoSphericalDistance,
71288 modeAddArea: modeAddArea$$1,
71289 modeAddLine: modeAddLine$$1,
71290 modeAddPoint: modeAddPoint$$1,
71291 modeBrowse: modeBrowse,
71292 modeDragNode: modeDragNode$$1,
71293 modeDrawArea: modeDrawArea,
71294 modeDrawLine: modeDrawLine,
71295 modeMove: modeMove$$1,
71296 modeRotate: modeRotate$$1,
71297 modeSave: modeSave$$1,
71298 modeSelect: modeSelect,
71299 operationCircularize: operationCircularize,
71300 operationContinue: operationContinue,
71301 operationDelete: operationDelete,
71302 operationDisconnect: operationDisconnect,
71303 operationMerge: operationMerge,
71304 operationMove: operationMove,
71305 operationOrthogonalize: operationOrthogonalize,
71306 operationReflectShort: operationReflectShort,
71307 operationReflectLong: operationReflectLong,
71308 operationReverse: operationReverse,
71309 operationRotate: operationRotate,
71310 operationSplit: operationSplit,
71311 operationStraighten: operationStraighten,
71312 osmEntity: osmEntity$$1,
71314 osmRelation: osmRelation,
71316 osmIntersection: osmIntersection,
71318 osmInferRestriction: osmInferRestriction,
71319 osmLanes: osmLanes,
71320 osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
71321 osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
71322 osmJoinWays: osmJoinWays,
71323 osmOneWayTags: osmOneWayTags,
71324 osmPavedTags: osmPavedTags,
71325 osmIsInterestingTag: osmIsInterestingTag,
71326 presetCategory: presetCategory,
71327 presetCollection: presetCollection,
71328 presetField: presetField,
71329 presetPreset: presetPreset,
71330 presetIndex: presetIndex,
71331 rendererBackgroundSource: rendererBackgroundSource,
71332 rendererBackground: rendererBackground,
71333 rendererFeatures: rendererFeatures,
71334 rendererMap: rendererMap,
71335 rendererTileLayer: rendererTileLayer,
71336 services: services,
71337 svgAreas: svgAreas$$1,
71338 svgDebug: svgDebug,
71342 svgLabels: svgLabels,
71343 svgLayers: svgLayers,
71344 svgLines: svgLines$$1,
71345 svgMapillaryImages: svgMapillaryImages,
71346 svgMapillarySigns: svgMapillarySigns,
71347 svgMidpoints: svgMidpoints$$1,
71348 svgOneWaySegments: svgOneWaySegments,
71351 svgPointTransform: svgPointTransform,
71352 svgPoints: svgPoints$$1,
71353 svgRelationMemberTags: svgRelationMemberTags,
71354 svgTagClasses: svgTagClasses,
71355 svgTurns: svgTurns,
71356 svgVertices: svgVertices$$1,
71357 uiFields: uiFields,
71358 uiFieldDefaultcheck: uiFieldCheck,
71359 uiFieldCheck: uiFieldCheck,
71360 uiFieldTypeCombo: uiFieldCombo,
71361 uiFieldMultiCombo: uiFieldCombo,
71362 uiFieldNetworkCombo: uiFieldCombo,
71363 uiFieldCombo: uiFieldCombo,
71364 uiFieldUrl: uiFieldText,
71365 uiFieldNumber: uiFieldText,
71366 uiFieldTel: uiFieldText,
71367 uiFieldEmail: uiFieldText,
71368 uiFieldText: uiFieldText,
71369 uiFieldAccess: uiFieldAccess,
71370 uiFieldAddress: uiFieldAddress,
71371 uiFieldCycleway: uiFieldCycleway,
71372 uiFieldLanes: uiFieldLanes,
71373 uiFieldLocalized: uiFieldLocalized,
71374 uiFieldMaxspeed: uiFieldMaxspeed,
71375 uiFieldRadio: uiFieldRadio,
71376 uiFieldRestrictions: uiFieldRestrictions,
71377 uiFieldTextarea: uiFieldTextarea,
71378 uiFieldWikipedia: uiFieldWikipedia,
71381 uiAccount: uiAccount,
71382 uiAttribution: uiAttribution,
71383 uiBackground: uiBackground,
71385 uiCommit: uiCommit,
71386 uiConfirm: uiConfirm,
71387 uiConflicts: uiConflicts,
71388 uiContributors: uiContributors,
71389 uiDisclosure: uiDisclosure,
71390 uiEntityEditor: uiEntityEditor,
71391 uiFeatureInfo: uiFeatureInfo,
71392 uiFeatureList: uiFeatureList,
71394 uiFullScreen: uiFullScreen,
71395 uiGeolocate: uiGeolocate,
71398 uiInspector: uiInspector,
71400 uiLoading: uiLoading,
71401 uiMapData: uiMapData,
71402 uiMapInMap: uiMapInMap,
71405 uiNotice: uiNotice,
71406 uiPreset: uiPreset,
71407 uiPresetIcon: uiPresetIcon,
71408 uiPresetList: uiPresetList,
71409 uiRadialMenu: uiRadialMenu,
71410 uiRawMemberEditor: uiRawMemberEditor,
71411 uiRawMembershipEditor: uiRawMembershipEditor,
71412 uiRawTagEditor: uiRawTagEditor,
71413 uiRestore: uiRestore,
71416 uiSelectionList: uiSelectionList,
71417 uiSidebar: uiSidebar,
71418 uiSourceSwitch: uiSourceSwitch,
71419 uiSpinner: uiSpinner,
71420 uiSplash: uiSplash,
71421 uiStatus: uiStatus,
71422 uiSuccess: uiSuccess,
71423 uiTagReference: uiTagReference,
71424 uiToggle: uiToggle,
71425 uiTooltipHtml: uiTooltipHtml,
71426 uiUndoRedo: uiUndoRedo,
71427 uiViewOnOSM: uiViewOnOSM,
71429 utilTagText: utilTagText,
71430 utilEntitySelector: utilEntitySelector,
71431 utilEntityOrMemberSelector: utilEntityOrMemberSelector,
71432 utilGetAllNodes: utilGetAllNodes,
71433 utilDisplayName: utilDisplayName,
71434 utilDisplayNameForPath: utilDisplayNameForPath,
71435 utilDisplayType: utilDisplayType,
71436 utilStringQs: utilStringQs,
71437 utilQsString: utilQsString,
71438 utilPrefixDOMProperty: utilPrefixDOMProperty,
71439 utilPrefixCSSProperty: utilPrefixCSSProperty,
71440 utilSetTransform: utilSetTransform,
71441 utilEditDistance: utilEditDistance,
71442 utilFastMouse: utilFastMouse,
71443 utilGetPrototypeOf: utilGetPrototypeOf,
71444 utilAsyncMap: utilAsyncMap,
71445 utilWrap: utilWrap,
71446 utilFunctor: utilFunctor,
71447 utilSessionMutex: utilSessionMutex,
71448 utilSuggestNames: utilSuggestNames,
71449 utilTriggerEvent: utilTriggerEvent,
71450 utilGetSetValue: utilGetSetValue,
71451 d3combobox: d3combobox,
71452 d3geoTile: d3geoTile,
71453 d3keybinding: d3keybinding,
71454 validationDeprecatedTag: validationDeprecatedTag,
71455 validationDisconnectedHighway: validationDisconnectedHighway,
71456 validationManyDeletions: validationManyDeletions,
71457 validationMissingTag: validationMissingTag,
71458 validationTagSuggestsArea: validationTagSuggestsArea
71464 //# sourceMappingURL=iD.js.map