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","ie":"+353 20 912 3456","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 1632 961234","gg":"+44 1632 961234","im":"+44 1632 961234","je":"+44 1632 961234","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":"Review your changes and upload them 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"},"produce":{"label":"Produce"},"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/nursing_home":{"name":"Nursing Home","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,infirmary,institution,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/social_facility/nursing_home":{"name":"Nursing Home","terms":"elderly,living,nursing,old,senior"},"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/aquaculture":{"name":"Aquaculture","terms":"fish farm,crustacean,algae,aquafarming,shrimp farm,oyster farm,mariculture,algaculture"},"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":[[[-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]]]},{"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":[[[-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-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":[[[-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":"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":[[[-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]]]},{"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":{"amenity":"coworking_space"},"name":"Coworking Space","searchable":false},"amenity/nursing_home":{"icon":"wheelchair","fields":["operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"tags":{"amenity":"nursing_home"},"name":"Nursing Home","searchable":false},"amenity/register_office":{"icon":"town-hall","fields":["address","building_area","opening_hours","operator"],"geometry":["point","area"],"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","infirmary","institution","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/social_facility/nursing_home":{"icon":"wheelchair","fields":["operator","address","building_area","social_facility","social_facility_for","opening_hours","wheelchair"],"geometry":["point","area"],"terms":["elderly","living","nursing","old","senior"],"tags":{"amenity":"social_facility","social_facility":"nursing_home","social_facility:for":"senior"},"name":"Nursing Home"},"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/aquaculture":{"icon":"aquarium","fields":["operator","produce"],"geometry":["area"],"tags":{"landuse":"aquaculture"},"terms":["fish farm","crustacean","algae","aquafarming","shrimp farm","oyster farm","mariculture","algaculture"],"name":"Aquaculture"},"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","produce"],"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","produce"],"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/aquaculture","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"},"produce":{"key":"produce","type":"combo","label":"Produce"},"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.language || navigator.userLanguage || 'en-US');
37266 detected.language = detected.locale.split('-')[0];
37268 // Search `navigator.languages` for a better locale.. Prefer the first language,
37269 // unless the second language is a culture-specific version of the first one, see #3842
37270 if (navigator.languages && navigator.languages.length > 0) {
37271 var code0 = navigator.languages[0],
37272 parts0 = code0.split('-');
37274 detected.locale = code0;
37275 detected.language = parts0[0];
37277 if (navigator.languages.length > 1 && parts0.length === 1) {
37278 var code1 = navigator.languages[1],
37279 parts1 = code1.split('-');
37281 if (parts1[0] === parts0[0]) {
37282 detected.locale = code1;
37287 // Loaded locale is stored in currentLocale
37288 // return that instead (except in the situation where 'en' might override 'en-US')
37289 var loadedLocale = currentLocale || 'en';
37290 if (loadedLocale !== 'en') {
37291 detected.locale = loadedLocale;
37292 detected.language = detected.locale.split('-')[0];
37295 // detect text direction
37296 var q = utilStringQs(window.location.hash.substring(1));
37297 var lang = dataLocales[detected.locale];
37298 if ((lang && lang.rtl) || q.hasOwnProperty('rtl')) {
37299 detected.textDirection = 'rtl';
37301 detected.textDirection = 'ltr';
37303 setTextDirection(detected.textDirection);
37305 detected.host = window.location && (window.location.origin + window.location.pathname);
37307 detected.filedrop = (window.FileReader && 'ondrop' in window);
37310 return navigator.userAgent.indexOf(x) !== -1;
37314 detected.os = 'win';
37315 detected.platform = 'Windows';
37317 else if (nav('Mac')) {
37318 detected.os = 'mac';
37319 detected.platform = 'Macintosh';
37321 else if (nav('X11') || nav('Linux')) {
37322 detected.os = 'linux';
37323 detected.platform = 'Linux';
37326 detected.os = 'win';
37327 detected.platform = 'Unknown';
37333 var remove$1 = removeDiacritics;
37335 var replacementList = [
37344 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",
37350 chars: "\u00C6\u01FC\u01E2",
37359 chars: "\uA738\uA73A",
37365 chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
37368 chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
37371 chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
37377 chars: "\u01F1\u01C4",
37380 chars: "\u01F2\u01C5",
37383 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",
37386 chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
37389 chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
37392 chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
37395 chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
37398 chars: "\u24BF\uFF2A\u0134\u0248\u0237",
37401 chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
37404 chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
37413 chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
37416 chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
37425 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",
37440 chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
37443 chars: "\u24C6\uFF31\uA756\uA758\u024A",
37446 chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
37449 chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
37452 chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
37461 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",
37464 chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
37470 chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
37473 chars: "\u24CD\uFF38\u1E8A\u1E8C",
37476 chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
37479 chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
37482 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",
37488 chars: "\u00E6\u01FD\u01E3",
37497 chars: "\uA739\uA73B",
37503 chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
37506 chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
37509 chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
37515 chars: "\u01F3\u01C6",
37518 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",
37521 chars: "\u24D5\uFF46\u1E1F\u0192",
37539 chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
37542 chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
37548 chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
37551 chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
37554 chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
37557 chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
37563 chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
37566 chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
37572 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",
37587 chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
37590 chars: "\u24E0\uFF51\u024B\uA757\uA759",
37593 chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
37596 chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
37602 chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
37611 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",
37614 chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
37620 chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
37623 chars: "\u24E7\uFF58\u1E8B\u1E8D",
37626 chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
37629 chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
37633 var diacriticsMap = {};
37634 for (var i = 0; i < replacementList.length; i += 1) {
37635 var chars = replacementList[i].chars;
37636 for (var j = 0; j < chars.length; j += 1) {
37637 diacriticsMap[chars[j]] = replacementList[i].base;
37641 function removeDiacritics(str) {
37642 return str.replace(/[^\u0000-\u007e]/g, function(c) {
37643 return diacriticsMap[c] || c;
37647 // see https://github.com/openstreetmap/iD/pull/3707
37648 // https://gist.github.com/mapmeld/556b09ddec07a2044c76e1ef45f01c60
37651 // madda above alef
37652 1570: { initial: 'آ', isolated: 'ﺁ', medial: 'ﺁ', final: 'ﺂ' },
37654 // hamza above and below alef
37655 1571: { initial: 'أ', isolated: 'ﺃ', medial: '', final: 'ﺄ' },
37657 1573: { initial: 'إ', isolated: 'ﺇ', medial: '', final: 'ﺈ' },
37659 1575: { initial: 'ا', isolated: 'ا', medial: '', final: 'ﺎ' },
37660 1576: { initial: 'ﺑ', isolated: 'ﺏ', medial: 'ﺒ', final: 'ﺐ' },
37663 1577: { initial: '', isolated: 'ة', medial: '', final: 'ﺔ' },
37665 1578: { initial: 'ﺗ', isolated: 'ﺕ', medial: 'ﺘ', final: 'ﺖ' },
37666 1579: { initial: 'ﺛ', isolated: 'ﺙ', medial: 'ﺜ', final: 'ﺚ' },
37667 1580: { initial: 'ﺟ', isolated: 'ﺝ', medial: 'ﺠ', final: 'ﺞ' },
37668 1581: { initial: 'ﺣ', isolated: 'ﺡ', medial: 'ﺤ', final: 'ﺢ' },
37669 1582: { initial: 'ﺧ', isolated: 'ﺥ', medial: 'ﺨ', final: 'ﺦ' },
37670 1583: { initial: 'ﺩ', isolated: 'ﺩ', medial: '', final: 'ﺪ' },
37671 1584: { initial: 'ﺫ', isolated: 'ﺫ', medial: '', final: 'ﺬ' },
37672 1585: { initial: 'ﺭ', isolated: 'ﺭ', medial: '', final: 'ﺮ' },
37673 1586: { initial: 'ﺯ', isolated: 'ﺯ', medial: '', final: 'ﺰ' },
37674 1688: { initial: 'ﮊ', isolated: 'ﮊ', medial: '', final: 'ﮋ' },
37675 1587: { initial: 'ﺳ', isolated: 'ﺱ', medial: 'ﺴ', final: 'ﺲ' },
37676 1588: { initial: 'ﺷ', isolated: 'ﺵ', medial: 'ﺸ', final: 'ﺶ' },
37677 1589: { initial: 'ﺻ', isolated: 'ﺹ', medial: 'ﺼ', final: 'ﺺ' },
37678 1590: { initial: 'ﺿ', isolated: 'ﺽ', medial: 'ﻀ', final: 'ﺾ' },
37679 1591: { initial: 'ﻃ', isolated: 'ﻁ', medial: 'ﻄ', final: 'ﻂ' },
37680 1592: { initial: 'ﻇ', isolated: 'ﻅ', medial: 'ﻈ', final: 'ﻆ' },
37681 1593: { initial: 'ﻋ', isolated: 'ﻉ', medial: 'ﻌ', final: 'ﻊ' },
37682 1594: { initial: 'ﻏ', isolated: 'ﻍ', medial: 'ﻐ', final: 'ﻎ' },
37684 // 1595 ػ - may be very rare
37686 1601: { initial: 'ﻓ', isolated: 'ﻑ', medial: 'ﻔ', final: 'ﻒ' },
37687 1602: { initial: 'ﻗ', isolated: 'ﻕ', medial: 'ﻘ', final: 'ﻖ' },
37688 1604: { initial: 'ﻟ', isolated: 'ﻝ', medial: 'ﻠ', final: 'ﻞ' },
37689 1605: { initial: 'ﻣ', isolated: 'ﻡ', medial: 'ﻤ', final: 'ﻢ' },
37690 1606: { initial: 'ﻧ', isolated: 'ﻥ', medial: 'ﻨ', final: 'ﻦ' },
37691 1607: { initial: 'ﻫ', isolated: 'ﻩ', medial: 'ﻬ', final: 'ﻪ' },
37692 1608: { initial: 'ﻭ', isolated: 'ﻭ', medial: '', final: 'ﻮ' },
37695 1609: { initial: 'ﯨ', isolated: 'ﻯ', medial: 'ﯩ', final: 'ﻰ' },
37697 1610: { initial: 'ﻳ', isolated: 'ﻱ', medial: 'ﻴ', final: 'ﻲ' },
37699 // short vowel sounds / tashkil markings
37701 1662: { initial: 'ﭘ', isolated: 'ﭖ', medial: 'ﭙ', final: 'ﭗ' },
37703 1670: { initial: 'ﭼ', isolated: 'ﭺ', medial: 'ﭽ', final: 'ﭻ' },
37704 1603: { initial: 'ﻛ', isolated: 'ﻙ', medial: 'ﻜ', final: 'ﻚ' },
37705 1705: { initial: 'ﻛ', isolated: 'ﮎ', medial: 'ﻜ', final: 'ﮏ' },
37706 1711: { initial: 'ﮔ', isolated: 'ﮒ', medial: 'ﮕ', final: 'ﮓ' },
37707 1740: { initial: 'ﻳ', isolated: 'ﻯ', medial: 'ﻴ', final: 'ﻰ' },
37708 5000: { initial: 'ﻻ', isolated: 'ﻻ', medial: '', final: 'ﻼ' }
37712 function fixArabicScriptTextForSvg(inputText) {
37713 var context = true;
37715 var rtlBuffer = [];
37717 for (var i = 0, l = inputText.length; i < l; i++) {
37718 var code = inputText[i].charCodeAt(0);
37719 var nextCode = inputText[i + 1] ? inputText[i + 1].charCodeAt(0) : 0;
37721 if (!chars$1[code]) {
37722 if (code === 32 && rtlBuffer.length) {
37724 rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
37726 // non-RTL character
37727 ret += rtlBuffer.reverse().join('') + inputText[i];
37733 if (i === l - 1 || nextCode === 32) {
37734 rtlBuffer.push(chars$1[code].isolated);
37736 // special case for لا
37737 if (code === 1604 && nextCode === 1575) {
37738 rtlBuffer.push(chars$1[5000].initial);
37743 rtlBuffer.push(chars$1[code].initial);
37746 if (i === l - 1 || nextCode === 32){
37747 rtlBuffer.push(chars$1[code].final);
37749 // special case for ﻼ
37750 if (code === 1604 && nextCode === 1575){
37751 rtlBuffer.push(chars$1[5000].final);
37756 if (chars$1[code].medial === ''){
37757 rtlBuffer.push(chars$1[code].final);
37759 rtlBuffer.push(chars$1[code].medial);
37763 context = (chars$1[code].medial === '') || nextCode === 32;
37766 ret += rtlBuffer.reverse().join('');
37770 function utilTagText(entity) {
37771 return entries(entity.tags).map(function(e) {
37772 return e.key + '=' + e.value;
37777 function utilEntitySelector(ids) {
37778 return ids.length ? '.' + ids.join(',.') : 'nothing';
37782 function utilEntityOrMemberSelector(ids, graph) {
37783 var s = utilEntitySelector(ids);
37785 ids.forEach(function(id) {
37786 var entity = graph.hasEntity(id);
37787 if (entity && entity.type === 'relation') {
37788 entity.members.forEach(function(member) {
37789 s += ',.' + member.id;
37798 function utilGetAllNodes(ids, graph) {
37801 ids.forEach(getNodes);
37804 function getNodes(id) {
37805 if (seen[id]) return;
37808 var entity = graph.hasEntity(id);
37809 if (!entity) return;
37811 if (entity.type === 'node') {
37812 nodes.push(entity);
37813 } else if (entity.type === 'way') {
37814 entity.nodes.forEach(getNodes);
37816 entity.members.map(function(member) { return member.id; }).forEach(getNodes);
37822 function utilDisplayName(entity) {
37823 var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
37824 name = entity.tags[localizedNameKey] || entity.tags.name || '',
37825 network = entity.tags.cycle_network || entity.tags.network;
37827 if (!name && entity.tags.ref) {
37828 name = entity.tags.ref;
37830 name = network + ' ' + name;
37838 function utilDisplayNameForPath(entity) {
37839 var name = utilDisplayName(entity);
37840 var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1;
37841 var arabicRegex = /[\u0600-\u06FF]/g;
37843 if (!isFirefox && name && arabicRegex.test(name)) {
37844 name = fixArabicScriptTextForSvg(name);
37851 function utilDisplayType(id) {
37853 n: t('inspector.node'),
37854 w: t('inspector.way'),
37855 r: t('inspector.relation')
37860 function utilStringQs(str) {
37861 return str.split('&').reduce(function(obj, pair){
37862 var parts = pair.split('=');
37863 if (parts.length === 2) {
37864 obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
37871 function utilQsString(obj, noencode) {
37872 function softEncode(s) {
37873 // encode everything except special characters used in certain hash parameters:
37874 // "/" in map states, ":", ",", {" and "}" in background
37875 return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
37877 return Object.keys(obj).sort().map(function(key) {
37878 return encodeURIComponent(key) + '=' + (
37879 noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
37884 function utilPrefixDOMProperty(property) {
37885 var prefixes = ['webkit', 'ms', 'moz', 'o'],
37887 n = prefixes.length,
37893 property = property.substr(0, 1).toUpperCase() + property.substr(1);
37896 if (prefixes[i] + property in s)
37897 return prefixes[i] + property;
37903 function utilPrefixCSSProperty(property) {
37904 var prefixes = ['webkit', 'ms', 'Moz', 'O'],
37906 n = prefixes.length,
37907 s = document.body.style;
37909 if (property.toLowerCase() in s)
37910 return property.toLowerCase();
37913 if (prefixes[i] + property in s)
37914 return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
37920 var transformProperty;
37921 function utilSetTransform(el, x, y, scale) {
37922 var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
37923 translate = utilDetect().opera ?
37924 'translate(' + x + 'px,' + y + 'px)' :
37925 'translate3d(' + x + 'px,' + y + 'px,0)';
37926 return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
37930 // Calculates Levenshtein distance between two strings
37931 // see: https://en.wikipedia.org/wiki/Levenshtein_distance
37932 // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents.
37933 function utilEditDistance(a, b) {
37934 a = remove$1(a.toLowerCase());
37935 b = remove$1(b.toLowerCase());
37936 if (a.length === 0) return b.length;
37937 if (b.length === 0) return a.length;
37939 for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
37940 for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
37941 for (i = 1; i <= b.length; i++) {
37942 for (j = 1; j <= a.length; j++) {
37943 if (b.charAt(i-1) === a.charAt(j-1)) {
37944 matrix[i][j] = matrix[i-1][j-1];
37946 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
37947 Math.min(matrix[i][j-1] + 1, // insertion
37948 matrix[i-1][j] + 1)); // deletion
37952 return matrix[b.length][a.length];
37956 // a d3.mouse-alike which
37957 // 1. Only works on HTML elements, not SVG
37958 // 2. Does not cause style recalculation
37959 function utilFastMouse(container) {
37960 var rect = container.getBoundingClientRect(),
37961 rectLeft = rect.left,
37962 rectTop = rect.top,
37963 clientLeft = +container.clientLeft,
37964 clientTop = +container.clientTop;
37965 if (textDirection === 'rtl') {
37968 return function(e) {
37970 e.clientX - rectLeft - clientLeft,
37971 e.clientY - rectTop - clientTop];
37976 /* eslint-disable no-proto */
37977 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
37978 /* eslint-enable no-proto */
37981 function utilAsyncMap(inputs, func, callback) {
37982 var remaining = inputs.length,
37986 inputs.forEach(function(d, i) {
37987 func(d, function done(err, data) {
37991 if (!remaining) callback(errors, results);
37997 // wraps an index to an interval [0..length-1]
37998 function utilWrap(index, length) {
38000 index += Math.ceil(-index/length)*length;
38001 return index % length;
38006 * a replacement for functor
38008 * @param {*} value any value
38009 * @returns {Function} a function that returns that value or the value if it's a function
38011 function utilFunctor(value) {
38012 if (typeof value === 'function') return value;
38013 return function() {
38019 function utilNoAuto(selection$$1) {
38020 return selection$$1
38021 .attr('autocomplete', 'off')
38022 .attr('autocorrect', 'off')
38023 .attr('autocapitalize', 'off')
38024 .attr('spellcheck', 'false');
38027 // Like selection.property('value', ...), but avoids no-op value sets,
38028 // which can result in layout/repaint thrashing in some situations.
38029 function utilGetSetValue(selection, value) {
38030 function d3_selection_value(value) {
38031 function valueNull() {
38035 function valueConstant() {
38036 if (this.value !== value) {
38037 this.value = value;
38041 function valueFunction() {
38042 var x = value.apply(this, arguments);
38045 } else if (this.value !== x) {
38050 return value == null
38051 ? valueNull : (typeof value === 'function'
38052 ? valueFunction : valueConstant);
38055 if (arguments.length === 1) {
38056 return selection.property('value');
38059 return selection.each(d3_selection_value(value));
38062 // Copies a variable number of methods from source to target.
38063 function utilRebind(target, source) {
38064 var i = 1, n = arguments.length, method;
38066 target[method = arguments[i]] = d3_rebind(target, source, source[method]);
38071 // Method is assumed to be a standard D3 getter-setter:
38072 // If passed with no arguments, gets the value.
38073 // If passed with arguments, sets the value and returns the target.
38074 function d3_rebind(target, source, method) {
38075 return function() {
38076 var value = method.apply(source, arguments);
38077 return value === source ? target : value;
38081 // A per-domain session mutex backed by a cookie and dead man's
38082 // switch. If the session crashes, the mutex will auto-release
38083 // after 5 seconds.
38085 function utilSessionMutex(name) {
38090 var expires = new Date();
38091 expires.setSeconds(expires.getSeconds() + 5);
38092 document.cookie = name + '=1; expires=' + expires.toUTCString();
38095 mutex.lock = function() {
38096 if (intervalID) return true;
38097 var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
38098 if (cookie) return false;
38100 intervalID = window.setInterval(renew, 4000);
38104 mutex.unlock = function() {
38105 if (!intervalID) return;
38106 document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
38107 clearInterval(intervalID);
38111 mutex.locked = function() {
38112 return !!intervalID;
38118 function utilSuggestNames(preset, suggestions) {
38119 preset = preset.id.split('/', 2);
38123 return function(value, callback) {
38125 if (value && value.length > 2) {
38126 if (suggestions[k] && suggestions[k][v]) {
38127 for (var sugg in suggestions[k][v]) {
38128 var dist = utilEditDistance(value, sugg.substring(0, value.length));
38138 result.sort(function(a, b) {
38139 return a.dist - b.dist;
38142 result = result.slice(0,3);
38147 function utilTriggerEvent(target, type) {
38148 target.each(function() {
38149 var evt = document.createEvent('HTMLEvents');
38150 evt.initEvent(type, true, true);
38151 this.dispatchEvent(evt);
38155 function validationDeprecatedTag() {
38157 var validation = function(changes) {
38159 for (var i = 0; i < changes.created.length; i++) {
38160 var change = changes.created[i],
38161 deprecatedTags = change.deprecatedTags();
38163 if (!lodash.isEmpty(deprecatedTags)) {
38164 var tags = utilTagText({ tags: deprecatedTags });
38166 id: 'deprecated_tags',
38167 message: t('validations.deprecated_tags', { tags: tags }),
38180 function validationDisconnectedHighway() {
38183 function isDisconnectedHighway(entity, graph) {
38184 if (!entity.tags.highway) return false;
38185 if (entity.geometry(graph) !== 'line') return false;
38187 return graph.childNodes(entity)
38188 .every(function(vertex) {
38189 return graph.parentWays(vertex)
38190 .filter(function(parent) {
38191 return parent.tags.highway && parent !== entity;
38198 var validation = function(changes, graph) {
38200 for (var i = 0; i < changes.created.length; i++) {
38201 var entity = changes.created[i];
38203 if (isDisconnectedHighway(entity, graph)) {
38206 message: t('validations.disconnected_highway'),
38207 tooltip: t('validations.disconnected_highway_tooltip'),
38220 function validationManyDeletions() {
38221 var threshold = 100;
38223 var validation = function(changes) {
38225 if (changes.deleted.length > threshold) {
38227 id: 'many_deletions',
38228 message: t('validations.many_deletions', { n: changes.deleted.length })
38239 function validationMissingTag() {
38241 // Slightly stricter check than Entity#isUsed (#3091)
38242 function hasTags(entity, graph) {
38243 return lodash.without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
38244 graph.parentRelations(entity).length > 0;
38247 var validation = function(changes, graph) {
38248 var types = ['point', 'line', 'area', 'relation'],
38251 for (var i = 0; i < changes.created.length; i++) {
38252 var change = changes.created[i],
38253 geometry = change.geometry(graph);
38255 if (types.indexOf(geometry) !== -1 && !hasTags(change, graph)) {
38258 message: t('validations.untagged_' + geometry),
38259 tooltip: t('validations.untagged_' + geometry + '_tooltip'),
38272 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
38273 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
38274 function validationTagSuggestsArea() {
38276 function tagSuggestsArea(tags) {
38277 if (lodash.isEmpty(tags)) return false;
38279 var presence = ['landuse', 'amenities', 'tourism', 'shop'];
38280 for (var i = 0; i < presence.length; i++) {
38281 if (tags[presence[i]] !== undefined) {
38282 return presence[i] + '=' + tags[presence[i]];
38286 if (tags.building && tags.building === 'yes') return 'building=yes';
38290 var validation = function(changes, graph) {
38292 for (var i = 0; i < changes.created.length; i++) {
38293 var change = changes.created[i],
38294 geometry = change.geometry(graph),
38295 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
38299 id: 'tag_suggests_area',
38300 message: t('validations.tag_suggests_area', { tag: suggestion }),
38315 var Validations = Object.freeze({
38316 validationDeprecatedTag: validationDeprecatedTag,
38317 validationDisconnectedHighway: validationDisconnectedHighway,
38318 validationManyDeletions: validationManyDeletions,
38319 validationMissingTag: validationMissingTag,
38320 validationTagSuggestsArea: validationTagSuggestsArea
38324 iD.Difference represents the difference between two graphs.
38325 It knows how to calculate the set of entities that were
38326 created, modified, or deleted, and also contains the logic
38327 for recursively extending a difference to the complete set
38328 of entities that will require a redraw, taking into account
38329 child and parent relationships.
38331 function coreDifference(base, head) {
38337 function changed(h, b) {
38338 return h !== b && !lodash.isEqual(lodash.omit(h, 'v'), lodash.omit(b, 'v'));
38342 lodash.each(head.entities, function(h, id) {
38343 var b = base.entities[id];
38344 if (changed(h, b)) {
38345 changes[id] = {base: b, head: h};
38351 lodash.each(base.entities, function(b, id) {
38352 var h = head.entities[id];
38353 if (!changes[id] && changed(h, b)) {
38354 changes[id] = {base: b, head: h};
38360 function addParents(parents, result) {
38361 for (var i = 0; i < parents.length; i++) {
38362 var parent = parents[i];
38364 if (parent.id in result)
38367 result[parent.id] = parent;
38368 addParents(head.parentRelations(parent), result);
38373 difference.length = function() {
38378 difference.changes = function() {
38383 difference.extantIDs = function() {
38385 lodash.each(changes, function(change, id) {
38386 if (change.head) result.push(id);
38392 difference.modified = function() {
38394 lodash.each(changes, function(change) {
38395 if (change.base && change.head) result.push(change.head);
38401 difference.created = function() {
38403 lodash.each(changes, function(change) {
38404 if (!change.base && change.head) result.push(change.head);
38410 difference.deleted = function() {
38412 lodash.each(changes, function(change) {
38413 if (change.base && !change.head) result.push(change.base);
38419 difference.summary = function() {
38422 function addEntity(entity, graph, changeType) {
38423 relevant[entity.id] = {
38426 changeType: changeType
38430 function addParents(entity) {
38431 var parents = head.parentWays(entity);
38432 for (var j = parents.length - 1; j >= 0; j--) {
38433 var parent = parents[j];
38434 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
38438 lodash.each(changes, function(change) {
38439 if (change.head && change.head.geometry(head) !== 'vertex') {
38440 addEntity(change.head, head, change.base ? 'modified' : 'created');
38442 } else if (change.base && change.base.geometry(base) !== 'vertex') {
38443 addEntity(change.base, base, 'deleted');
38445 } else if (change.base && change.head) { // modified vertex
38446 var moved = !lodash.isEqual(change.base.loc, change.head.loc),
38447 retagged = !lodash.isEqual(change.base.tags, change.head.tags);
38450 addParents(change.head);
38453 if (retagged || (moved && change.head.hasInterestingTags())) {
38454 addEntity(change.head, head, 'modified');
38457 } else if (change.head && change.head.hasInterestingTags()) { // created vertex
38458 addEntity(change.head, head, 'created');
38460 } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
38461 addEntity(change.base, base, 'deleted');
38465 return values(relevant);
38469 difference.complete = function(extent$$1) {
38470 var result = {}, id, change;
38472 for (id in changes) {
38473 change = changes[id];
38475 var h = change.head,
38480 (!h || !h.intersects(extent$$1, head)) &&
38481 (!b || !b.intersects(extent$$1, base)))
38486 if (entity.type === 'way') {
38487 var nh = h ? h.nodes : [],
38488 nb = b ? b.nodes : [],
38491 diff = lodash.difference(nh, nb);
38492 for (i = 0; i < diff.length; i++) {
38493 result[diff[i]] = head.hasEntity(diff[i]);
38496 diff = lodash.difference(nb, nh);
38497 for (i = 0; i < diff.length; i++) {
38498 result[diff[i]] = head.hasEntity(diff[i]);
38502 addParents(head.parentWays(entity), result);
38503 addParents(head.parentRelations(entity), result);
38513 function coreGraph$$1(other, mutable) {
38514 if (!(this instanceof coreGraph$$1)) return new coreGraph$$1(other, mutable);
38516 if (other instanceof coreGraph$$1) {
38517 var base = other.base();
38518 this.entities = lodash.assign(Object.create(base.entities), other.entities);
38519 this._parentWays = lodash.assign(Object.create(base.parentWays), other._parentWays);
38520 this._parentRels = lodash.assign(Object.create(base.parentRels), other._parentRels);
38523 this.entities = Object.create({});
38524 this._parentWays = Object.create({});
38525 this._parentRels = Object.create({});
38526 this.rebase(other || [], [this]);
38529 this.transients = {};
38530 this._childNodes = {};
38531 this.frozen = !mutable;
38535 coreGraph$$1.prototype = {
38537 hasEntity: function(id) {
38538 return this.entities[id];
38542 entity: function(id) {
38543 var entity = this.entities[id];
38545 throw new Error('entity ' + id + ' not found');
38551 transient: function(entity, key, fn) {
38552 var id = entity.id,
38553 transients = this.transients[id] ||
38554 (this.transients[id] = {});
38556 if (transients[key] !== undefined) {
38557 return transients[key];
38560 transients[key] = fn.call(entity);
38562 return transients[key];
38566 parentWays: function(entity) {
38567 var parents = this._parentWays[entity.id],
38571 for (var i = 0; i < parents.length; i++) {
38572 result.push(this.entity(parents[i]));
38579 isPoi: function(entity) {
38580 var parentWays = this._parentWays[entity.id];
38581 return !parentWays || parentWays.length === 0;
38585 isShared: function(entity) {
38586 var parentWays = this._parentWays[entity.id];
38587 return parentWays && parentWays.length > 1;
38591 parentRelations: function(entity) {
38592 var parents = this._parentRels[entity.id],
38596 for (var i = 0; i < parents.length; i++) {
38597 result.push(this.entity(parents[i]));
38604 childNodes: function(entity) {
38605 if (this._childNodes[entity.id]) return this._childNodes[entity.id];
38606 if (!entity.nodes) return [];
38609 for (var i = 0; i < entity.nodes.length; i++) {
38610 nodes[i] = this.entity(entity.nodes[i]);
38613 if (debug) Object.freeze(nodes);
38615 this._childNodes[entity.id] = nodes;
38616 return this._childNodes[entity.id];
38622 'entities': utilGetPrototypeOf(this.entities),
38623 'parentWays': utilGetPrototypeOf(this._parentWays),
38624 'parentRels': utilGetPrototypeOf(this._parentRels)
38629 // Unlike other graph methods, rebase mutates in place. This is because it
38630 // is used only during the history operation that merges newly downloaded
38631 // data into each state. To external consumers, it should appear as if the
38632 // graph always contained the newly downloaded data.
38633 rebase: function(entities, stack, force) {
38634 var base = this.base(),
38637 for (i = 0; i < entities.length; i++) {
38638 var entity = entities[i];
38640 if (!entity.visible || (!force && base.entities[entity.id]))
38643 // Merging data into the base graph
38644 base.entities[entity.id] = entity;
38645 this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
38647 // Restore provisionally-deleted nodes that are discovered to have an extant parent
38648 if (entity.type === 'way') {
38649 for (j = 0; j < entity.nodes.length; j++) {
38650 id = entity.nodes[j];
38651 for (k = 1; k < stack.length; k++) {
38652 var ents = stack[k].entities;
38653 if (ents.hasOwnProperty(id) && ents[id] === undefined) {
38661 for (i = 0; i < stack.length; i++) {
38662 stack[i]._updateRebased();
38667 _updateRebased: function() {
38668 var base = this.base(),
38669 i, k, child, id, keys;
38671 keys = Object.keys(this._parentWays);
38672 for (i = 0; i < keys.length; i++) {
38674 if (base.parentWays[child]) {
38675 for (k = 0; k < base.parentWays[child].length; k++) {
38676 id = base.parentWays[child][k];
38677 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentWays[child], id)) {
38678 this._parentWays[child].push(id);
38684 keys = Object.keys(this._parentRels);
38685 for (i = 0; i < keys.length; i++) {
38687 if (base.parentRels[child]) {
38688 for (k = 0; k < base.parentRels[child].length; k++) {
38689 id = base.parentRels[child][k];
38690 if (!this.entities.hasOwnProperty(id) && !lodash.includes(this._parentRels[child], id)) {
38691 this._parentRels[child].push(id);
38697 this.transients = {};
38699 // this._childNodes is not updated, under the assumption that
38700 // ways are always downloaded with their child nodes.
38704 // Updates calculated properties (parentWays, parentRels) for the specified change
38705 _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
38707 parentWays = parentWays || this._parentWays;
38708 parentRels = parentRels || this._parentRels;
38710 var type = entity && entity.type || oldentity && oldentity.type,
38711 removed, added, ways, rels, i;
38714 if (type === 'way') {
38716 // Update parentWays
38717 if (oldentity && entity) {
38718 removed = lodash.difference(oldentity.nodes, entity.nodes);
38719 added = lodash.difference(entity.nodes, oldentity.nodes);
38720 } else if (oldentity) {
38721 removed = oldentity.nodes;
38723 } else if (entity) {
38725 added = entity.nodes;
38727 for (i = 0; i < removed.length; i++) {
38728 parentWays[removed[i]] = lodash.without(parentWays[removed[i]], oldentity.id);
38730 for (i = 0; i < added.length; i++) {
38731 ways = lodash.without(parentWays[added[i]], entity.id);
38732 ways.push(entity.id);
38733 parentWays[added[i]] = ways;
38736 } else if (type === 'relation') {
38738 // Update parentRels
38739 if (oldentity && entity) {
38740 removed = lodash.difference(oldentity.members, entity.members);
38741 added = lodash.difference(entity.members, oldentity);
38742 } else if (oldentity) {
38743 removed = oldentity.members;
38745 } else if (entity) {
38747 added = entity.members;
38749 for (i = 0; i < removed.length; i++) {
38750 parentRels[removed[i].id] = lodash.without(parentRels[removed[i].id], oldentity.id);
38752 for (i = 0; i < added.length; i++) {
38753 rels = lodash.without(parentRels[added[i].id], entity.id);
38754 rels.push(entity.id);
38755 parentRels[added[i].id] = rels;
38761 replace: function(entity) {
38762 if (this.entities[entity.id] === entity)
38765 return this.update(function() {
38766 this._updateCalculated(this.entities[entity.id], entity);
38767 this.entities[entity.id] = entity;
38772 remove: function(entity) {
38773 return this.update(function() {
38774 this._updateCalculated(entity, undefined);
38775 this.entities[entity.id] = undefined;
38780 revert: function(id) {
38781 var baseEntity = this.base().entities[id],
38782 headEntity = this.entities[id];
38784 if (headEntity === baseEntity)
38787 return this.update(function() {
38788 this._updateCalculated(headEntity, baseEntity);
38789 delete this.entities[id];
38794 update: function() {
38795 var graph = this.frozen ? coreGraph$$1(this, true) : this;
38797 for (var i = 0; i < arguments.length; i++) {
38798 arguments[i].call(graph, graph);
38801 if (this.frozen) graph.frozen = true;
38807 // Obliterates any existing entities
38808 load: function(entities) {
38809 var base = this.base();
38810 this.entities = Object.create(base.entities);
38812 for (var i in entities) {
38813 this.entities[i] = entities[i];
38814 this._updateCalculated(base.entities[i], this.entities[i]);
38821 var index$10 = partialSort;
38823 // Floyd-Rivest selection algorithm:
38824 // Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right];
38825 // The k-th element will have the (k - left + 1)th smallest value in [left, right]
38827 function partialSort(arr, k, left, right, compare) {
38829 right = right || (arr.length - 1);
38830 compare = compare || defaultCompare;
38832 while (right > left) {
38833 if (right - left > 600) {
38834 var n = right - left + 1;
38835 var m = k - left + 1;
38836 var z = Math.log(n);
38837 var s = 0.5 * Math.exp(2 * z / 3);
38838 var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
38839 var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
38840 var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
38841 partialSort(arr, k, newLeft, newRight, compare);
38848 swap(arr, left, k);
38849 if (compare(arr[right], t) > 0) swap(arr, left, right);
38855 while (compare(arr[i], t) < 0) i++;
38856 while (compare(arr[j], t) > 0) j--;
38859 if (compare(arr[left], t) === 0) swap(arr, left, j);
38862 swap(arr, j, right);
38865 if (j <= k) left = j + 1;
38866 if (k <= j) right = j - 1;
38870 function swap(arr, i, j) {
38876 function defaultCompare(a, b) {
38877 return a < b ? -1 : a > b ? 1 : 0;
38880 var index$9 = rbush;
38882 var quickselect = index$10;
38884 function rbush(maxEntries, format) {
38885 if (!(this instanceof rbush)) return new rbush(maxEntries, format);
38887 // max entries in a node is 9 by default; min node fill is 40% for best performance
38888 this._maxEntries = Math.max(4, maxEntries || 9);
38889 this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
38892 this._initFormat(format);
38898 rbush.prototype = {
38901 return this._all(this.data, []);
38904 search: function (bbox) {
38906 var node = this.data,
38908 toBBox = this.toBBox;
38910 if (!intersects$1(bbox, node)) return result;
38912 var nodesToSearch = [],
38913 i, len, child, childBBox;
38916 for (i = 0, len = node.children.length; i < len; i++) {
38918 child = node.children[i];
38919 childBBox = node.leaf ? toBBox(child) : child;
38921 if (intersects$1(bbox, childBBox)) {
38922 if (node.leaf) result.push(child);
38923 else if (contains$1(bbox, childBBox)) this._all(child, result);
38924 else nodesToSearch.push(child);
38927 node = nodesToSearch.pop();
38933 collides: function (bbox) {
38935 var node = this.data,
38936 toBBox = this.toBBox;
38938 if (!intersects$1(bbox, node)) return false;
38940 var nodesToSearch = [],
38941 i, len, child, childBBox;
38944 for (i = 0, len = node.children.length; i < len; i++) {
38946 child = node.children[i];
38947 childBBox = node.leaf ? toBBox(child) : child;
38949 if (intersects$1(bbox, childBBox)) {
38950 if (node.leaf || contains$1(bbox, childBBox)) return true;
38951 nodesToSearch.push(child);
38954 node = nodesToSearch.pop();
38960 load: function (data) {
38961 if (!(data && data.length)) return this;
38963 if (data.length < this._minEntries) {
38964 for (var i = 0, len = data.length; i < len; i++) {
38965 this.insert(data[i]);
38970 // recursively build the tree with the given data from stratch using OMT algorithm
38971 var node = this._build(data.slice(), 0, data.length - 1, 0);
38973 if (!this.data.children.length) {
38974 // save as is if tree is empty
38977 } else if (this.data.height === node.height) {
38978 // split root if trees have the same height
38979 this._splitRoot(this.data, node);
38982 if (this.data.height < node.height) {
38983 // swap trees if inserted one is bigger
38984 var tmpNode = this.data;
38989 // insert the small tree into the large tree at appropriate level
38990 this._insert(node, this.data.height - node.height - 1, true);
38996 insert: function (item) {
38997 if (item) this._insert(item, this.data.height - 1);
39001 clear: function () {
39002 this.data = createNode([]);
39006 remove: function (item, equalsFn) {
39007 if (!item) return this;
39009 var node = this.data,
39010 bbox = this.toBBox(item),
39013 i, parent, index, goingUp;
39015 // depth-first iterative tree traversal
39016 while (node || path.length) {
39018 if (!node) { // go up
39020 parent = path[path.length - 1];
39025 if (node.leaf) { // check current node
39026 index = findItem(item, node.children, equalsFn);
39028 if (index !== -1) {
39029 // item found, remove the item and condense tree upwards
39030 node.children.splice(index, 1);
39032 this._condense(path);
39037 if (!goingUp && !node.leaf && contains$1(node, bbox)) { // go down
39042 node = node.children[0];
39044 } else if (parent) { // go right
39046 node = parent.children[i];
39049 } else node = null; // nothing found
39055 toBBox: function (item) { return item; },
39057 compareMinX: compareNodeMinX,
39058 compareMinY: compareNodeMinY,
39060 toJSON: function () { return this.data; },
39062 fromJSON: function (data) {
39067 _all: function (node, result) {
39068 var nodesToSearch = [];
39070 if (node.leaf) result.push.apply(result, node.children);
39071 else nodesToSearch.push.apply(nodesToSearch, node.children);
39073 node = nodesToSearch.pop();
39078 _build: function (items, left, right, height) {
39080 var N = right - left + 1,
39081 M = this._maxEntries,
39085 // reached leaf level; return leaf
39086 node = createNode(items.slice(left, right + 1));
39087 calcBBox(node, this.toBBox);
39092 // target height of the bulk-loaded tree
39093 height = Math.ceil(Math.log(N) / Math.log(M));
39095 // target number of root entries to maximize storage utilization
39096 M = Math.ceil(N / Math.pow(M, height - 1));
39099 node = createNode([]);
39101 node.height = height;
39103 // split the items into M mostly square tiles
39105 var N2 = Math.ceil(N / M),
39106 N1 = N2 * Math.ceil(Math.sqrt(M)),
39107 i, j, right2, right3;
39109 multiSelect(items, left, right, N1, this.compareMinX);
39111 for (i = left; i <= right; i += N1) {
39113 right2 = Math.min(i + N1 - 1, right);
39115 multiSelect(items, i, right2, N2, this.compareMinY);
39117 for (j = i; j <= right2; j += N2) {
39119 right3 = Math.min(j + N2 - 1, right2);
39121 // pack each entry recursively
39122 node.children.push(this._build(items, j, right3, height - 1));
39126 calcBBox(node, this.toBBox);
39131 _chooseSubtree: function (bbox, node, level, path) {
39133 var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
39138 if (node.leaf || path.length - 1 === level) break;
39140 minArea = minEnlargement = Infinity;
39142 for (i = 0, len = node.children.length; i < len; i++) {
39143 child = node.children[i];
39144 area = bboxArea(child);
39145 enlargement = enlargedArea(bbox, child) - area;
39147 // choose entry with the least area enlargement
39148 if (enlargement < minEnlargement) {
39149 minEnlargement = enlargement;
39150 minArea = area < minArea ? area : minArea;
39151 targetNode = child;
39153 } else if (enlargement === minEnlargement) {
39154 // otherwise choose one with the smallest area
39155 if (area < minArea) {
39157 targetNode = child;
39162 node = targetNode || node.children[0];
39168 _insert: function (item, level, isNode) {
39170 var toBBox = this.toBBox,
39171 bbox = isNode ? item : toBBox(item),
39174 // find the best node for accommodating the item, saving all nodes along the path too
39175 var node = this._chooseSubtree(bbox, this.data, level, insertPath);
39177 // put the item into the node
39178 node.children.push(item);
39179 extend$1(node, bbox);
39181 // split on node overflow; propagate upwards if necessary
39182 while (level >= 0) {
39183 if (insertPath[level].children.length > this._maxEntries) {
39184 this._split(insertPath, level);
39189 // adjust bboxes along the insertion path
39190 this._adjustParentBBoxes(bbox, insertPath, level);
39193 // split overflowed node into two
39194 _split: function (insertPath, level) {
39196 var node = insertPath[level],
39197 M = node.children.length,
39198 m = this._minEntries;
39200 this._chooseSplitAxis(node, m, M);
39202 var splitIndex = this._chooseSplitIndex(node, m, M);
39204 var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
39205 newNode.height = node.height;
39206 newNode.leaf = node.leaf;
39208 calcBBox(node, this.toBBox);
39209 calcBBox(newNode, this.toBBox);
39211 if (level) insertPath[level - 1].children.push(newNode);
39212 else this._splitRoot(node, newNode);
39215 _splitRoot: function (node, newNode) {
39217 this.data = createNode([node, newNode]);
39218 this.data.height = node.height + 1;
39219 this.data.leaf = false;
39220 calcBBox(this.data, this.toBBox);
39223 _chooseSplitIndex: function (node, m, M) {
39225 var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
39227 minOverlap = minArea = Infinity;
39229 for (i = m; i <= M - m; i++) {
39230 bbox1 = distBBox(node, 0, i, this.toBBox);
39231 bbox2 = distBBox(node, i, M, this.toBBox);
39233 overlap = intersectionArea(bbox1, bbox2);
39234 area = bboxArea(bbox1) + bboxArea(bbox2);
39236 // choose distribution with minimum overlap
39237 if (overlap < minOverlap) {
39238 minOverlap = overlap;
39241 minArea = area < minArea ? area : minArea;
39243 } else if (overlap === minOverlap) {
39244 // otherwise choose distribution with minimum area
39245 if (area < minArea) {
39255 // sorts node children by the best axis for split
39256 _chooseSplitAxis: function (node, m, M) {
39258 var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
39259 compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
39260 xMargin = this._allDistMargin(node, m, M, compareMinX),
39261 yMargin = this._allDistMargin(node, m, M, compareMinY);
39263 // if total distributions margin value is minimal for x, sort by minX,
39264 // otherwise it's already sorted by minY
39265 if (xMargin < yMargin) node.children.sort(compareMinX);
39268 // total margin of all possible split distributions where each node is at least m full
39269 _allDistMargin: function (node, m, M, compare) {
39271 node.children.sort(compare);
39273 var toBBox = this.toBBox,
39274 leftBBox = distBBox(node, 0, m, toBBox),
39275 rightBBox = distBBox(node, M - m, M, toBBox),
39276 margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
39279 for (i = m; i < M - m; i++) {
39280 child = node.children[i];
39281 extend$1(leftBBox, node.leaf ? toBBox(child) : child);
39282 margin += bboxMargin(leftBBox);
39285 for (i = M - m - 1; i >= m; i--) {
39286 child = node.children[i];
39287 extend$1(rightBBox, node.leaf ? toBBox(child) : child);
39288 margin += bboxMargin(rightBBox);
39294 _adjustParentBBoxes: function (bbox, path, level) {
39295 // adjust bboxes along the given tree path
39296 for (var i = level; i >= 0; i--) {
39297 extend$1(path[i], bbox);
39301 _condense: function (path) {
39302 // go through the path, removing empty nodes and updating bboxes
39303 for (var i = path.length - 1, siblings; i >= 0; i--) {
39304 if (path[i].children.length === 0) {
39306 siblings = path[i - 1].children;
39307 siblings.splice(siblings.indexOf(path[i]), 1);
39309 } else this.clear();
39311 } else calcBBox(path[i], this.toBBox);
39315 _initFormat: function (format) {
39316 // data format (minX, minY, maxX, maxY accessors)
39318 // uses eval-type function compilation instead of just accepting a toBBox function
39319 // because the algorithms are very sensitive to sorting functions performance,
39320 // so they should be dead simple and without inner calls
39322 var compareArr = ['return a', ' - b', ';'];
39324 this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
39325 this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
39327 this.toBBox = new Function('a',
39328 'return {minX: a' + format[0] +
39329 ', minY: a' + format[1] +
39330 ', maxX: a' + format[2] +
39331 ', maxY: a' + format[3] + '};');
39335 function findItem(item, items, equalsFn) {
39336 if (!equalsFn) return items.indexOf(item);
39338 for (var i = 0; i < items.length; i++) {
39339 if (equalsFn(item, items[i])) return i;
39344 // calculate node's bbox from bboxes of its children
39345 function calcBBox(node, toBBox) {
39346 distBBox(node, 0, node.children.length, toBBox, node);
39349 // min bounding rectangle of node children from k to p-1
39350 function distBBox(node, k, p, toBBox, destNode) {
39351 if (!destNode) destNode = createNode(null);
39352 destNode.minX = Infinity;
39353 destNode.minY = Infinity;
39354 destNode.maxX = -Infinity;
39355 destNode.maxY = -Infinity;
39357 for (var i = k, child; i < p; i++) {
39358 child = node.children[i];
39359 extend$1(destNode, node.leaf ? toBBox(child) : child);
39365 function extend$1(a, b) {
39366 a.minX = Math.min(a.minX, b.minX);
39367 a.minY = Math.min(a.minY, b.minY);
39368 a.maxX = Math.max(a.maxX, b.maxX);
39369 a.maxY = Math.max(a.maxY, b.maxY);
39373 function compareNodeMinX(a, b) { return a.minX - b.minX; }
39374 function compareNodeMinY(a, b) { return a.minY - b.minY; }
39376 function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }
39377 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
39379 function enlargedArea(a, b) {
39380 return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
39381 (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
39384 function intersectionArea(a, b) {
39385 var minX = Math.max(a.minX, b.minX),
39386 minY = Math.max(a.minY, b.minY),
39387 maxX = Math.min(a.maxX, b.maxX),
39388 maxY = Math.min(a.maxY, b.maxY);
39390 return Math.max(0, maxX - minX) *
39391 Math.max(0, maxY - minY);
39394 function contains$1(a, b) {
39395 return a.minX <= b.minX &&
39396 a.minY <= b.minY &&
39397 b.maxX <= a.maxX &&
39401 function intersects$1(a, b) {
39402 return b.minX <= a.maxX &&
39403 b.minY <= a.maxY &&
39404 b.maxX >= a.minX &&
39408 function createNode(children) {
39410 children: children,
39420 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
39421 // combines selection algorithm with binary divide & conquer approach
39423 function multiSelect(arr, left, right, n, compare) {
39424 var stack = [left, right],
39427 while (stack.length) {
39428 right = stack.pop();
39429 left = stack.pop();
39431 if (right - left <= n) continue;
39433 mid = left + Math.ceil((right - left) / n / 2) * n;
39434 quickselect(arr, mid, left, right, compare);
39436 stack.push(left, mid, mid, right);
39440 function coreTree(head) {
39441 var rtree = index$9(),
39446 function entityBBox(entity) {
39447 var bbox = entity.extent(head).bbox();
39448 bbox.id = entity.id;
39449 bboxes[entity.id] = bbox;
39454 function updateParents(entity, insertions, memo) {
39455 head.parentWays(entity).forEach(function(way) {
39456 if (bboxes[way.id]) {
39457 rtree.remove(bboxes[way.id]);
39458 insertions[way.id] = way;
39460 updateParents(way, insertions, memo);
39463 head.parentRelations(entity).forEach(function(relation) {
39464 if (memo[entity.id]) return;
39465 memo[entity.id] = true;
39466 if (bboxes[relation.id]) {
39467 rtree.remove(bboxes[relation.id]);
39468 insertions[relation.id] = relation;
39470 updateParents(relation, insertions, memo);
39475 tree.rebase = function(entities, force) {
39476 var insertions = {};
39478 for (var i = 0; i < entities.length; i++) {
39479 var entity = entities[i];
39481 if (!entity.visible)
39484 if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
39487 } else if (bboxes[entity.id]) {
39488 rtree.remove(bboxes[entity.id]);
39492 insertions[entity.id] = entity;
39493 updateParents(entity, insertions, {});
39496 rtree.load(lodash.map(insertions, entityBBox));
39502 tree.intersects = function(extent, graph) {
39503 if (graph !== head) {
39504 var diff = coreDifference(head, graph),
39509 diff.deleted().forEach(function(entity) {
39510 rtree.remove(bboxes[entity.id]);
39511 delete bboxes[entity.id];
39514 diff.modified().forEach(function(entity) {
39515 rtree.remove(bboxes[entity.id]);
39516 insertions[entity.id] = entity;
39517 updateParents(entity, insertions, {});
39520 diff.created().forEach(function(entity) {
39521 insertions[entity.id] = entity;
39524 rtree.load(lodash.map(insertions, entityBBox));
39527 return rtree.search(extent.bbox()).map(function(bbox) {
39528 return head.entity(bbox.id);
39537 * This code is licensed under the MIT license.
39539 * Copyright © 2013, iD authors.
39541 * Portions copyright © 2011, Keith Cirkel
39542 * See https://github.com/keithamus/jwerty
39545 function d3keybinding(namespace$$1) {
39548 function matches(binding, event$$1) {
39549 for (var p in binding.event) {
39550 if (event$$1[p] !== binding.event[p])
39556 function testBindings(isCapturing) {
39557 for (var i = 0; i < bindings.length; i++) {
39558 var binding = bindings[i];
39560 if (!!binding.capture === isCapturing && matches(binding, event)) {
39561 binding.callback();
39566 function capture() {
39567 testBindings(true);
39570 function bubble() {
39571 var tagName = select(event.target).node().tagName;
39572 if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
39575 testBindings(false);
39578 function keybinding(selection$$1) {
39579 selection$$1 = selection$$1 || select(document);
39580 selection$$1.on('keydown.capture' + namespace$$1, capture, true);
39581 selection$$1.on('keydown.bubble' + namespace$$1, bubble, false);
39585 keybinding.off = function(selection$$1) {
39587 selection$$1 = selection$$1 || select(document);
39588 selection$$1.on('keydown.capture' + namespace$$1, null);
39589 selection$$1.on('keydown.bubble' + namespace$$1, null);
39593 keybinding.on = function(codes, callback, capture) {
39594 var arr = [].concat(codes);
39595 for (var i = 0; i < arr.length; i++) {
39609 code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
39611 for (var j = 0; j < code.length; j++) {
39612 // Normalise matching errors
39613 if (code[j] === '++') code[i] = '+';
39615 if (code[j] in d3keybinding.modifierCodes) {
39616 binding.event[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
39617 } else if (code[j] in d3keybinding.keyCodes) {
39618 binding.event.keyCode = d3keybinding.keyCodes[code[j]];
39622 bindings.push(binding);
39632 d3keybinding.modifierCodes = {
39634 '⇧': 16, shift: 16,
39635 // CTRL key, on Mac: ⌃
39637 // ALT key, on Mac: ⌥ (Alt)
39638 '⌥': 18, alt: 18, option: 18,
39639 // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
39640 '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
39643 d3keybinding.modifierProperties = {
39650 d3keybinding.keyCodes = {
39651 // Backspace key, on Mac: ⌫ (Backspace)
39652 '⌫': 8, backspace: 8,
39653 // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
39654 '⇥': 9, '⇆': 9, tab: 9,
39656 '↩': 13, 'return': 13, enter: 13, '⌅': 13,
39658 'pause': 19, 'pause-break': 19,
39659 // Caps Lock key, ⇪
39660 '⇪': 20, caps: 20, 'caps-lock': 20,
39661 // Escape key, on Mac: ⎋, on Windows: Esc
39662 '⎋': 27, escape: 27, esc: 27,
39665 // Page-Up key, or pgup, on Mac: ↖
39666 '↖': 33, pgup: 33, 'page-up': 33,
39667 // Page-Down key, or pgdown, on Mac: ↘
39668 '↘': 34, pgdown: 34, 'page-down': 34,
39669 // END key, on Mac: ⇟
39671 // HOME key, on Mac: ⇞
39673 // Insert key, or ins
39674 ins: 45, insert: 45,
39675 // Delete key, on Mac: ⌦ (Delete)
39676 '⌦': 46, del: 46, 'delete': 46,
39677 // Left Arrow Key, or ←
39678 '←': 37, left: 37, 'arrow-left': 37,
39679 // Up Arrow Key, or ↑
39680 '↑': 38, up: 38, 'arrow-up': 38,
39681 // Right Arrow Key, or →
39682 '→': 39, right: 39, 'arrow-right': 39,
39683 // Up Arrow Key, or ↓
39684 '↓': 40, down: 40, 'arrow-down': 40,
39685 // odities, printing characters that come out wrong:
39688 // Num-Multiply, or *
39689 '*': 106, star: 106, asterisk: 106, multiply: 106,
39691 '+': 107, 'plus': 107,
39692 // Num-Subtract, or -
39693 '-': 109, subtract: 109,
39699 ';': 186, semicolon: 186,
39701 '=': 187, 'equals': 187,
39703 ',': 188, comma: 188,
39704 // Dash / Underscore key
39706 // Period, or ., or full-stop
39707 '.': 190, period: 190, 'full-stop': 190,
39708 // Slash, or /, or forward-slash
39709 '/': 191, slash: 191, 'forward-slash': 191,
39710 // Tick, or `, or back-quote
39711 '`': 192, tick: 192, 'back-quote': 192,
39712 // Open bracket, or [
39713 '[': 219, 'open-bracket': 219,
39714 // Back slash, or \
39715 '\\': 220, 'back-slash': 220,
39716 // Close backet, or ]
39717 ']': 221, 'close-bracket': 221,
39718 // Apostrophe, or Quote, or '
39719 '\'': 222, quote: 222, apostrophe: 222
39725 while (++i$1 < 106) {
39726 d3keybinding.keyCodes['num-' + n] = i$1;
39732 while (++i$1 < 58) {
39733 d3keybinding.keyCodes[n] = i$1;
39739 while (++i$1 < 136) {
39740 d3keybinding.keyCodes['f' + n] = i$1;
39746 while (++i$1 < 91) {
39747 d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
39750 function tooltip() {
39751 var tooltip = function(selection$$1) {
39752 selection$$1.each(setup);
39754 animation = utilFunctor(false),
39755 html$$1 = utilFunctor(false),
39756 title = function() {
39757 var title = this.getAttribute('data-original-title');
39761 title = this.getAttribute('title');
39762 this.removeAttribute('title');
39763 this.setAttribute('data-original-title', title);
39767 over = 'mouseenter.tooltip',
39768 out = 'mouseleave.tooltip',
39769 placement = utilFunctor('top');
39772 tooltip.title = function(_) {
39773 if (arguments.length) {
39774 title = utilFunctor(_);
39782 tooltip.html = function(_) {
39783 if (arguments.length) {
39784 html$$1 = utilFunctor(_);
39792 tooltip.placement = function(_) {
39793 if (arguments.length) {
39794 placement = utilFunctor(_);
39802 tooltip.show = function(selection$$1) {
39803 selection$$1.each(show);
39807 tooltip.hide = function(selection$$1) {
39808 selection$$1.each(hide);
39812 tooltip.toggle = function(selection$$1) {
39813 selection$$1.each(toggle);
39817 tooltip.destroy = function(selection$$1) {
39821 .attr('title', function() {
39822 return this.getAttribute('data-original-title') || this.getAttribute('title');
39824 .attr('data-original-title', null)
39825 .selectAll('.tooltip')
39831 var root = select(this),
39832 animate = animation.apply(this, arguments),
39833 tip = root.selectAll('.tooltip').data([0]);
39835 var enter = tip.enter()
39837 .attr('class', 'tooltip');
39841 .attr('class', 'tooltip-arrow');
39845 .attr('class', 'tooltip-inner');
39851 tip.classed('fade', true);
39854 var place = placement.apply(this, arguments);
39855 tip.classed(place, true);
39857 root.on(over, show);
39858 root.on(out, hide);
39863 var root = select(this),
39864 content = title.apply(this, arguments),
39865 tip = root.selectAll('.tooltip')
39866 .classed('in', true),
39867 markup = html$$1.apply(this, arguments);
39869 tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
39870 var place = placement.apply(this, arguments),
39871 outer = getPosition(root.node()),
39872 inner = getPosition(tip.node()),
39877 pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
39880 pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
39883 pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
39886 pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
39891 tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
39893 tip.style('left', null).style('top', null);
39896 this.tooltipVisible = true;
39901 select(this).selectAll('.tooltip')
39902 .classed('in', false);
39904 this.tooltipVisible = false;
39908 function toggle() {
39909 if (this.tooltipVisible) {
39910 hide.apply(this, arguments);
39912 show.apply(this, arguments);
39920 function getPosition(node) {
39921 var mode = select(node).style('position');
39922 if (mode === 'absolute' || mode === 'static') {
39924 x: node.offsetLeft,
39926 w: node.offsetWidth,
39927 h: node.offsetHeight
39933 w: node.offsetWidth,
39934 h: node.offsetHeight
39939 function svgAreas$$1(projection, context) {
39940 // Patterns only work in Firefox when set directly on element.
39941 // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
39944 cemetery: 'cemetery',
39945 construction: 'construction',
39947 farmland: 'farmland',
39948 grave_yard: 'cemetery',
39950 military: 'construction',
39951 orchard: 'orchard',
39954 wetland: 'wetland',
39957 var patternKeys = ['landuse', 'natural', 'amenity'];
39960 function setPattern(d) {
39961 for (var i = 0; i < patternKeys.length; i++) {
39962 if (d.tags.building && d.tags.building !== 'no') continue;
39964 if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
39965 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
39969 this.style.fill = this.style.stroke = '';
39973 return function drawAreas(selection$$1, graph, entities, filter) {
39974 var path$$1 = svgPath(projection, graph, true),
39978 for (var i = 0; i < entities.length; i++) {
39979 var entity = entities[i];
39980 if (entity.geometry(graph) !== 'area') continue;
39982 multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
39983 if (multipolygon) {
39984 areas[multipolygon.id] = {
39985 entity: multipolygon.mergeTags(entity.tags),
39986 area: Math.abs(entity.area(graph))
39988 } else if (!areas[entity.id]) {
39989 areas[entity.id] = {
39991 area: Math.abs(entity.area(graph))
39996 areas = values(areas).filter(function hasPath(a) { return path$$1(a.entity); });
39997 areas.sort(function areaSort(a, b) { return b.area - a.area; });
39998 areas = lodash.map(areas, 'entity');
40000 var strokes = areas.filter(function(area$$1) {
40001 return area$$1.type === 'way';
40011 var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
40013 .data(data.clip, osmEntity$$1.key);
40018 var clipPathsEnter = clipPaths.enter()
40019 .append('clipPath')
40020 .attr('class', 'clipPath')
40021 .attr('id', function(entity) { return entity.id + '-clippath'; });
40026 clipPaths.merge(clipPathsEnter)
40028 .attr('d', path$$1);
40031 var layer = selection$$1.selectAll('.layer-areas');
40033 var areagroup = layer
40034 .selectAll('g.areagroup')
40035 .data(['fill', 'shadow', 'stroke']);
40037 areagroup = areagroup.enter()
40039 .attr('class', function(d) { return 'areagroup area-' + d; })
40042 var paths = areagroup
40045 .data(function(layer) { return data[layer]; }, osmEntity$$1.key);
40050 var fills = selection$$1.selectAll('.area-fill path.area').nodes();
40052 var bisect$$1 = bisector(function(node) {
40053 return -node.__data__.area(graph);
40056 function sortedByArea(entity) {
40057 if (this._parent.__data__ === 'fill') {
40058 return fills[bisect$$1(fills, -entity.area(graph))];
40062 paths = paths.enter()
40063 .insert('path', sortedByArea)
40065 .each(function(entity) {
40066 var layer = this.parentNode.__data__;
40068 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
40070 if (layer === 'fill') {
40071 this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
40072 setPattern.apply(this, arguments);
40075 .call(svgTagClasses())
40076 .attr('d', path$$1);
40080 function svgDebug(projection, context) {
40082 function multipolygons(imagery) {
40083 return imagery.map(function(data$$1) {
40085 type: 'MultiPolygon',
40086 coordinates: [ data$$1.polygon ]
40091 function drawDebug(selection$$1) {
40092 var showsTile = context.getDebug('tile'),
40093 showsCollision = context.getDebug('collision'),
40094 showsImagery = context.getDebug('imagery'),
40095 showsImperial = context.getDebug('imperial'),
40096 showsDriveLeft = context.getDebug('driveLeft'),
40097 path$$1 = index$4(projection);
40100 var debugData = [];
40102 debugData.push({ class: 'red', label: 'tile' });
40104 if (showsCollision) {
40105 debugData.push({ class: 'yellow', label: 'collision' });
40107 if (showsImagery) {
40108 debugData.push({ class: 'orange', label: 'imagery' });
40110 if (showsImperial) {
40111 debugData.push({ class: 'cyan', label: 'imperial' });
40113 if (showsDriveLeft) {
40114 debugData.push({ class: 'green', label: 'driveLeft' });
40118 var legend = select('#content')
40119 .selectAll('.debug-legend')
40120 .data(debugData.length ? [0] : []);
40125 legend = legend.enter()
40127 .attr('class', 'fillD debug-legend')
40131 var legendItems = legend.selectAll('.debug-legend-item')
40132 .data(debugData, function(d) { return d.label; });
40137 legendItems.enter()
40139 .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
40140 .text(function(d) { return d.label; });
40143 var layer = selection$$1.selectAll('.layer-debug')
40144 .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
40149 layer = layer.enter()
40151 .attr('class', 'layer-debug')
40155 var extent$$1 = context.map().extent(),
40156 dataImagery = data.imagery || [],
40157 availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
40158 if (!source.polygon) return false;
40159 return source.polygon.some(function(polygon) {
40160 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
40164 var imagery = layer.selectAll('path.debug-imagery')
40165 .data(showsImagery ? availableImagery : []);
40172 .attr('class', 'debug-imagery debug orange');
40175 var imperial = layer
40176 .selectAll('path.debug-imperial')
40177 .data(showsImperial ? [dataImperial] : []);
40184 .attr('class', 'debug-imperial debug cyan');
40187 var driveLeft = layer
40188 .selectAll('path.debug-drive-left')
40189 .data(showsDriveLeft ? [dataDriveLeft] : []);
40196 .attr('class', 'debug-drive-left debug green');
40200 layer.selectAll('path')
40201 .attr('d', path$$1);
40205 // This looks strange because `enabled` methods on other layers are
40206 // chainable getter/setters, and this one is just a getter.
40207 drawDebug.enabled = function() {
40208 if (!arguments.length) {
40209 return context.getDebug('tile') ||
40210 context.getDebug('collision') ||
40211 context.getDebug('imagery') ||
40212 context.getDebug('imperial') ||
40213 context.getDebug('driveLeft');
40224 A standalone SVG element that contains only a `defs` sub-element. To be
40225 used once globally, since defs IDs must be unique within a document.
40227 function svgDefs(context) {
40229 function SVGSpriteDefinition(id, href) {
40230 return function(defs) {
40232 .mimeType('image/svg+xml')
40233 .response(function(xhr) { return xhr.responseXML; })
40234 .get(function(err, svg) {
40236 defs.node().appendChild(
40237 select(svg.documentElement).attr('id', id).node()
40244 return function drawDefs(selection$$1) {
40245 var defs = selection$$1.append('defs');
40248 defs.append('marker')
40249 .attr('id', 'oneway-marker')
40250 .attr('viewBox', '0 0 10 10')
40253 .attr('markerWidth', 2)
40254 .attr('markerHeight', 2)
40255 .attr('markerUnits', 'strokeWidth')
40256 .attr('orient', 'auto')
40259 .attr('class', 'oneway')
40260 .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')
40261 .attr('stroke', 'none')
40262 .attr('fill', '#000')
40263 .attr('opacity', '0.5');
40266 var patterns = defs.selectAll('pattern')
40268 // pattern name, pattern image name
40269 ['wetland', 'wetland'],
40270 ['construction', 'construction'],
40271 ['cemetery', 'cemetery'],
40272 ['orchard', 'orchard'],
40273 ['farmland', 'farmland'],
40280 .attr('id', function (d) {
40281 return 'pattern-' + d[0];
40284 .attr('height', 32)
40285 .attr('patternUnits', 'userSpaceOnUse');
40287 patterns.append('rect')
40291 .attr('height', 32)
40292 .attr('class', function (d) {
40293 return 'pattern-color-' + d[0];
40296 patterns.append('image')
40300 .attr('height', 32)
40301 .attr('xlink:href', function (d) {
40302 return context.imagePath('pattern/' + d[1] + '.png');
40307 .data([12, 18, 20, 32, 45])
40309 .append('clipPath')
40310 .attr('id', function (d) {
40311 return 'clip-square-' + d;
40316 .attr('width', function (d) {
40319 .attr('height', function (d) {
40323 defs.call(SVGSpriteDefinition(
40325 context.imagePath('iD-sprite.svg')));
40327 defs.call(SVGSpriteDefinition(
40329 context.imagePath('maki-sprite.svg')));
40333 var sax = createCommonjsModule(function (module, exports) {
40334 //[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]
40335 //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
40336 //[5] Name ::= NameStartChar (NameChar)*
40337 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
40338 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]");
40339 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
40340 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
40341 //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(',')
40343 //S_TAG, S_ATTR, S_EQ, S_V
40344 //S_ATTR_S, S_E, S_S, S_C
40345 var S_TAG = 0;//tag name offerring
40346 var S_ATTR = 1;//attr name offerring
40347 var S_ATTR_S=2;//attr name end and space offer
40348 var S_EQ = 3;//=space?
40349 var S_V = 4;//attr value(no quot value only)
40350 var S_E = 5;//attr value end and no space(quot end)
40351 var S_S = 6;//(attr value end || tag end ) && (space offer)
40352 var S_C = 7;//closed el<el />
40354 function XMLReader(){
40358 XMLReader.prototype = {
40359 parse:function(source,defaultNSMap,entityMap){
40360 var domBuilder = this.domBuilder;
40361 domBuilder.startDocument();
40362 _copy(defaultNSMap ,defaultNSMap = {});
40363 parse(source,defaultNSMap,entityMap,
40364 domBuilder,this.errorHandler);
40365 domBuilder.endDocument();
40368 function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
40369 function fixedFromCharCode(code) {
40370 // String.prototype.fromCharCode does not supports
40371 // > 2 bytes unicode chars directly
40372 if (code > 0xffff) {
40374 var surrogate1 = 0xd800 + (code >> 10)
40375 , surrogate2 = 0xdc00 + (code & 0x3ff);
40377 return String.fromCharCode(surrogate1, surrogate2);
40379 return String.fromCharCode(code);
40382 function entityReplacer(a){
40383 var k = a.slice(1,-1);
40384 if(k in entityMap){
40385 return entityMap[k];
40386 }else if(k.charAt(0) === '#'){
40387 return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
40389 errorHandler.error('entity not found:'+a);
40393 function appendText(end){//has some bugs
40395 var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
40396 locator&&position(start);
40397 domBuilder.characters(xt,0,end-start);
40401 function position(p,m){
40402 while(p>=lineEnd && (m = linePattern.exec(source))){
40403 lineStart = m.index;
40404 lineEnd = lineStart + m[0].length;
40405 locator.lineNumber++;
40406 //console.log('line++:',locator,startPos,endPos)
40408 locator.columnNumber = p-lineStart+1;
40412 var linePattern = /.+(?:\r\n?|\n)|.*$/g;
40413 var locator = domBuilder.locator;
40415 var parseStack = [{currentNSMap:defaultNSMapCopy}];
40420 var tagStart = source.indexOf('<',start);
40422 if(!source.substr(start).match(/^\s*$/)){
40423 var doc = domBuilder.document;
40424 var text = doc.createTextNode(source.substr(start));
40425 doc.appendChild(text);
40426 domBuilder.currentElement = text;
40430 if(tagStart>start){
40431 appendText(tagStart);
40433 switch(source.charAt(tagStart+1)){
40435 var end = source.indexOf('>',tagStart+3);
40436 var tagName = source.substring(tagStart+2,end);
40437 var config = parseStack.pop();
40438 var localNSMap = config.localNSMap;
40439 if(config.tagName != tagName){
40440 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
40442 domBuilder.endElement(config.uri,config.localName,tagName);
40444 for(var prefix in localNSMap){
40445 domBuilder.endPrefixMapping(prefix) ;
40451 case '?':// <?...?>
40452 locator&&position(tagStart);
40453 end = parseInstruction(source,tagStart,domBuilder);
40455 case '!':// <!doctype,<![CDATA,<!--
40456 locator&&position(tagStart);
40457 end = parseDCC(source,tagStart,domBuilder,errorHandler);
40461 locator&&position(tagStart);
40463 var el = new ElementAttributes();
40466 var end = parseElementStartPart(source,tagStart,el,entityReplacer,errorHandler);
40467 var len = el.length;
40471 //attribute position fixed
40472 for(var i = 0;i<len;i++){
40474 position(a.offset);
40475 a.offset = copyLocator(locator,{});
40480 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
40482 if(!entityMap.nbsp){
40483 errorHandler.warning('unclosed xml attribute');
40486 appendElement(el,domBuilder,parseStack);
40489 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
40490 end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
40496 errorHandler.error('element parse error: '+e);
40502 //TODO: 这里有可能sax回退,有位置错误风险
40503 appendText(Math.max(tagStart,start)+1);
40507 function copyLocator(f,t){
40508 t.lineNumber = f.lineNumber;
40509 t.columnNumber = f.columnNumber;
40514 * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
40515 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40517 function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
40521 var s = S_TAG;//status
40523 var c = source.charAt(p);
40526 if(s === S_ATTR){//attrName
40527 attrName = source.slice(start,p);
40529 }else if(s === S_ATTR_S){
40532 //fatalError: equal must after attrName or space after attrName
40533 throw new Error('attribute equal must after attrName');
40538 if(s === S_EQ){//equal
40540 p = source.indexOf(c,start);
40542 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40543 el.add(attrName,value,start-1);
40546 //fatalError: no end quot match
40547 throw new Error('attribute value no end \''+c+'\' match');
40549 }else if(s == S_V){
40550 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40551 //console.log(attrName,value,start,p)
40552 el.add(attrName,value,start);
40554 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
40558 //fatalError: no equal before
40559 throw new Error('attribute value must after "="');
40565 el.setTagName(source.slice(start,p));
40577 throw new Error("attribute invalid close char('/')")
40580 case ''://end document
40581 //throw new Error('unexpected end of input')
40582 errorHandler.error('unexpected end of input');
40586 el.setTagName(source.slice(start,p));
40591 case S_V://Compatible state
40593 value = source.slice(start,p);
40594 if(value.slice(-1) === '/'){
40596 value = value.slice(0,-1);
40599 if(s === S_ATTR_S){
40603 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40604 el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
40606 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
40607 el.add(value,value,start);
40611 throw new Error('attribute value missed!!');
40613 // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
40615 /*xml space '\x20' | #x9 | #xD | #xA; */
40619 if(c<= ' '){//space
40622 el.setTagName(source.slice(start,p));//tagName
40626 attrName = source.slice(start,p);
40630 var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
40631 errorHandler.warning('attribute "'+value+'" missed quot(")!!');
40632 el.add(attrName,value,start);
40644 //S_TAG, S_ATTR, S_EQ, S_V
40645 //S_ATTR_S, S_E, S_S, S_C
40647 //case S_TAG:void();break;
40648 //case S_ATTR:void();break;
40649 //case S_V:void();break;
40651 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!');
40652 el.add(attrName,attrName,start);
40657 errorHandler.warning('attribute space is required"'+attrName+'"!!');
40667 throw new Error("elements closed character '/' and '>' must be connected to");
40675 * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
40677 function appendElement(el,domBuilder,parseStack){
40678 var tagName = el.tagName;
40679 var localNSMap = null;
40680 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
40684 var qName = a.qName;
40685 var value = a.value;
40686 var nsp = qName.indexOf(':');
40688 var prefix = a.prefix = qName.slice(0,nsp);
40689 var localName = qName.slice(nsp+1);
40690 var nsPrefix = prefix === 'xmlns' && localName;
40694 nsPrefix = qName === 'xmlns' && '';
40696 //can not set prefix,because prefix !== ''
40697 a.localName = localName ;
40698 //prefix == null for no ns prefix attribute
40699 if(nsPrefix !== false){//hack!!
40700 if(localNSMap == null){
40702 //console.log(currentNSMap,0)
40703 _copy(currentNSMap,currentNSMap={});
40704 //console.log(currentNSMap,1)
40706 currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
40707 a.uri = 'http://www.w3.org/2000/xmlns/';
40708 domBuilder.startPrefixMapping(nsPrefix, value);
40714 var prefix = a.prefix;
40715 if(prefix){//no prefix attribute has no namespace
40716 if(prefix === 'xml'){
40717 a.uri = 'http://www.w3.org/XML/1998/namespace';
40718 }if(prefix !== 'xmlns'){
40719 a.uri = currentNSMap[prefix];
40721 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
40725 var nsp = tagName.indexOf(':');
40727 prefix = el.prefix = tagName.slice(0,nsp);
40728 localName = el.localName = tagName.slice(nsp+1);
40730 prefix = null;//important!!
40731 localName = el.localName = tagName;
40733 //no prefix element has default namespace
40734 var ns = el.uri = currentNSMap[prefix || ''];
40735 domBuilder.startElement(ns,localName,tagName,el);
40736 //endPrefixMapping and startPrefixMapping have not any help for dom builder
40737 //localNSMap = null
40739 domBuilder.endElement(ns,localName,tagName);
40741 for(prefix in localNSMap){
40742 domBuilder.endPrefixMapping(prefix);
40746 el.currentNSMap = currentNSMap;
40747 el.localNSMap = localNSMap;
40748 parseStack.push(el);
40751 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
40752 if(/^(?:script|textarea)$/i.test(tagName)){
40753 var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
40754 var text = source.substring(elStartEnd+1,elEndStart);
40755 if(/[&<]/.test(text)){
40756 if(/^script$/i.test(tagName)){
40757 //if(!/\]\]>/.test(text)){
40758 //lexHandler.startCDATA();
40759 domBuilder.characters(text,0,text.length);
40760 //lexHandler.endCDATA();
40763 }//}else{//text area
40764 text = text.replace(/&#?\w+;/g,entityReplacer);
40765 domBuilder.characters(text,0,text.length);
40771 return elStartEnd+1;
40773 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
40774 //if(tagName in closeMap){
40775 var pos = closeMap[tagName];
40777 //console.log(tagName)
40778 pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>');
40780 return pos<elStartEnd;
40783 function _copy(source,target){
40784 for(var n in source){target[n] = source[n];}
40786 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
40787 var next= source.charAt(start+2);
40790 if(source.charAt(start + 3) === '-'){
40791 var end = source.indexOf('-->',start+4);
40792 //append comment source.substring(4,end)//<!--
40794 domBuilder.comment(source,start+4,end-start-4);
40797 errorHandler.error("Unclosed comment");
40805 if(source.substr(start+3,6) == 'CDATA['){
40806 var end = source.indexOf(']]>',start+9);
40807 domBuilder.startCDATA();
40808 domBuilder.characters(source,start+9,end-start-9);
40809 domBuilder.endCDATA();
40813 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
40814 var matchs = split(source,start);
40815 var len = matchs.length;
40816 if(len>1 && /!doctype/i.test(matchs[0][0])){
40817 var name = matchs[1][0];
40818 var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
40819 var sysid = len>4 && matchs[4][0];
40820 var lastMatch = matchs[len-1];
40821 domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
40822 sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
40823 domBuilder.endDTD();
40825 return lastMatch.index+lastMatch[0].length
40833 function parseInstruction(source,start,domBuilder){
40834 var end = source.indexOf('?>',start);
40836 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
40838 var len = match[0].length;
40839 domBuilder.processingInstruction(match[1], match[2]) ;
40851 function ElementAttributes(source){
40854 ElementAttributes.prototype = {
40855 setTagName:function(tagName){
40856 if(!tagNamePattern.test(tagName)){
40857 throw new Error('invalid tagName:'+tagName)
40859 this.tagName = tagName;
40861 add:function(qName,value,offset){
40862 if(!tagNamePattern.test(qName)){
40863 throw new Error('invalid attribute:'+qName)
40865 this[this.length++] = {qName:qName,value:value,offset:offset};
40868 getLocalName:function(i){return this[i].localName},
40869 getOffset:function(i){return this[i].offset},
40870 getQName:function(i){return this[i].qName},
40871 getURI:function(i){return this[i].uri},
40872 getValue:function(i){return this[i].value}
40873 // ,getIndex:function(uri, localName)){
40880 // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
40881 // getType:function(uri,localName){}
40882 // getType:function(i){},
40888 function _set_proto_(thiz,parent){
40889 thiz.__proto__ = parent;
40892 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
40893 _set_proto_ = function(thiz,parent){
40895 p.prototype = parent;
40897 for(parent in thiz){
40898 p[parent] = thiz[parent];
40904 function split(source,start){
40907 var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
40908 reg.lastIndex = start;
40909 reg.exec(source);//skip <
40910 while(match = reg.exec(source)){
40912 if(match[1])return buf;
40916 if(typeof commonjsRequire == 'function'){
40917 exports.XMLReader = XMLReader;
40921 var dom = createCommonjsModule(function (module, exports) {
40924 * Object DOMException
40925 * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
40926 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
40929 function copy(src,dest){
40935 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
40936 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
40938 function _extends(Class,Super){
40939 var pt = Class.prototype;
40941 var ppt = Object.create(Super.prototype);
40942 pt.__proto__ = ppt;
40944 if(!(pt instanceof Super)){
40946 t.prototype = Super.prototype;
40949 Class.prototype = pt = t;
40951 if(pt.constructor != Class){
40952 if(typeof Class != 'function'){
40953 console.error("unknow Class:"+Class);
40955 pt.constructor = Class;
40958 var htmlns = 'http://www.w3.org/1999/xhtml';
40961 var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
40962 var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
40963 var TEXT_NODE = NodeType.TEXT_NODE = 3;
40964 var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
40965 var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
40966 var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
40967 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
40968 var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
40969 var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
40970 var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
40971 var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
40972 var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
40975 var ExceptionCode = {};
40976 var ExceptionMessage = {};
40977 var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
40978 var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
40979 var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
40980 var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
40981 var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
40982 var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
40983 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
40984 var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
40985 var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
40986 var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
40988 var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
40989 var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
40990 var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
40991 var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
40992 var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
40995 function DOMException(code, message) {
40996 if(message instanceof Error){
40997 var error = message;
41000 Error.call(this, ExceptionMessage[code]);
41001 this.message = ExceptionMessage[code];
41002 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
41005 if(message) this.message = this.message + ": " + message;
41008 DOMException.prototype = Error.prototype;
41009 copy(ExceptionCode,DOMException);
41011 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
41012 * 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.
41013 * The items in the NodeList are accessible via an integral index, starting from 0.
41015 function NodeList() {
41017 NodeList.prototype = {
41019 * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
41024 * 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.
41026 * @param index unsigned long
41027 * Index into the collection.
41029 * The node at the indexth position in the NodeList, or null if that is not a valid index.
41031 item: function(index) {
41032 return this[index] || null;
41034 toString:function(){
41035 for(var buf = [], i = 0;i<this.length;i++){
41036 serializeToString(this[i],buf);
41038 return buf.join('');
41041 function LiveNodeList(node,refresh){
41043 this._refresh = refresh;
41044 _updateLiveList(this);
41046 function _updateLiveList(list){
41047 var inc = list._node._inc || list._node.ownerDocument._inc;
41048 if(list._inc != inc){
41049 var ls = list._refresh(list._node);
41050 //console.log(ls.length)
41051 __set__(list,'length',ls.length);
41056 LiveNodeList.prototype.item = function(i){
41057 _updateLiveList(this);
41061 _extends(LiveNodeList,NodeList);
41064 * 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.
41065 * NamedNodeMap objects in the DOM are live.
41066 * used for attributes or DocumentType entities
41068 function NamedNodeMap() {
41071 function _findNodeIndex(list,node){
41072 var i = list.length;
41074 if(list[i] === node){return i}
41078 function _addNamedNode(el,list,newAttr,oldAttr){
41080 list[_findNodeIndex(list,oldAttr)] = newAttr;
41082 list[list.length++] = newAttr;
41085 newAttr.ownerElement = el;
41086 var doc = el.ownerDocument;
41088 oldAttr && _onRemoveAttribute(doc,el,oldAttr);
41089 _onAddAttribute(doc,el,newAttr);
41093 function _removeNamedNode(el,list,attr){
41094 var i = _findNodeIndex(list,attr);
41096 var lastIndex = list.length-1;
41097 while(i<lastIndex){
41098 list[i] = list[++i];
41100 list.length = lastIndex;
41102 var doc = el.ownerDocument;
41104 _onRemoveAttribute(doc,el,attr);
41105 attr.ownerElement = null;
41109 throw DOMException(NOT_FOUND_ERR,new Error())
41112 NamedNodeMap.prototype = {
41114 item:NodeList.prototype.item,
41115 getNamedItem: function(key) {
41116 // if(key.indexOf(':')>0 || key == 'xmlns'){
41119 var i = this.length;
41121 var attr = this[i];
41122 if(attr.nodeName == key){
41127 setNamedItem: function(attr) {
41128 var el = attr.ownerElement;
41129 if(el && el!=this._ownerElement){
41130 throw new DOMException(INUSE_ATTRIBUTE_ERR);
41132 var oldAttr = this.getNamedItem(attr.nodeName);
41133 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41137 setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
41138 var el = attr.ownerElement, oldAttr;
41139 if(el && el!=this._ownerElement){
41140 throw new DOMException(INUSE_ATTRIBUTE_ERR);
41142 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
41143 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41148 removeNamedItem: function(key) {
41149 var attr = this.getNamedItem(key);
41150 _removeNamedNode(this._ownerElement,this,attr);
41154 },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
41157 removeNamedItemNS:function(namespaceURI,localName){
41158 var attr = this.getNamedItemNS(namespaceURI,localName);
41159 _removeNamedNode(this._ownerElement,this,attr);
41162 getNamedItemNS: function(namespaceURI, localName) {
41163 var i = this.length;
41165 var node = this[i];
41166 if(node.localName == localName && node.namespaceURI == namespaceURI){
41174 * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
41176 function DOMImplementation(/* Object */ features) {
41177 this._features = {};
41179 for (var feature in features) {
41180 this._features = features[feature];
41185 DOMImplementation.prototype = {
41186 hasFeature: function(/* string */ feature, /* string */ version) {
41187 var versions = this._features[feature.toLowerCase()];
41188 if (versions && (!version || version in versions)) {
41194 // Introduced in DOM Level 2:
41195 createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
41196 var doc = new Document();
41197 doc.implementation = this;
41198 doc.childNodes = new NodeList();
41199 doc.doctype = doctype;
41201 doc.appendChild(doctype);
41204 var root = doc.createElementNS(namespaceURI,qualifiedName);
41205 doc.appendChild(root);
41209 // Introduced in DOM Level 2:
41210 createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
41211 var node = new DocumentType();
41212 node.name = qualifiedName;
41213 node.nodeName = qualifiedName;
41214 node.publicId = publicId;
41215 node.systemId = systemId;
41216 // Introduced in DOM Level 2:
41217 //readonly attribute DOMString internalSubset;
41220 // readonly attribute NamedNodeMap entities;
41221 // readonly attribute NamedNodeMap notations;
41228 * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
41237 previousSibling : null,
41238 nextSibling : null,
41242 ownerDocument : null,
41244 namespaceURI : null,
41247 // Modified in DOM Level 2:
41248 insertBefore:function(newChild, refChild){//raises
41249 return _insertBefore(this,newChild,refChild);
41251 replaceChild:function(newChild, oldChild){//raises
41252 this.insertBefore(newChild,oldChild);
41254 this.removeChild(oldChild);
41257 removeChild:function(oldChild){
41258 return _removeChild(this,oldChild);
41260 appendChild:function(newChild){
41261 return this.insertBefore(newChild,null);
41263 hasChildNodes:function(){
41264 return this.firstChild != null;
41266 cloneNode:function(deep){
41267 return cloneNode(this.ownerDocument||this,this,deep);
41269 // Modified in DOM Level 2:
41270 normalize:function(){
41271 var child = this.firstChild;
41273 var next = child.nextSibling;
41274 if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
41275 this.removeChild(next);
41276 child.appendData(next.data);
41283 // Introduced in DOM Level 2:
41284 isSupported:function(feature, version){
41285 return this.ownerDocument.implementation.hasFeature(feature,version);
41287 // Introduced in DOM Level 2:
41288 hasAttributes:function(){
41289 return this.attributes.length>0;
41291 lookupPrefix:function(namespaceURI){
41294 var map = el._nsMap;
41298 if(map[n] == namespaceURI){
41303 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
41307 // Introduced in DOM Level 3:
41308 lookupNamespaceURI:function(prefix){
41311 var map = el._nsMap;
41315 return map[prefix] ;
41318 el = el.nodeType == 2?el.ownerDocument : el.parentNode;
41322 // Introduced in DOM Level 3:
41323 isDefaultNamespace:function(namespaceURI){
41324 var prefix = this.lookupPrefix(namespaceURI);
41325 return prefix == null;
41330 function _xmlEncoder(c){
41331 return c == '<' && '<' ||
41332 c == '>' && '>' ||
41333 c == '&' && '&' ||
41334 c == '"' && '"' ||
41335 '&#'+c.charCodeAt()+';'
41339 copy(NodeType,Node);
41340 copy(NodeType,Node.prototype);
41343 * @param callback return true for continue,false for break
41344 * @return boolean true: break visit;
41346 function _visitNode(node,callback){
41347 if(callback(node)){
41350 if(node = node.firstChild){
41352 if(_visitNode(node,callback)){return true}
41353 }while(node=node.nextSibling)
41359 function Document(){
41361 function _onAddAttribute(doc,el,newAttr){
41363 var ns = newAttr.namespaceURI;
41364 if(ns == 'http://www.w3.org/2000/xmlns/'){
41366 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
41369 function _onRemoveAttribute(doc,el,newAttr,remove){
41371 var ns = newAttr.namespaceURI;
41372 if(ns == 'http://www.w3.org/2000/xmlns/'){
41374 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
41377 function _onUpdateChild(doc,el,newChild){
41378 if(doc && doc._inc){
41380 //update childNodes
41381 var cs = el.childNodes;
41383 cs[cs.length++] = newChild;
41386 var child = el.firstChild;
41390 child =child.nextSibling;
41401 * writeable properties:
41402 * nodeValue,Attr:value,CharacterData:data
41405 function _removeChild(parentNode,child){
41406 var previous = child.previousSibling;
41407 var next = child.nextSibling;
41409 previous.nextSibling = next;
41411 parentNode.firstChild = next;
41414 next.previousSibling = previous;
41416 parentNode.lastChild = previous;
41418 _onUpdateChild(parentNode.ownerDocument,parentNode);
41422 * preformance key(refChild == null)
41424 function _insertBefore(parentNode,newChild,nextChild){
41425 var cp = newChild.parentNode;
41427 cp.removeChild(newChild);//remove and update
41429 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41430 var newFirst = newChild.firstChild;
41431 if (newFirst == null) {
41434 var newLast = newChild.lastChild;
41436 newFirst = newLast = newChild;
41438 var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
41440 newFirst.previousSibling = pre;
41441 newLast.nextSibling = nextChild;
41445 pre.nextSibling = newFirst;
41447 parentNode.firstChild = newFirst;
41449 if(nextChild == null){
41450 parentNode.lastChild = newLast;
41452 nextChild.previousSibling = newLast;
41455 newFirst.parentNode = parentNode;
41456 }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
41457 _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
41458 //console.log(parentNode.lastChild.nextSibling == null)
41459 if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
41460 newChild.firstChild = newChild.lastChild = null;
41464 function _appendSingleChild(parentNode,newChild){
41465 var cp = newChild.parentNode;
41467 var pre = parentNode.lastChild;
41468 cp.removeChild(newChild);//remove and update
41469 var pre = parentNode.lastChild;
41471 var pre = parentNode.lastChild;
41472 newChild.parentNode = parentNode;
41473 newChild.previousSibling = pre;
41474 newChild.nextSibling = null;
41476 pre.nextSibling = newChild;
41478 parentNode.firstChild = newChild;
41480 parentNode.lastChild = newChild;
41481 _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
41483 //console.log("__aa",parentNode.lastChild.nextSibling == null)
41485 Document.prototype = {
41486 //implementation : null,
41487 nodeName : '#document',
41488 nodeType : DOCUMENT_NODE,
41490 documentElement : null,
41493 insertBefore : function(newChild, refChild){//raises
41494 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
41495 var child = newChild.firstChild;
41497 var next = child.nextSibling;
41498 this.insertBefore(child,refChild);
41503 if(this.documentElement == null && newChild.nodeType == 1){
41504 this.documentElement = newChild;
41507 return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
41509 removeChild : function(oldChild){
41510 if(this.documentElement == oldChild){
41511 this.documentElement = null;
41513 return _removeChild(this,oldChild);
41515 // Introduced in DOM Level 2:
41516 importNode : function(importedNode,deep){
41517 return importNode(this,importedNode,deep);
41519 // Introduced in DOM Level 2:
41520 getElementById : function(id){
41522 _visitNode(this.documentElement,function(node){
41523 if(node.nodeType == 1){
41524 if(node.getAttribute('id') == id){
41533 //document factory method:
41534 createElement : function(tagName){
41535 var node = new Element();
41536 node.ownerDocument = this;
41537 node.nodeName = tagName;
41538 node.tagName = tagName;
41539 node.childNodes = new NodeList();
41540 var attrs = node.attributes = new NamedNodeMap();
41541 attrs._ownerElement = node;
41544 createDocumentFragment : function(){
41545 var node = new DocumentFragment();
41546 node.ownerDocument = this;
41547 node.childNodes = new NodeList();
41550 createTextNode : function(data){
41551 var node = new Text();
41552 node.ownerDocument = this;
41553 node.appendData(data);
41556 createComment : function(data){
41557 var node = new Comment();
41558 node.ownerDocument = this;
41559 node.appendData(data);
41562 createCDATASection : function(data){
41563 var node = new CDATASection();
41564 node.ownerDocument = this;
41565 node.appendData(data);
41568 createProcessingInstruction : function(target,data){
41569 var node = new ProcessingInstruction();
41570 node.ownerDocument = this;
41571 node.tagName = node.target = target;
41572 node.nodeValue= node.data = data;
41575 createAttribute : function(name){
41576 var node = new Attr();
41577 node.ownerDocument = this;
41579 node.nodeName = name;
41580 node.localName = name;
41581 node.specified = true;
41584 createEntityReference : function(name){
41585 var node = new EntityReference();
41586 node.ownerDocument = this;
41587 node.nodeName = name;
41590 // Introduced in DOM Level 2:
41591 createElementNS : function(namespaceURI,qualifiedName){
41592 var node = new Element();
41593 var pl = qualifiedName.split(':');
41594 var attrs = node.attributes = new NamedNodeMap();
41595 node.childNodes = new NodeList();
41596 node.ownerDocument = this;
41597 node.nodeName = qualifiedName;
41598 node.tagName = qualifiedName;
41599 node.namespaceURI = namespaceURI;
41600 if(pl.length == 2){
41601 node.prefix = pl[0];
41602 node.localName = pl[1];
41604 //el.prefix = null;
41605 node.localName = qualifiedName;
41607 attrs._ownerElement = node;
41610 // Introduced in DOM Level 2:
41611 createAttributeNS : function(namespaceURI,qualifiedName){
41612 var node = new Attr();
41613 var pl = qualifiedName.split(':');
41614 node.ownerDocument = this;
41615 node.nodeName = qualifiedName;
41616 node.name = qualifiedName;
41617 node.namespaceURI = namespaceURI;
41618 node.specified = true;
41619 if(pl.length == 2){
41620 node.prefix = pl[0];
41621 node.localName = pl[1];
41623 //el.prefix = null;
41624 node.localName = qualifiedName;
41629 _extends(Document,Node);
41632 function Element() {
41635 Element.prototype = {
41636 nodeType : ELEMENT_NODE,
41637 hasAttribute : function(name){
41638 return this.getAttributeNode(name)!=null;
41640 getAttribute : function(name){
41641 var attr = this.getAttributeNode(name);
41642 return attr && attr.value || '';
41644 getAttributeNode : function(name){
41645 return this.attributes.getNamedItem(name);
41647 setAttribute : function(name, value){
41648 var attr = this.ownerDocument.createAttribute(name);
41649 attr.value = attr.nodeValue = "" + value;
41650 this.setAttributeNode(attr);
41652 removeAttribute : function(name){
41653 var attr = this.getAttributeNode(name);
41654 attr && this.removeAttributeNode(attr);
41657 //four real opeartion method
41658 appendChild:function(newChild){
41659 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41660 return this.insertBefore(newChild,null);
41662 return _appendSingleChild(this,newChild);
41665 setAttributeNode : function(newAttr){
41666 return this.attributes.setNamedItem(newAttr);
41668 setAttributeNodeNS : function(newAttr){
41669 return this.attributes.setNamedItemNS(newAttr);
41671 removeAttributeNode : function(oldAttr){
41672 return this.attributes.removeNamedItem(oldAttr.nodeName);
41674 //get real attribute name,and remove it by removeAttributeNode
41675 removeAttributeNS : function(namespaceURI, localName){
41676 var old = this.getAttributeNodeNS(namespaceURI, localName);
41677 old && this.removeAttributeNode(old);
41680 hasAttributeNS : function(namespaceURI, localName){
41681 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
41683 getAttributeNS : function(namespaceURI, localName){
41684 var attr = this.getAttributeNodeNS(namespaceURI, localName);
41685 return attr && attr.value || '';
41687 setAttributeNS : function(namespaceURI, qualifiedName, value){
41688 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
41689 attr.value = attr.nodeValue = "" + value;
41690 this.setAttributeNode(attr);
41692 getAttributeNodeNS : function(namespaceURI, localName){
41693 return this.attributes.getNamedItemNS(namespaceURI, localName);
41696 getElementsByTagName : function(tagName){
41697 return new LiveNodeList(this,function(base){
41699 _visitNode(base,function(node){
41700 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
41707 getElementsByTagNameNS : function(namespaceURI, localName){
41708 return new LiveNodeList(this,function(base){
41710 _visitNode(base,function(node){
41711 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
41719 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
41720 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
41723 _extends(Element,Node);
41726 Attr.prototype.nodeType = ATTRIBUTE_NODE;
41727 _extends(Attr,Node);
41730 function CharacterData() {
41732 CharacterData.prototype = {
41734 substringData : function(offset, count) {
41735 return this.data.substring(offset, offset+count);
41737 appendData: function(text) {
41738 text = this.data+text;
41739 this.nodeValue = this.data = text;
41740 this.length = text.length;
41742 insertData: function(offset,text) {
41743 this.replaceData(offset,0,text);
41746 appendChild:function(newChild){
41747 //if(!(newChild instanceof CharacterData)){
41748 throw new Error(ExceptionMessage[3])
41750 return Node.prototype.appendChild.apply(this,arguments)
41752 deleteData: function(offset, count) {
41753 this.replaceData(offset,count,"");
41755 replaceData: function(offset, count, text) {
41756 var start = this.data.substring(0,offset);
41757 var end = this.data.substring(offset+count);
41758 text = start + text + end;
41759 this.nodeValue = this.data = text;
41760 this.length = text.length;
41763 _extends(CharacterData,Node);
41767 nodeName : "#text",
41768 nodeType : TEXT_NODE,
41769 splitText : function(offset) {
41770 var text = this.data;
41771 var newText = text.substring(offset);
41772 text = text.substring(0, offset);
41773 this.data = this.nodeValue = text;
41774 this.length = text.length;
41775 var newNode = this.ownerDocument.createTextNode(newText);
41776 if(this.parentNode){
41777 this.parentNode.insertBefore(newNode, this.nextSibling);
41782 _extends(Text,CharacterData);
41783 function Comment() {
41785 Comment.prototype = {
41786 nodeName : "#comment",
41787 nodeType : COMMENT_NODE
41789 _extends(Comment,CharacterData);
41791 function CDATASection() {
41793 CDATASection.prototype = {
41794 nodeName : "#cdata-section",
41795 nodeType : CDATA_SECTION_NODE
41797 _extends(CDATASection,CharacterData);
41800 function DocumentType() {
41802 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
41803 _extends(DocumentType,Node);
41805 function Notation() {
41807 Notation.prototype.nodeType = NOTATION_NODE;
41808 _extends(Notation,Node);
41810 function Entity() {
41812 Entity.prototype.nodeType = ENTITY_NODE;
41813 _extends(Entity,Node);
41815 function EntityReference() {
41817 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
41818 _extends(EntityReference,Node);
41820 function DocumentFragment() {
41822 DocumentFragment.prototype.nodeName = "#document-fragment";
41823 DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
41824 _extends(DocumentFragment,Node);
41827 function ProcessingInstruction() {
41829 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
41830 _extends(ProcessingInstruction,Node);
41831 function XMLSerializer(){}
41832 XMLSerializer.prototype.serializeToString = function(node,attributeSorter){
41833 return node.toString(attributeSorter);
41835 Node.prototype.toString =function(attributeSorter){
41837 serializeToString(this,buf,attributeSorter);
41838 return buf.join('');
41840 function serializeToString(node,buf,attributeSorter,isHTML){
41841 switch(node.nodeType){
41843 var attrs = node.attributes;
41844 var len = attrs.length;
41845 var child = node.firstChild;
41846 var nodeName = node.tagName;
41847 isHTML = (htmlns === node.namespaceURI) ||isHTML;
41848 buf.push('<',nodeName);
41849 if(attributeSorter){
41850 buf.sort.apply(attrs, attributeSorter);
41852 for(var i=0;i<len;i++){
41853 serializeToString(attrs.item(i),buf,attributeSorter,isHTML);
41855 if(child || isHTML && !/^(?:meta|link|img|br|hr|input|button)$/i.test(nodeName)){
41857 //if is cdata child node
41858 if(isHTML && /^script$/i.test(nodeName)){
41860 buf.push(child.data);
41864 serializeToString(child,buf,attributeSorter,isHTML);
41865 child = child.nextSibling;
41868 buf.push('</',nodeName,'>');
41873 case DOCUMENT_NODE:
41874 case DOCUMENT_FRAGMENT_NODE:
41875 var child = node.firstChild;
41877 serializeToString(child,buf,attributeSorter,isHTML);
41878 child = child.nextSibling;
41881 case ATTRIBUTE_NODE:
41882 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
41884 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
41885 case CDATA_SECTION_NODE:
41886 return buf.push( '<![CDATA[',node.data,']]>');
41888 return buf.push( "<!--",node.data,"-->");
41889 case DOCUMENT_TYPE_NODE:
41890 var pubid = node.publicId;
41891 var sysid = node.systemId;
41892 buf.push('<!DOCTYPE ',node.name);
41894 buf.push(' PUBLIC "',pubid);
41895 if (sysid && sysid!='.') {
41896 buf.push( '" "',sysid);
41899 }else if(sysid && sysid!='.'){
41900 buf.push(' SYSTEM "',sysid,'">');
41902 var sub = node.internalSubset;
41904 buf.push(" [",sub,"]");
41909 case PROCESSING_INSTRUCTION_NODE:
41910 return buf.push( "<?",node.target," ",node.data,"?>");
41911 case ENTITY_REFERENCE_NODE:
41912 return buf.push( '&',node.nodeName,';');
41913 //case ENTITY_NODE:
41914 //case NOTATION_NODE:
41916 buf.push('??',node.nodeName);
41919 function importNode(doc,node,deep){
41921 switch (node.nodeType) {
41923 node2 = node.cloneNode(false);
41924 node2.ownerDocument = doc;
41925 //var attrs = node2.attributes;
41926 //var len = attrs.length;
41927 //for(var i=0;i<len;i++){
41928 //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
41930 case DOCUMENT_FRAGMENT_NODE:
41932 case ATTRIBUTE_NODE:
41935 //case ENTITY_REFERENCE_NODE:
41936 //case PROCESSING_INSTRUCTION_NODE:
41937 ////case TEXT_NODE:
41938 //case CDATA_SECTION_NODE:
41939 //case COMMENT_NODE:
41942 //case DOCUMENT_NODE:
41943 //case DOCUMENT_TYPE_NODE:
41944 //cannot be imported.
41945 //case ENTITY_NODE:
41946 //case NOTATION_NODE:
41947 //can not hit in level3
41951 node2 = node.cloneNode(false);//false
41953 node2.ownerDocument = doc;
41954 node2.parentNode = null;
41956 var child = node.firstChild;
41958 node2.appendChild(importNode(doc,child,deep));
41959 child = child.nextSibling;
41965 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
41966 // attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
41967 function cloneNode(doc,node,deep){
41968 var node2 = new node.constructor();
41969 for(var n in node){
41971 if(typeof v != 'object' ){
41977 if(node.childNodes){
41978 node2.childNodes = new NodeList();
41980 node2.ownerDocument = doc;
41981 switch (node2.nodeType) {
41983 var attrs = node.attributes;
41984 var attrs2 = node2.attributes = new NamedNodeMap();
41985 var len = attrs.length;
41986 attrs2._ownerElement = node2;
41987 for(var i=0;i<len;i++){
41988 node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
41991 case ATTRIBUTE_NODE:
41995 var child = node.firstChild;
41997 node2.appendChild(cloneNode(doc,child,deep));
41998 child = child.nextSibling;
42004 function __set__(object,key,value){
42005 object[key] = value;
42009 if(Object.defineProperty){
42010 Object.defineProperty(LiveNodeList.prototype,'length',{
42012 _updateLiveList(this);
42013 return this.$$length;
42016 Object.defineProperty(Node.prototype,'textContent',{
42018 return getTextContent(this);
42020 set:function(data){
42021 switch(this.nodeType){
42024 while(this.firstChild){
42025 this.removeChild(this.firstChild);
42027 if(data || String(data)){
42028 this.appendChild(this.ownerDocument.createTextNode(data));
42034 this.value = value;
42035 this.nodeValue = data;
42040 function getTextContent(node){
42041 switch(node.nodeType){
42045 node = node.firstChild;
42047 if(node.nodeType!==7 && node.nodeType !==8){
42048 buf.push(getTextContent(node));
42050 node = node.nextSibling;
42052 return buf.join('');
42054 return node.nodeValue;
42057 __set__ = function(object,key,value){
42058 //console.log(value)
42059 object['$$'+key] = value;
42065 if(typeof commonjsRequire == 'function'){
42066 exports.DOMImplementation = DOMImplementation;
42067 exports.XMLSerializer = XMLSerializer;
42071 var domParser = createCommonjsModule(function (module, exports) {
42072 function DOMParser(options){
42073 this.options = options ||{locator:{}};
42076 DOMParser.prototype.parseFromString = function(source,mimeType){
42077 var options = this.options;
42078 var sax$$1 = new XMLReader();
42079 var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
42080 var errorHandler = options.errorHandler;
42081 var locator = options.locator;
42082 var defaultNSMap = options.xmlns||{};
42083 var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
42085 domBuilder.setDocumentLocator(locator);
42088 sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
42089 sax$$1.domBuilder = options.domBuilder || domBuilder;
42090 if(/\/x?html?$/.test(mimeType)){
42091 entityMap.nbsp = '\xa0';
42092 entityMap.copy = '\xa9';
42093 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
42095 defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
42097 sax$$1.parse(source,defaultNSMap,entityMap);
42099 sax$$1.errorHandler.error("invalid document source");
42101 return domBuilder.document;
42103 function buildErrorHandler(errorImpl,domBuilder,locator){
42105 if(domBuilder instanceof DOMHandler){
42108 errorImpl = domBuilder ;
42110 var errorHandler = {};
42111 var isCallback = errorImpl instanceof Function;
42112 locator = locator||{};
42113 function build(key){
42114 var fn = errorImpl[key];
42115 if(!fn && isCallback){
42116 fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
42118 errorHandler[key] = fn && function(msg){
42119 fn('[xmldom '+key+']\t'+msg+_locator(locator));
42124 build('fatalError');
42125 return errorHandler;
42128 //console.log('#\n\n\n\n\n\n\n####')
42130 * +ContentHandler+ErrorHandler
42131 * +LexicalHandler+EntityResolver2
42132 * -DeclHandler-DTDHandler
42134 * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
42135 * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
42136 * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
42138 function DOMHandler() {
42139 this.cdata = false;
42141 function position(locator,node){
42142 node.lineNumber = locator.lineNumber;
42143 node.columnNumber = locator.columnNumber;
42146 * @see org.xml.sax.ContentHandler#startDocument
42147 * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
42149 DOMHandler.prototype = {
42150 startDocument : function() {
42151 this.document = new DOMImplementation().createDocument(null, null, null);
42152 if (this.locator) {
42153 this.document.documentURI = this.locator.systemId;
42156 startElement:function(namespaceURI, localName, qName, attrs) {
42157 var doc = this.document;
42158 var el = doc.createElementNS(namespaceURI, qName||localName);
42159 var len = attrs.length;
42160 appendElement(this, el);
42161 this.currentElement = el;
42163 this.locator && position(this.locator,el);
42164 for (var i = 0 ; i < len; i++) {
42165 var namespaceURI = attrs.getURI(i);
42166 var value = attrs.getValue(i);
42167 var qName = attrs.getQName(i);
42168 var attr = doc.createAttributeNS(namespaceURI, qName);
42169 if( attr.getOffset){
42170 position(attr.getOffset(1),attr);
42172 attr.value = attr.nodeValue = value;
42173 el.setAttributeNode(attr);
42176 endElement:function(namespaceURI, localName, qName) {
42177 var current = this.currentElement;
42178 var tagName = current.tagName;
42179 this.currentElement = current.parentNode;
42181 startPrefixMapping:function(prefix, uri) {
42183 endPrefixMapping:function(prefix) {
42185 processingInstruction:function(target, data) {
42186 var ins = this.document.createProcessingInstruction(target, data);
42187 this.locator && position(this.locator,ins);
42188 appendElement(this, ins);
42190 ignorableWhitespace:function(ch, start, length) {
42192 characters:function(chars, start, length) {
42193 chars = _toString.apply(this,arguments);
42194 //console.log(chars)
42195 if(this.currentElement && chars){
42197 var charNode = this.document.createCDATASection(chars);
42198 this.currentElement.appendChild(charNode);
42200 var charNode = this.document.createTextNode(chars);
42201 this.currentElement.appendChild(charNode);
42203 this.locator && position(this.locator,charNode);
42206 skippedEntity:function(name) {
42208 endDocument:function() {
42209 this.document.normalize();
42211 setDocumentLocator:function (locator) {
42212 if(this.locator = locator){// && !('lineNumber' in locator)){
42213 locator.lineNumber = 0;
42217 comment:function(chars, start, length) {
42218 chars = _toString.apply(this,arguments);
42219 var comm = this.document.createComment(chars);
42220 this.locator && position(this.locator,comm);
42221 appendElement(this, comm);
42224 startCDATA:function() {
42225 //used in characters() methods
42228 endCDATA:function() {
42229 this.cdata = false;
42232 startDTD:function(name, publicId, systemId) {
42233 var impl = this.document.implementation;
42234 if (impl && impl.createDocumentType) {
42235 var dt = impl.createDocumentType(name, publicId, systemId);
42236 this.locator && position(this.locator,dt);
42237 appendElement(this, dt);
42241 * @see org.xml.sax.ErrorHandler
42242 * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
42244 warning:function(error) {
42245 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
42247 error:function(error) {
42248 console.error('[xmldom error]\t'+error,_locator(this.locator));
42250 fatalError:function(error) {
42251 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
42255 function _locator(l){
42257 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
42260 function _toString(chars,start,length){
42261 if(typeof chars == 'string'){
42262 return chars.substr(start,length)
42263 }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
42264 if(chars.length >= start+length || start){
42265 return new java.lang.String(chars,start,length)+'';
42272 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
42273 * used method of org.xml.sax.ext.LexicalHandler:
42274 * #comment(chars, start, length)
42277 * #startDTD(name, publicId, systemId)
42280 * IGNORED method of org.xml.sax.ext.LexicalHandler:
42282 * #startEntity(name)
42286 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
42287 * IGNORED method of org.xml.sax.ext.DeclHandler
42288 * #attributeDecl(eName, aName, type, mode, value)
42289 * #elementDecl(name, model)
42290 * #externalEntityDecl(name, publicId, systemId)
42291 * #internalEntityDecl(name, value)
42292 * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
42293 * IGNORED method of org.xml.sax.EntityResolver2
42294 * #resolveEntity(String name,String publicId,String baseURI,String systemId)
42295 * #resolveEntity(publicId, systemId)
42296 * #getExternalSubset(name, baseURI)
42297 * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
42298 * IGNORED method of org.xml.sax.DTDHandler
42299 * #notationDecl(name, publicId, systemId) {};
42300 * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
42302 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
42303 DOMHandler.prototype[key] = function(){return null};
42306 /* 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 */
42307 function appendElement (hander,node) {
42308 if (!hander.currentElement) {
42309 hander.document.appendChild(node);
42311 hander.currentElement.appendChild(node);
42313 }//appendChild and setAttributeNS are preformance key
42315 if(typeof commonjsRequire == 'function'){
42316 var XMLReader = sax.XMLReader;
42317 var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
42318 exports.XMLSerializer = dom.XMLSerializer ;
42319 exports.DOMParser = DOMParser;
42323 var togeojson = createCommonjsModule(function (module, exports) {
42324 var toGeoJSON = (function() {
42327 var removeSpace = /\s*/g,
42328 trimSpace = /^\s*|\s*$/g,
42329 splitSpace = /\s+/;
42330 // generate a short, numeric hash of a string
42331 function okhash(x) {
42332 if (!x || !x.length) return 0;
42333 for (var i = 0, h = 0; i < x.length; i++) {
42334 h = ((h << 5) - h) + x.charCodeAt(i) | 0;
42337 // all Y children of X
42338 function get(x, y) { return x.getElementsByTagName(y); }
42339 function attr(x, y) { return x.getAttribute(y); }
42340 function attrf(x, y) { return parseFloat(attr(x, y)); }
42341 // one Y child of X, if any, otherwise null
42342 function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
42343 // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
42344 function norm(el) { if (el.normalize) { el.normalize(); } return el; }
42345 // cast array x into numbers
42346 function numarray(x) {
42347 for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
42350 // get the content of a text node, if any
42351 function nodeVal(x) {
42352 if (x) { norm(x); }
42353 return (x && x.textContent) || '';
42355 // get the contents of multiple text nodes, if present
42356 function getMulti(x, ys) {
42358 for (k = 0; k < ys.length; k++) {
42359 n = get1(x, ys[k]);
42360 if (n) o[ys[k]] = nodeVal(n);
42364 // add properties of Y to X, overwriting if present in both
42365 function extend(x, y) { for (var k in y) x[k] = y[k]; }
42366 // get one coordinate from a coordinate array, if any
42367 function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
42368 // get all coordinates from a coordinate array as [[],[]]
42369 function coord(v) {
42370 var coords = v.replace(trimSpace, '').split(splitSpace),
42372 for (var i = 0; i < coords.length; i++) {
42373 o.push(coord1(coords[i]));
42377 function coordPair(x) {
42378 var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
42379 ele = get1(x, 'ele'),
42380 // handle namespaced attribute in browser
42381 heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
42382 time = get1(x, 'time'),
42385 e = parseFloat(nodeVal(ele));
42392 time: time ? nodeVal(time) : null,
42393 heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
42397 // create a new feature collection parent object
42400 type: 'FeatureCollection',
42406 if (typeof XMLSerializer !== 'undefined') {
42407 /* istanbul ignore next */
42408 serializer = new XMLSerializer();
42409 // only require xmldom in a node environment
42410 } else if ('object' === 'object' && typeof process === 'object' && !process.browser) {
42411 serializer = new (domParser.XMLSerializer)();
42413 function xml2str(str) {
42414 // IE9 will create a new XMLSerializer but it'll crash immediately.
42415 // This line is ignored because we don't run coverage tests in IE9
42416 /* istanbul ignore next */
42417 if (str.xml !== undefined) return str.xml;
42418 return serializer.serializeToString(str);
42422 kml: function(doc) {
42425 // styleindex keeps track of hashed styles in order to match features
42426 styleIndex = {}, styleByHash = {},
42427 // stylemapindex keeps track of style maps to expose in properties
42428 styleMapIndex = {},
42429 // atomic geospatial types supported by KML - MultiGeometry is
42430 // handled separately
42431 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
42432 // all root placemarks in the file
42433 placemarks = get(doc, 'Placemark'),
42434 styles = get(doc, 'Style'),
42435 styleMaps = get(doc, 'StyleMap');
42437 for (var k = 0; k < styles.length; k++) {
42438 var hash = okhash(xml2str(styles[k])).toString(16);
42439 styleIndex['#' + attr(styles[k], 'id')] = hash;
42440 styleByHash[hash] = styles[k];
42442 for (var l = 0; l < styleMaps.length; l++) {
42443 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
42444 var pairs = get(styleMaps[l], 'Pair');
42446 for (var m = 0; m < pairs.length; m++) {
42447 pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
42449 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
42452 for (var j = 0; j < placemarks.length; j++) {
42453 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
42455 function kmlColor(v) {
42456 var color, opacity;
42458 if (v.substr(0, 1) === '#') { v = v.substr(1); }
42459 if (v.length === 6 || v.length === 3) { color = v; }
42460 if (v.length === 8) {
42461 opacity = parseInt(v.substr(0, 2), 16) / 255;
42462 color = '#' + v.substr(6, 2) +
42466 return [color, isNaN(opacity) ? undefined : opacity];
42468 function gxCoord(v) { return numarray(v.split(' ')); }
42469 function gxCoords(root) {
42470 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
42471 if (elems.length === 0) elems = get(root, 'gx:coord');
42472 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
42473 var timeElems = get(root, 'when');
42474 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
42480 function getGeometry(root) {
42481 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
42482 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
42483 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
42484 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
42485 for (i = 0; i < geotypes.length; i++) {
42486 geomNodes = get(root, geotypes[i]);
42488 for (j = 0; j < geomNodes.length; j++) {
42489 geomNode = geomNodes[j];
42490 if (geotypes[i] === 'Point') {
42493 coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
42495 } else if (geotypes[i] === 'LineString') {
42497 type: 'LineString',
42498 coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
42500 } else if (geotypes[i] === 'Polygon') {
42501 var rings = get(geomNode, 'LinearRing'),
42503 for (k = 0; k < rings.length; k++) {
42504 coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
42508 coordinates: coords
42510 } else if (geotypes[i] === 'Track' ||
42511 geotypes[i] === 'gx:Track') {
42512 var track = gxCoords(geomNode);
42514 type: 'LineString',
42515 coordinates: track.coords
42517 if (track.times.length) coordTimes.push(track.times);
42524 coordTimes: coordTimes
42527 function getPlacemark(root) {
42528 var geomsAndTimes = getGeometry(root), i, properties = {},
42529 name = nodeVal(get1(root, 'name')),
42530 address = nodeVal(get1(root, 'address')),
42531 styleUrl = nodeVal(get1(root, 'styleUrl')),
42532 description = nodeVal(get1(root, 'description')),
42533 timeSpan = get1(root, 'TimeSpan'),
42534 timeStamp = get1(root, 'TimeStamp'),
42535 extendedData = get1(root, 'ExtendedData'),
42536 lineStyle = get1(root, 'LineStyle'),
42537 polyStyle = get1(root, 'PolyStyle'),
42538 visibility = get1(root, 'visibility');
42540 if (!geomsAndTimes.geoms.length) return [];
42541 if (name) properties.name = name;
42542 if (address) properties.address = address;
42544 if (styleUrl[0] !== '#') {
42545 styleUrl = '#' + styleUrl;
42548 properties.styleUrl = styleUrl;
42549 if (styleIndex[styleUrl]) {
42550 properties.styleHash = styleIndex[styleUrl];
42552 if (styleMapIndex[styleUrl]) {
42553 properties.styleMapHash = styleMapIndex[styleUrl];
42554 properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
42556 // Try to populate the lineStyle or polyStyle since we got the style hash
42557 var style = styleByHash[properties.styleHash];
42559 if (!lineStyle) lineStyle = get1(style, 'LineStyle');
42560 if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
42563 if (description) properties.description = description;
42565 var begin = nodeVal(get1(timeSpan, 'begin'));
42566 var end = nodeVal(get1(timeSpan, 'end'));
42567 properties.timespan = { begin: begin, end: end };
42570 properties.timestamp = nodeVal(get1(timeStamp, 'when'));
42573 var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
42574 color = linestyles[0],
42575 opacity = linestyles[1],
42576 width = parseFloat(nodeVal(get1(lineStyle, 'width')));
42577 if (color) properties.stroke = color;
42578 if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
42579 if (!isNaN(width)) properties['stroke-width'] = width;
42582 var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
42583 pcolor = polystyles[0],
42584 popacity = polystyles[1],
42585 fill = nodeVal(get1(polyStyle, 'fill')),
42586 outline = nodeVal(get1(polyStyle, 'outline'));
42587 if (pcolor) properties.fill = pcolor;
42588 if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
42589 if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
42590 if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
42592 if (extendedData) {
42593 var datas = get(extendedData, 'Data'),
42594 simpleDatas = get(extendedData, 'SimpleData');
42596 for (i = 0; i < datas.length; i++) {
42597 properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
42599 for (i = 0; i < simpleDatas.length; i++) {
42600 properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
42604 properties.visibility = nodeVal(visibility);
42606 if (geomsAndTimes.coordTimes.length) {
42607 properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
42608 geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
42612 geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
42613 type: 'GeometryCollection',
42614 geometries: geomsAndTimes.geoms
42616 properties: properties
42618 if (attr(root, 'id')) feature.id = attr(root, 'id');
42623 gpx: function(doc) {
42625 tracks = get(doc, 'trk'),
42626 routes = get(doc, 'rte'),
42627 waypoints = get(doc, 'wpt'),
42628 // a feature collection
42631 for (i = 0; i < tracks.length; i++) {
42632 feature = getTrack(tracks[i]);
42633 if (feature) gj.features.push(feature);
42635 for (i = 0; i < routes.length; i++) {
42636 feature = getRoute(routes[i]);
42637 if (feature) gj.features.push(feature);
42639 for (i = 0; i < waypoints.length; i++) {
42640 gj.features.push(getPoint(waypoints[i]));
42642 function getPoints(node, pointname) {
42643 var pts = get(node, pointname),
42648 if (l < 2) return {}; // Invalid line in GeoJSON
42649 for (var i = 0; i < l; i++) {
42650 var c = coordPair(pts[i]);
42651 line.push(c.coordinates);
42652 if (c.time) times.push(c.time);
42653 if (c.heartRate) heartRates.push(c.heartRate);
42658 heartRates: heartRates
42661 function getTrack(node) {
42662 var segments = get(node, 'trkseg'),
42667 for (var i = 0; i < segments.length; i++) {
42668 line = getPoints(segments[i], 'trkpt');
42670 if (line.line) track.push(line.line);
42671 if (line.times && line.times.length) times.push(line.times);
42672 if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
42675 if (track.length === 0) return;
42676 var properties = getProperties(node);
42677 extend(properties, getLineStyle(get1(node, 'extensions')));
42678 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
42679 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
42682 properties: properties,
42684 type: track.length === 1 ? 'LineString' : 'MultiLineString',
42685 coordinates: track.length === 1 ? track[0] : track
42689 function getRoute(node) {
42690 var line = getPoints(node, 'rtept');
42691 if (!line.line) return;
42692 var prop = getProperties(node);
42693 extend(prop, getLineStyle(get1(node, 'extensions')));
42698 type: 'LineString',
42699 coordinates: line.line
42704 function getPoint(node) {
42705 var prop = getProperties(node);
42706 extend(prop, getMulti(node, ['sym']));
42712 coordinates: coordPair(node).coordinates
42716 function getLineStyle(extensions) {
42719 var lineStyle = get1(extensions, 'line');
42721 var color = nodeVal(get1(lineStyle, 'color')),
42722 opacity = parseFloat(nodeVal(get1(lineStyle, 'opacity'))),
42723 width = parseFloat(nodeVal(get1(lineStyle, 'width')));
42724 if (color) style.stroke = color;
42725 if (!isNaN(opacity)) style['stroke-opacity'] = opacity;
42726 // GPX width is in mm, convert to px with 96 px per inch
42727 if (!isNaN(width)) style['stroke-width'] = width * 96 / 25.4;
42732 function getProperties(node) {
42733 var prop = getMulti(node, ['name', 'cmt', 'desc', 'type', 'time', 'keywords']),
42734 links = get(node, 'link');
42735 if (links.length) prop.links = [];
42736 for (var i = 0, link; i < links.length; i++) {
42737 link = { href: attr(links[i], 'href') };
42738 extend(link, getMulti(links[i], ['text', 'type']));
42739 prop.links.push(link);
42749 module.exports = toGeoJSON;
42752 function svgGpx(projection, context, dispatch$$1) {
42753 var showLabels = true,
42754 detected = utilDetect(),
42759 if (svgGpx.initialized) return; // run once
42761 svgGpx.geojson = {};
42762 svgGpx.enabled = true;
42765 event.stopPropagation();
42766 event.preventDefault();
42767 event.dataTransfer.dropEffect = 'copy';
42771 .attr('dropzone', 'copy')
42772 .on('drop.localgpx', function() {
42773 event.stopPropagation();
42774 event.preventDefault();
42775 if (!detected.filedrop) return;
42776 drawGpx.files(event.dataTransfer.files);
42778 .on('dragenter.localgpx', over)
42779 .on('dragexit.localgpx', over)
42780 .on('dragover.localgpx', over);
42782 svgGpx.initialized = true;
42786 function drawGpx(selection$$1) {
42787 var geojson = svgGpx.geojson,
42788 enabled = svgGpx.enabled;
42790 layer = selection$$1.selectAll('.layer-gpx')
42791 .data(enabled ? [0] : []);
42796 layer = layer.enter()
42798 .attr('class', 'layer-gpx')
42809 paths = paths.enter()
42811 .attr('class', 'gpx')
42815 var path$$1 = index$4(projection);
42818 .attr('d', path$$1);
42821 var labels = layer.selectAll('text')
42822 .data(showLabels && geojson.features ? geojson.features : []);
42827 labels = labels.enter()
42829 .attr('class', 'gpx')
42833 .text(function(d) {
42834 return d.properties.desc || d.properties.name;
42836 .attr('x', function(d) {
42837 var centroid = path$$1.centroid(d);
42838 return centroid[0] + 7;
42840 .attr('y', function(d) {
42841 var centroid = path$$1.centroid(d);
42842 return centroid[1];
42848 function toDom(x) {
42849 return (new DOMParser()).parseFromString(x, 'text/xml');
42853 function getExtension(fileName) {
42854 if (lodash.isUndefined(fileName)) {
42858 var lastDotIndex = fileName.lastIndexOf('.');
42859 if (lastDotIndex < 0) {
42863 return fileName.substr(lastDotIndex);
42867 function parseSaveAndZoom(extension, data) {
42868 switch (extension) {
42870 drawGpx.geojson(togeojson.gpx(toDom(data))).fitZoom();
42873 drawGpx.geojson(togeojson.kml(toDom(data))).fitZoom();
42877 drawGpx.geojson(JSON.parse(data)).fitZoom();
42883 drawGpx.showLabels = function(_) {
42884 if (!arguments.length) return showLabels;
42890 drawGpx.enabled = function(_) {
42891 if (!arguments.length) return svgGpx.enabled;
42892 svgGpx.enabled = _;
42893 dispatch$$1.call('change');
42898 drawGpx.hasGpx = function() {
42899 var geojson = svgGpx.geojson;
42900 return (!(lodash.isEmpty(geojson) || lodash.isEmpty(geojson.features)));
42904 drawGpx.geojson = function(gj) {
42905 if (!arguments.length) return svgGpx.geojson;
42906 if (lodash.isEmpty(gj) || lodash.isEmpty(gj.features)) return this;
42907 svgGpx.geojson = gj;
42908 dispatch$$1.call('change');
42913 drawGpx.url = function(url) {
42914 text(url, function(err, data) {
42916 var extension = getExtension(url);
42917 parseSaveAndZoom(extension, data);
42924 drawGpx.files = function(fileList) {
42925 if (!fileList.length) return this;
42926 var f = fileList[0],
42927 reader = new FileReader();
42929 reader.onload = (function(file) {
42930 var extension = getExtension(file.name);
42932 return function (e) {
42933 parseSaveAndZoom(extension, e.target.result);
42937 reader.readAsText(f);
42942 drawGpx.fitZoom = function() {
42943 if (!this.hasGpx()) return this;
42944 var geojson = svgGpx.geojson;
42946 var map$$1 = context.map(),
42947 viewport = map$$1.trimmedExtent().polygon(),
42948 coords = lodash.reduce(geojson.features, function(coords, feature) {
42949 var c = feature.geometry.coordinates;
42951 /* eslint-disable no-fallthrough */
42952 switch (feature.geometry.type) {
42959 case 'MultiPolygon':
42960 c = lodash.flatten(c);
42962 case 'MultiLineString':
42963 c = lodash.flatten(c);
42966 /* eslint-enable no-fallthrough */
42968 return lodash.union(coords, c);
42971 if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
42972 var extent$$1 = geoExtent$$1(bounds({ type: 'LineString', coordinates: coords }));
42973 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
42984 function svgIcon(name, svgklass, useklass) {
42985 return function drawIcon(selection) {
42986 selection.selectAll('svg')
42990 .attr('class', 'icon ' + (svgklass || ''))
42992 .attr('xlink:href', name)
42993 .attr('class', useklass);
42997 function svgLabels(projection, context) {
42998 var path$$1 = index$4(projection),
42999 detected = utilDetect(),
43000 baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge'),
43001 rdrawn = index$9(),
43002 rskipped = index$9(),
43003 textWidthCache = {},
43006 // Listed from highest to lowest priority
43008 ['line', 'aeroway', '*', 12],
43009 ['line', 'highway', 'motorway', 12],
43010 ['line', 'highway', 'trunk', 12],
43011 ['line', 'highway', 'primary', 12],
43012 ['line', 'highway', 'secondary', 12],
43013 ['line', 'highway', 'tertiary', 12],
43014 ['line', 'highway', '*', 12],
43015 ['line', 'railway', '*', 12],
43016 ['line', 'waterway', '*', 12],
43017 ['area', 'aeroway', '*', 12],
43018 ['area', 'amenity', '*', 12],
43019 ['area', 'building', '*', 12],
43020 ['area', 'historic', '*', 12],
43021 ['area', 'leisure', '*', 12],
43022 ['area', 'man_made', '*', 12],
43023 ['area', 'natural', '*', 12],
43024 ['area', 'shop', '*', 12],
43025 ['area', 'tourism', '*', 12],
43026 ['area', 'camp_site', '*', 12],
43027 ['point', 'aeroway', '*', 10],
43028 ['point', 'amenity', '*', 10],
43029 ['point', 'building', '*', 10],
43030 ['point', 'historic', '*', 10],
43031 ['point', 'leisure', '*', 10],
43032 ['point', 'man_made', '*', 10],
43033 ['point', 'natural', '*', 10],
43034 ['point', 'shop', '*', 10],
43035 ['point', 'tourism', '*', 10],
43036 ['point', 'camp_site', '*', 10],
43037 ['line', 'name', '*', 12],
43038 ['area', 'name', '*', 12],
43039 ['point', 'name', '*', 10]
43043 function blacklisted(preset) {
43044 var noIcons = ['building', 'landuse', 'natural'];
43045 return lodash.some(noIcons, function(s) {
43046 return preset.id.indexOf(s) >= 0;
43051 function get(array, prop) {
43052 return function(d, i) { return array[i][prop]; };
43056 function textWidth(text$$1, size, elem) {
43057 var c = textWidthCache[size];
43058 if (!c) c = textWidthCache[size] = {};
43064 c[text$$1] = elem.getComputedTextLength();
43068 var str = encodeURIComponent(text$$1).match(/%[CDEFcdef]/g);
43069 if (str === null) {
43070 return size / 3 * 2 * text$$1.length;
43072 return size / 3 * (2 * text$$1.length + str.length);
43078 function drawLinePaths(selection$$1, entities, filter, classes, labels) {
43079 var paths = selection$$1.selectAll('path')
43081 .data(entities, osmEntity$$1.key);
43088 .style('stroke-width', get(labels, 'font-size'))
43089 .attr('id', function(d) { return 'labelpath-' + d.id; })
43090 .attr('class', classes)
43092 .attr('d', get(labels, 'lineString'));
43096 function drawLineLabels(selection$$1, entities, filter, classes, labels) {
43097 var texts = selection$$1.selectAll('text.' + classes)
43099 .data(entities, osmEntity$$1.key);
43106 .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
43107 .attr('dy', baselineHack ? '0.35em' : null)
43108 .append('textPath')
43109 .attr('class', 'textpath');
43111 texts = selection$$1.selectAll('text.' + classes);
43113 texts.selectAll('.textpath')
43115 .data(entities, osmEntity$$1.key)
43116 .attr('startOffset', '50%')
43117 .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
43118 .text(utilDisplayNameForPath);
43122 function drawPointLabels(selection$$1, entities, filter, classes, labels) {
43123 var texts = selection$$1.selectAll('text.' + classes)
43125 .data(entities, osmEntity$$1.key);
43130 texts = texts.enter()
43132 .attr('class', function(d, i) {
43133 return classes + ' ' + labels[i].classes + ' ' + d.id;
43138 .attr('x', get(labels, 'x'))
43139 .attr('y', get(labels, 'y'))
43140 .style('text-anchor', get(labels, 'textAnchor'))
43141 .text(utilDisplayName)
43142 .each(function(d, i) {
43143 textWidth(utilDisplayName(d), labels[i].height, this);
43148 function drawAreaLabels(selection$$1, entities, filter, classes, labels) {
43149 entities = entities.filter(hasText);
43150 labels = labels.filter(hasText);
43151 drawPointLabels(selection$$1, entities, filter, classes, labels);
43153 function hasText(d, i) {
43154 return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
43159 function drawAreaIcons(selection$$1, entities, filter, classes, labels) {
43160 var icons = selection$$1.selectAll('use.' + classes)
43162 .data(entities, osmEntity$$1.key);
43167 icons = icons.enter()
43169 .attr('class', 'icon ' + classes)
43170 .attr('width', '17px')
43171 .attr('height', '17px')
43175 .attr('transform', get(labels, 'transform'))
43176 .attr('xlink:href', function(d) {
43177 var icon = context.presets().match(d, context.graph()).icon;
43178 return '#' + icon + '-15';
43183 function drawCollisionBoxes(selection$$1, rtree, which) {
43184 var showDebug = context.getDebug('collision'),
43185 classes = 'debug ' + which + ' ' +
43186 (which === 'debug-skipped' ? 'orange' : 'yellow');
43188 var debug = selection$$1.selectAll('.layer-label-debug')
43189 .data(showDebug ? [true] : []);
43194 debug = debug.enter()
43196 .attr('class', 'layer-label-debug')
43200 var gj = rtree.all().map(function(d) {
43201 return { type: 'Polygon', coordinates: [[
43210 var debugboxes = debug.selectAll('.' + which)
43216 debugboxes = debugboxes.enter()
43218 .attr('class', classes)
43219 .merge(debugboxes);
43222 .attr('d', index$4());
43227 function drawLabels(selection$$1, graph, entities, filter, dimensions, fullRedraw) {
43228 var lowZoom = context.surface().classed('low-zoom');
43230 var labelable = [], i, j, k, entity, geometry;
43231 for (i = 0; i < labelStack.length; i++) {
43232 labelable.push([]);
43240 for (i = 0; i < entities.length; i++) {
43241 entity = entities[i];
43243 .concat(entitybboxes[entity.id] || [])
43244 .concat(entitybboxes[entity.id + 'I'] || []);
43246 for (j = 0; j < toRemove.length; j++) {
43247 rdrawn.remove(toRemove[j]);
43248 rskipped.remove(toRemove[j]);
43253 // Split entities into groups specified by labelStack
43254 for (i = 0; i < entities.length; i++) {
43255 entity = entities[i];
43256 geometry = entity.geometry(graph);
43257 if (geometry === 'vertex') { geometry = 'point'; } // treat vertex like point
43259 var preset = geometry === 'area' && context.presets().match(entity, graph),
43260 icon = preset && !blacklisted(preset) && preset.icon;
43262 if (!icon && !utilDisplayName(entity))
43265 for (k = 0; k < labelStack.length; k++) {
43266 var matchGeom = labelStack[k][0],
43267 matchKey = labelStack[k][1],
43268 matchVal = labelStack[k][2],
43269 hasVal = entity.tags[matchKey];
43271 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
43272 labelable[k].push(entity);
43290 // Try and find a valid label for labellable entities
43291 for (k = 0; k < labelable.length; k++) {
43292 var fontSize = labelStack[k][3];
43293 for (i = 0; i < labelable[k].length; i++) {
43294 entity = labelable[k][i];
43295 geometry = entity.geometry(graph);
43297 var getName = (geometry === 'line') ? utilDisplayNameForPath : utilDisplayName,
43298 name = getName(entity),
43299 width = name && textWidth(name, fontSize),
43302 if (geometry === 'point') {
43303 p = getPointLabel(entity, width, fontSize, geometry);
43304 } else if (geometry === 'vertex' && !lowZoom) {
43305 // don't label vertices at low zoom because they don't have icons
43306 p = getPointLabel(entity, width, fontSize, geometry);
43307 } else if (geometry === 'line') {
43308 p = getLineLabel(entity, width, fontSize);
43309 } else if (geometry === 'area') {
43310 p = getAreaLabel(entity, width, fontSize);
43314 if (geometry === 'vertex') { geometry = 'point'; } // treat vertex like point
43315 p.classes = geometry + ' tag-' + labelStack[k][1];
43316 positions[geometry].push(p);
43317 labelled[geometry].push(entity);
43323 function getPointLabel(entity, width, height, geometry) {
43324 var y = (geometry === 'point' ? -12 : 0),
43326 ltr: [15, y, 'start'],
43327 rtl: [-15, y, 'end']
43330 var coord = projection(entity.loc),
43332 offset = pointOffsets[textDirection],
43336 x: coord[0] + offset[0],
43337 y: coord[1] + offset[1],
43338 textAnchor: offset[2]
43342 if (textDirection === 'rtl') {
43344 minX: p.x - width - margin,
43345 minY: p.y - (height / 2) - margin,
43346 maxX: p.x + margin,
43347 maxY: p.y + (height / 2) + margin
43351 minX: p.x - margin,
43352 minY: p.y - (height / 2) - margin,
43353 maxX: p.x + width + margin,
43354 maxY: p.y + (height / 2) + margin
43358 if (tryInsert([bbox], entity.id, true)) {
43364 function getLineLabel(entity, width, height) {
43365 var viewport = geoExtent$$1(context.projection.clipExtent()).polygon(),
43366 nodes = lodash.map(graph.childNodes(entity), 'loc').map(projection),
43367 length = geoPathLength(nodes);
43369 if (length < width + 20) return;
43371 // % along the line to attempt to place the label
43372 var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
43373 25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
43376 for (var i = 0; i < lineOffsets.length; i++) {
43377 var offset = lineOffsets[i],
43378 middle = offset / 100 * length,
43379 start = middle - width / 2;
43381 if (start < 0 || start + width > length) continue;
43383 // generate subpath and ignore paths that are invalid or don't cross viewport.
43384 var sub = subpath(nodes, start, start + width);
43385 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
43389 var isReverse = reverse(sub);
43391 sub = sub.reverse();
43395 boxsize = (height + 2) / 2;
43397 for (var j = 0; j < sub.length - 1; j++) {
43399 var b = sub[j + 1];
43400 var num = Math.max(1, Math.floor(geoEuclideanDistance(a, b) / boxsize / 2));
43402 for (var box = 0; box < num; box++) {
43403 var p = geoInterp(a, b, box / num);
43404 var x0 = p[0] - boxsize - margin;
43405 var y0 = p[1] - boxsize - margin;
43406 var x1 = p[0] + boxsize + margin;
43407 var y1 = p[1] + boxsize + margin;
43410 minX: Math.min(x0, x1),
43411 minY: Math.min(y0, y1),
43412 maxX: Math.max(x0, x1),
43413 maxY: Math.max(y0, y1)
43418 if (tryInsert(bboxes, entity.id, false)) {
43420 'font-size': height + 2,
43421 lineString: lineString(sub),
43422 startOffset: offset + '%'
43427 function reverse(p) {
43428 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
43429 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
43432 function lineString(nodes) {
43433 return 'M' + nodes.join('L');
43436 function subpath(nodes, from, to) {
43438 start, end, i0, i1;
43440 for (var i = 0; i < nodes.length - 1; i++) {
43443 var current = geoEuclideanDistance(a, b);
43445 if (!start && sofar + current >= from) {
43446 portion = (from - sofar) / current;
43448 a[0] + portion * (b[0] - a[0]),
43449 a[1] + portion * (b[1] - a[1])
43453 if (!end && sofar + current >= to) {
43454 portion = (to - sofar) / current;
43456 a[0] + portion * (b[0] - a[0]),
43457 a[1] + portion * (b[1] - a[1])
43464 var ret = nodes.slice(i0, i1);
43465 ret.unshift(start);
43472 function getAreaLabel(entity, width, height) {
43473 var centroid = path$$1.centroid(entity.asGeoJSON(graph, true)),
43474 extent$$1 = entity.extent(graph),
43475 entitywidth = projection(extent$$1[1])[0] - projection(extent$$1[0])[0];
43477 if (isNaN(centroid[0]) || entitywidth < 20) return;
43480 iconX = centroid[0] - (iconSize / 2),
43481 iconY = centroid[1] - (iconSize / 2),
43483 textOffset = iconSize + margin,
43484 p = { transform: 'translate(' + iconX + ',' + iconY + ')' };
43489 maxX: iconX + iconSize,
43490 maxY: iconY + iconSize
43494 if (tryInsert([bbox], entity.id + 'I', true)) {
43495 if (width && entitywidth >= width + 20) {
43496 var labelX = centroid[0],
43497 labelY = centroid[1] + textOffset;
43500 minX: labelX - (width / 2) - margin,
43501 minY: labelY - (height / 2) - margin,
43502 maxX: labelX + (width / 2) + margin,
43503 maxY: labelY + (height / 2) + margin
43506 // try to add label
43507 if (tryInsert([bbox], entity.id, true)) {
43510 p.textAnchor = 'middle';
43520 function tryInsert(bboxes, id, saveSkipped) {
43521 var skipped = false,
43524 for (var i = 0; i < bboxes.length; i++) {
43528 // Check that label is visible
43529 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
43533 if (rdrawn.collides(bbox)) {
43539 entitybboxes[id] = bboxes;
43543 rskipped.load(bboxes);
43546 rdrawn.load(bboxes);
43553 var label = selection$$1.selectAll('.layer-label'),
43554 halo = selection$$1.selectAll('.layer-halo');
43557 drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
43558 drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
43561 drawLinePaths(halo, labelled.line, filter, '', positions.line);
43562 drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
43563 drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
43566 drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
43567 drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
43568 drawAreaIcons(label, labelled.area, filter, 'areaicon', positions.area);
43569 drawAreaIcons(halo, labelled.area, filter, 'areaicon-halo', positions.area);
43572 drawCollisionBoxes(label, rskipped, 'debug-skipped');
43573 drawCollisionBoxes(label, rdrawn, 'debug-drawn');
43575 selection$$1.call(filterLabels);
43579 function filterLabels(selection$$1) {
43580 var layers = selection$$1
43581 .selectAll('.layer-label, .layer-halo');
43583 layers.selectAll('.proximate')
43584 .classed('proximate', false);
43586 var mouse$$1 = context.mouse(),
43587 graph = context.graph(),
43588 selectedIDs = context.selectedIDs(),
43592 // hide labels near the mouse
43595 bbox = { minX: mouse$$1[0] - pad, minY: mouse$$1[1] - pad, maxX: mouse$$1[0] + pad, maxY: mouse$$1[1] + pad };
43596 ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
43599 // hide labels along selected ways, or near selected vertices
43600 for (var i = 0; i < selectedIDs.length; i++) {
43601 var entity = graph.hasEntity(selectedIDs[i]);
43602 if (!entity) continue;
43603 var geometry = entity.geometry(graph);
43605 if (geometry === 'line') {
43606 ids.push(selectedIDs[i]);
43607 } else if (geometry === 'vertex') {
43608 var point = context.projection(entity.loc);
43610 bbox = { minX: point[0] - pad, minY: point[1] - pad, maxX: point[0] + pad, maxY: point[1] + pad };
43611 ids.push.apply(ids, lodash.map(rdrawn.search(bbox), 'id'));
43615 layers.selectAll(utilEntitySelector(ids))
43616 .classed('proximate', true);
43620 var throttleFilterLabels = lodash.throttle(filterLabels, 100);
43623 drawLabels.observe = function(selection$$1) {
43624 var listener = function() { throttleFilterLabels(selection$$1); };
43625 selection$$1.on('mousemove.hidelabels', listener);
43626 context.on('enter.hidelabels', listener);
43630 drawLabels.off = function(selection$$1) {
43631 throttleFilterLabels.cancel();
43632 selection$$1.on('mousemove.hidelabels', null);
43633 context.on('enter.hidelabels', null);
43640 function refresh(selection, node) {
43641 var cr = node.getBoundingClientRect();
43642 var prop = [cr.width, cr.height];
43643 selection.property('__dimensions__', prop);
43647 function utilGetDimensions(selection, force) {
43648 if (!selection || selection.empty()) {
43651 var node = selection.node(),
43652 cached = selection.property('__dimensions__');
43653 return (!cached || force) ? refresh(selection, node) : cached;
43657 function utilSetDimensions(selection, dimensions) {
43658 if (!selection || selection.empty()) {
43661 var node = selection.node();
43662 if (dimensions === null) {
43663 refresh(selection, node);
43667 .property('__dimensions__', [dimensions[0], dimensions[1]])
43668 .attr('width', dimensions[0])
43669 .attr('height', dimensions[1]);
43672 function svgPointTransform(projection) {
43673 return function(entity) {
43674 // http://jsperf.com/short-array-join
43675 var pt = projection(entity.loc);
43676 return 'translate(' + pt[0] + ',' + pt[1] + ')';
43680 function d3geoTile() {
43681 var size = [960, 500],
43683 scaleExtent = [0, 20],
43684 translate = [size[0] / 2, size[1] / 2],
43687 function bound(_) {
43688 return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
43692 var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
43693 z0 = bound(Math.round(z + zoomDelta)),
43694 k = Math.pow(2, z - z0 + 8),
43695 origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
43697 cols = sequence(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
43698 rows = sequence(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
43700 rows.forEach(function(y) {
43701 cols.forEach(function(x) {
43702 tiles.push([x, y, z0]);
43706 tiles.translate = origin;
43712 tile.scaleExtent = function(_) {
43713 if (!arguments.length) return scaleExtent;
43718 tile.size = function(_) {
43719 if (!arguments.length) return size;
43724 tile.scale = function(_) {
43725 if (!arguments.length) return scale;
43730 tile.translate = function(_) {
43731 if (!arguments.length) return translate;
43736 tile.zoomDelta = function(_) {
43737 if (!arguments.length) return zoomDelta;
43745 /* global Mapillary:false */
43746 var apibase = 'https://a.mapillary.com/v2/';
43747 var viewercss = 'mapillary-js/mapillary.min.css';
43748 var viewerjs = 'mapillary-js/mapillary.min.js';
43749 var trafficocss = 'traffico/stylesheets/traffico.css';
43750 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
43751 var maxResults = 1000;
43753 var dispatch$2 = dispatch('loadedImages', 'loadedSigns');
43754 var mapillaryCache;
43755 var mapillaryClicks;
43756 var mapillaryImage;
43757 var mapillarySignDefs;
43758 var mapillaryViewer;
43761 function abortRequest(i) {
43766 function nearNullIsland(x, y, z) {
43768 var center = Math.pow(2, z - 1),
43769 width = Math.pow(2, z - 6),
43770 min$$1 = center - (width / 2),
43771 max$$1 = center + (width / 2) - 1;
43772 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
43778 function maxPageAtZoom(z) {
43779 if (z < 15) return 2;
43780 if (z === 15) return 5;
43781 if (z === 16) return 10;
43782 if (z === 17) return 20;
43783 if (z === 18) return 40;
43784 if (z > 18) return 80;
43788 function getTiles(projection) {
43789 var s = projection.scale() * 2 * Math.PI,
43790 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
43791 ts = 256 * Math.pow(2, z - tileZoom),
43793 s / 2 - projection.translate()[0],
43794 s / 2 - projection.translate()[1]];
43797 .scaleExtent([tileZoom, tileZoom])
43799 .size(projection.clipExtent()[1])
43800 .translate(projection.translate())()
43801 .map(function(tile) {
43802 var x = tile[0] * ts - origin[0],
43803 y = tile[1] * ts - origin[1];
43806 id: tile.toString(),
43808 extent: geoExtent$$1(
43809 projection.invert([x, y + ts]),
43810 projection.invert([x + ts, y])
43817 function loadTiles(which, url, projection) {
43818 var s = projection.scale() * 2 * Math.PI,
43819 currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
43821 var tiles = getTiles(projection).filter(function(t) {
43822 return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
43825 lodash.filter(which.inflight, function(v, k) {
43826 var wanted = lodash.find(tiles, function(tile) { return k === (tile.id + ',0'); });
43827 if (!wanted) delete which.inflight[k];
43829 }).map(abortRequest);
43831 tiles.forEach(function(tile) {
43832 loadNextTilePage(which, currZoom, url, tile);
43837 function loadNextTilePage(which, currZoom, url, tile) {
43838 var cache = mapillaryCache[which],
43839 rect = tile.extent.rectangle(),
43840 maxPages = maxPageAtZoom(currZoom),
43841 nextPage = cache.nextPage[tile.id] || 0;
43843 if (nextPage > maxPages) return;
43845 var id = tile.id + ',' + String(nextPage);
43846 if (cache.loaded[id] || cache.inflight[id]) return;
43848 cache.inflight[id] = json(url +
43853 client_id: clientId,
43858 }), function(err, data) {
43859 cache.loaded[id] = true;
43860 delete cache.inflight[id];
43861 if (err || !data.features || !data.features.length) return;
43866 for (var i = 0; i < data.features.length; i++) {
43867 feature = data.features[i];
43868 loc = feature.geometry.coordinates;
43869 d = { key: feature.properties.key, loc: loc };
43870 if (which === 'images') d.ca = feature.properties.ca;
43871 if (which === 'signs') d.signs = feature.properties.rects;
43873 features.push({minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d});
43876 cache.rtree.load(features);
43878 if (which === 'images') dispatch$2.call('loadedImages');
43879 if (which === 'signs') dispatch$2.call('loadedSigns');
43881 if (data.features.length === maxResults) { // more pages to load
43882 cache.nextPage[tile.id] = nextPage + 1;
43883 loadNextTilePage(which, currZoom, url, tile);
43885 cache.nextPage[tile.id] = Infinity; // no more pages to load
43892 // partition viewport into `psize` x `psize` regions
43893 function partitionViewport(psize, projection) {
43894 var dimensions = projection.clipExtent()[1];
43895 psize = psize || 16;
43896 var cols = sequence(0, dimensions[0], psize),
43897 rows = sequence(0, dimensions[1], psize),
43900 rows.forEach(function(y) {
43901 cols.forEach(function(x) {
43902 var min$$1 = [x, y + psize],
43903 max$$1 = [x + psize, y];
43905 geoExtent$$1(projection.invert(min$$1), projection.invert(max$$1)));
43913 // no more than `limit` results per partition.
43914 function searchLimited(psize, limit, projection, rtree) {
43915 limit = limit || 3;
43917 var partitions = partitionViewport(psize, projection);
43918 return lodash.flatten(lodash.compact(lodash.map(partitions, function(extent$$1) {
43919 return rtree.search(extent$$1.bbox())
43921 .map(function(d) { return d.data; });
43927 var serviceMapillary = {
43930 if (!mapillaryCache) {
43934 this.event = utilRebind(this, dispatch$2, 'on');
43937 reset: function() {
43938 var cache = mapillaryCache;
43941 if (cache.images && cache.images.inflight) {
43942 lodash.forEach(cache.images.inflight, abortRequest);
43944 if (cache.signs && cache.signs.inflight) {
43945 lodash.forEach(cache.signs.inflight, abortRequest);
43950 images: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$9() },
43951 signs: { inflight: {}, loaded: {}, nextPage: {}, rtree: index$9() }
43954 mapillaryImage = null;
43955 mapillaryClicks = [];
43959 images: function(projection) {
43960 var psize = 16, limit = 3;
43961 return searchLimited(psize, limit, projection, mapillaryCache.images.rtree);
43965 signs: function(projection) {
43966 var psize = 32, limit = 3;
43967 return searchLimited(psize, limit, projection, mapillaryCache.signs.rtree);
43971 signsSupported: function() {
43972 var detected = utilDetect();
43973 if (detected.ie) return false;
43974 if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
43979 signHTML: function(d) {
43980 if (!mapillarySignDefs) return;
43982 var detectionPackage = d.signs[0].package,
43983 type = d.signs[0].type,
43984 country = detectionPackage.split('_')[1];
43986 return mapillarySignDefs[country][type];
43990 loadImages: function(projection) {
43991 var url = apibase + 'search/im/geojson?';
43992 loadTiles('images', url, projection);
43996 loadSigns: function(context, projection) {
43997 var url = apibase + 'search/im/geojson/or?';
43998 loadTiles('signs', url, projection);
44000 // load traffico css
44001 select('head').selectAll('#traffico')
44005 .attr('id', 'traffico')
44006 .attr('rel', 'stylesheet')
44007 .attr('href', context.asset(trafficocss));
44009 // load traffico sign defs
44010 if (!mapillarySignDefs) {
44011 mapillarySignDefs = {};
44012 lodash.each(['au', 'br', 'ca', 'de', 'us'], function(region) {
44013 json(context.asset('traffico/string-maps/' + region + '-map.json'), function(err, data) {
44015 if (region === 'de') region = 'eu';
44016 mapillarySignDefs[region] = data;
44023 loadViewer: function(context) {
44025 var wrap = select('#content').selectAll('.mapillary-wrap')
44028 var enter = wrap.enter()
44030 .attr('class', 'mapillary-wrap')
44031 .classed('al', true) // 'al'=left, 'ar'=right
44032 .classed('hidden', true);
44036 .attr('class', 'thumb-hide')
44037 .on('click', function () { that.hideViewer(); })
44039 .call(svgIcon('#icon-close'));
44044 .attr('class', 'mly-wrapper')
44045 .classed('active', false);
44047 // load mapillary-viewercss
44048 select('head').selectAll('#mapillary-viewercss')
44052 .attr('id', 'mapillary-viewercss')
44053 .attr('rel', 'stylesheet')
44054 .attr('href', context.asset(viewercss));
44056 // load mapillary-viewerjs
44057 select('head').selectAll('#mapillary-viewerjs')
44061 .attr('id', 'mapillary-viewerjs')
44062 .attr('src', context.asset(viewerjs));
44066 showViewer: function() {
44068 .selectAll('.mapillary-wrap')
44069 .classed('hidden', false)
44070 .selectAll('.mly-wrapper')
44071 .classed('active', true);
44077 hideViewer: function() {
44079 .selectAll('.mapillary-wrap')
44080 .classed('hidden', true)
44081 .selectAll('.mly-wrapper')
44082 .classed('active', false);
44084 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
44085 .classed('selected', false);
44087 mapillaryImage = null;
44092 updateViewer: function(imageKey, context) {
44093 if (!imageKey) return;
44095 if (!mapillaryViewer) {
44096 this.initViewer(imageKey, context);
44098 mapillaryViewer.moveToKey(imageKey);
44105 initViewer: function(imageKey, context) {
44107 if (Mapillary && imageKey) {
44109 baseImageSize: 320,
44116 mapillaryViewer = new Mapillary.Viewer('mly', clientId, imageKey, opts);
44117 mapillaryViewer.on('nodechanged', nodeChanged);
44120 function nodeChanged(node) {
44121 var clicks = mapillaryClicks;
44122 var index = clicks.indexOf(node.key);
44123 if (index > -1) { // nodechange initiated from clicking on a marker..
44124 clicks.splice(index, 1);
44125 } else { // nodechange initiated from the Mapillary viewer controls..
44126 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
44127 context.map().centerEase(loc);
44128 that.selectedImage(node.key, false);
44134 selectedImage: function(imageKey, fromClick) {
44135 if (!arguments.length) return mapillaryImage;
44137 mapillaryImage = imageKey;
44139 mapillaryClicks.push(imageKey);
44142 selectAll('.layer-mapillary-images .viewfield-group, .layer-mapillary-signs .icon-sign')
44143 .classed('selected', function(d) { return d.key === imageKey; });
44149 cache: function(_) {
44150 if (!arguments.length) return mapillaryCache;
44151 mapillaryCache = _;
44156 signDefs: function(_) {
44157 if (!arguments.length) return mapillarySignDefs;
44158 mapillarySignDefs = _;
44164 var apibase$1 = 'https://nominatim.openstreetmap.org/';
44165 var nominatimCache;
44168 var serviceNominatim = {
44170 init: function() { nominatimCache = index$9(); },
44171 reset: function() { nominatimCache = index$9(); },
44174 countryCode: function (location, callback) {
44175 var countryCodes = nominatimCache.search(
44176 { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
44179 if (countryCodes.length > 0) {
44180 return callback(null, countryCodes[0].data);
44183 json(apibase$1 + 'reverse?' +
44189 }), function(err, result) {
44191 return callback(err);
44192 else if (result && result.error)
44193 return callback(result.error);
44195 var extent$$1 = geoExtent$$1(location).padByMeters(1000);
44196 nominatimCache.insert(lodash.assign(extent$$1.bbox(),
44197 { data: result.address.country_code }
44200 callback(null, result.address.country_code);
44206 search: function (val, callback) {
44207 var searchVal = encodeURIComponent(val);
44208 json(apibase$1 + 'search/' + searchVal + '?limit=10&format=json', callback);
44213 var hashes$1 = createCommonjsModule(function (module, exports) {
44215 * jshashes - https://github.com/h2non/jshashes
44216 * Released under the "New BSD" license
44218 * Algorithms specification:
44220 * MD5 - http://www.ietf.org/rfc/rfc1321.txt
44221 * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
44222 * SHA1 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
44223 * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
44224 * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
44225 * HMAC - http://www.ietf.org/rfc/rfc2104.txt
44230 function utf8Encode(str) {
44231 var x, y, output = '',
44235 if (str && str.length) {
44237 while ((i += 1) < l) {
44238 /* Decode utf-16 surrogate pairs */
44239 x = str.charCodeAt(i);
44240 y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
44241 if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
44242 x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
44245 /* Encode output as utf-8 */
44247 output += String.fromCharCode(x);
44248 } else if (x <= 0x7FF) {
44249 output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
44250 0x80 | (x & 0x3F));
44251 } else if (x <= 0xFFFF) {
44252 output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
44253 0x80 | ((x >>> 6) & 0x3F),
44254 0x80 | (x & 0x3F));
44255 } else if (x <= 0x1FFFFF) {
44256 output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
44257 0x80 | ((x >>> 12) & 0x3F),
44258 0x80 | ((x >>> 6) & 0x3F),
44259 0x80 | (x & 0x3F));
44266 function utf8Decode(str) {
44267 var i, ac, c1, c2, c3, arr = [],
44269 i = ac = c1 = c2 = c3 = 0;
44271 if (str && str.length) {
44276 c1 = str.charCodeAt(i);
44279 arr[ac] = String.fromCharCode(c1);
44281 } else if (c1 > 191 && c1 < 224) {
44282 c2 = str.charCodeAt(i + 1);
44283 arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
44286 c2 = str.charCodeAt(i + 1);
44287 c3 = str.charCodeAt(i + 2);
44288 arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
44293 return arr.join('');
44297 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
44298 * to work around bugs in some JS interpreters.
44301 function safe_add(x, y) {
44302 var lsw = (x & 0xFFFF) + (y & 0xFFFF),
44303 msw = (x >> 16) + (y >> 16) + (lsw >> 16);
44304 return (msw << 16) | (lsw & 0xFFFF);
44308 * Bitwise rotate a 32-bit number to the left.
44311 function bit_rol(num, cnt) {
44312 return (num << cnt) | (num >>> (32 - cnt));
44316 * Convert a raw string to a hex string
44319 function rstr2hex(input, hexcase) {
44320 var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
44324 for (; i < l; i += 1) {
44325 x = input.charCodeAt(i);
44326 output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
44332 * Encode a string as utf-16
44335 function binb2rstr(input) {
44336 var i, l = input.length * 32,
44338 for (i = 0; i < l; i += 8) {
44339 output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
44345 * Convert an array of little-endian words to a string
44348 function binl2rstr(input) {
44349 var i, l = input.length * 32,
44351 for (i = 0; i < l; i += 8) {
44352 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
44358 * Convert a raw string to an array of little-endian words
44359 * Characters >255 have their high-byte silently ignored.
44362 function rstr2binl(input) {
44363 var i, l = input.length * 8,
44364 output = Array(input.length >> 2),
44365 lo = output.length;
44366 for (i = 0; i < lo; i += 1) {
44369 for (i = 0; i < l; i += 8) {
44370 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
44376 * Convert a raw string to an array of big-endian words
44377 * Characters >255 have their high-byte silently ignored.
44380 function rstr2binb(input) {
44381 var i, l = input.length * 8,
44382 output = Array(input.length >> 2),
44383 lo = output.length;
44384 for (i = 0; i < lo; i += 1) {
44387 for (i = 0; i < l; i += 8) {
44388 output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
44394 * Convert a raw string to an arbitrary string encoding
44397 function rstr2any(input, encoding) {
44398 var divisor = encoding.length,
44399 remainders = Array(),
44400 i, q, x, ld, quotient, dividend, output, full_length;
44402 /* Convert to an array of 16-bit big-endian values, forming the dividend */
44403 dividend = Array(Math.ceil(input.length / 2));
44404 ld = dividend.length;
44405 for (i = 0; i < ld; i += 1) {
44406 dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
44410 * Repeatedly perform a long division. The binary array forms the dividend,
44411 * the length of the encoding is the divisor. Once computed, the quotient
44412 * forms the dividend for the next step. We stop when the dividend is zerHashes.
44413 * All remainders are stored for later use.
44415 while (dividend.length > 0) {
44416 quotient = Array();
44418 for (i = 0; i < dividend.length; i += 1) {
44419 x = (x << 16) + dividend[i];
44420 q = Math.floor(x / divisor);
44422 if (quotient.length > 0 || q > 0) {
44423 quotient[quotient.length] = q;
44426 remainders[remainders.length] = x;
44427 dividend = quotient;
44430 /* Convert the remainders to the output string */
44432 for (i = remainders.length - 1; i >= 0; i--) {
44433 output += encoding.charAt(remainders[i]);
44436 /* Append leading zero equivalents */
44437 full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
44438 for (i = output.length; i < full_length; i += 1) {
44439 output = encoding[0] + output;
44445 * Convert a raw string to a base-64 string
44448 function rstr2b64(input, b64pad) {
44449 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
44451 len = input.length,
44453 b64pad = b64pad || '=';
44454 for (i = 0; i < len; i += 3) {
44455 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
44456 for (j = 0; j < 4; j += 1) {
44457 if (i * 8 + j * 6 > input.length * 8) {
44460 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
44469 * @property {String} version
44478 Base64: function() {
44479 // private properties
44480 var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
44481 pad = '=', // default pad according with the RFC standard
44482 url = false, // URL encoding support @todo
44483 utf8 = true; // by default enable UTF-8 support encoding
44485 // public method for encoding
44486 this.encode = function(input) {
44489 len = input.length;
44492 input = (utf8) ? utf8Encode(input) : input;
44494 for (i = 0; i < len; i += 3) {
44495 triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
44496 for (j = 0; j < 4; j += 1) {
44497 if (i * 8 + j * 6 > len * 8) {
44500 output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
44507 // public method for decoding
44508 this.decode = function(input) {
44509 // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
44510 var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
44518 input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
44521 do { // unpack four hexets into three octets using index points in b64
44522 h1 = tab.indexOf(input.charAt(i += 1));
44523 h2 = tab.indexOf(input.charAt(i += 1));
44524 h3 = tab.indexOf(input.charAt(i += 1));
44525 h4 = tab.indexOf(input.charAt(i += 1));
44527 bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
44529 o1 = bits >> 16 & 0xff;
44530 o2 = bits >> 8 & 0xff;
44535 arr[ac] = String.fromCharCode(o1);
44536 } else if (h4 === 64) {
44537 arr[ac] = String.fromCharCode(o1, o2);
44539 arr[ac] = String.fromCharCode(o1, o2, o3);
44541 } while (i < input.length);
44543 dec = arr.join('');
44544 dec = (utf8) ? utf8Decode(dec) : dec;
44549 // set custom pad string
44550 this.setPad = function(str) {
44554 // set custom tab string characters
44555 this.setTab = function(str) {
44559 this.setUTF8 = function(bool) {
44560 if (typeof bool === 'boolean') {
44568 * CRC-32 calculation
44572 * @param {String} str Input String
44575 CRC32: function(str) {
44580 str = utf8Encode(str);
44583 '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
44584 '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
44585 '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
44586 '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
44587 'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
44588 '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
44589 'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
44590 '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
44591 'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
44592 '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
44593 'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
44594 '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
44595 'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
44596 '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
44597 '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
44598 '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
44599 '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
44600 'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
44601 '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
44602 'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
44603 '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
44604 'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
44605 '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
44606 'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
44607 '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
44608 'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
44612 for (i = 0, iTop = str.length; i < iTop; i += 1) {
44613 y = (crc ^ str.charCodeAt(i)) & 0xFF;
44614 x = '0x' + table.substr(y * 9, 8);
44615 crc = (crc >>> 8) ^ x;
44617 // always return a positive number (that's what >>> 0 does)
44618 return (crc ^ (-1)) >>> 0;
44624 * @param {Object} [config]
44626 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
44627 * Digest Algorithm, as defined in RFC 1321.
44628 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
44629 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44630 * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
44632 MD5: function(options) {
44634 * Private config properties. You may need to tweak these to be compatible with
44635 * the server-side, but the defaults work in most cases.
44636 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44638 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44639 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44640 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44642 // privileged (public) methods
44643 this.hex = function(s) {
44644 return rstr2hex(rstr(s, utf8), hexcase);
44646 this.b64 = function(s) {
44647 return rstr2b64(rstr(s), b64pad);
44649 this.any = function(s, e) {
44650 return rstr2any(rstr(s, utf8), e);
44652 this.raw = function(s) {
44653 return rstr(s, utf8);
44655 this.hex_hmac = function(k, d) {
44656 return rstr2hex(rstr_hmac(k, d), hexcase);
44658 this.b64_hmac = function(k, d) {
44659 return rstr2b64(rstr_hmac(k, d), b64pad);
44661 this.any_hmac = function(k, d, e) {
44662 return rstr2any(rstr_hmac(k, d), e);
44665 * Perform a simple self-test to see if the VM is working
44666 * @return {String} Hexadecimal hash sample
44668 this.vm_test = function() {
44669 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44672 * Enable/disable uppercase hexadecimal returned string
44674 * @return {Object} this
44676 this.setUpperCase = function(a) {
44677 if (typeof a === 'boolean') {
44683 * Defines a base64 pad string
44684 * @param {String} Pad
44685 * @return {Object} this
44687 this.setPad = function(a) {
44688 b64pad = a || b64pad;
44692 * Defines a base64 pad string
44694 * @return {Object} [this]
44696 this.setUTF8 = function(a) {
44697 if (typeof a === 'boolean') {
44706 * Calculate the MD5 of a raw string
44710 s = (utf8) ? utf8Encode(s) : s;
44711 return binl2rstr(binl(rstr2binl(s), s.length * 8));
44715 * Calculate the HMAC-MD5, of a key and some data (raw strings)
44718 function rstr_hmac(key, data) {
44719 var bkey, ipad, opad, hash, i;
44721 key = (utf8) ? utf8Encode(key) : key;
44722 data = (utf8) ? utf8Encode(data) : data;
44723 bkey = rstr2binl(key);
44724 if (bkey.length > 16) {
44725 bkey = binl(bkey, key.length * 8);
44728 ipad = Array(16), opad = Array(16);
44729 for (i = 0; i < 16; i += 1) {
44730 ipad[i] = bkey[i] ^ 0x36363636;
44731 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44733 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
44734 return binl2rstr(binl(opad.concat(hash), 512 + 128));
44738 * Calculate the MD5 of an array of little-endian words, and a bit length.
44741 function binl(x, len) {
44742 var i, olda, oldb, oldc, oldd,
44748 /* append padding */
44749 x[len >> 5] |= 0x80 << ((len) % 32);
44750 x[(((len + 64) >>> 9) << 4) + 14] = len;
44752 for (i = 0; i < x.length; i += 16) {
44758 a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
44759 d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
44760 c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
44761 b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
44762 a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
44763 d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
44764 c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
44765 b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
44766 a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
44767 d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
44768 c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
44769 b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
44770 a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
44771 d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
44772 c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
44773 b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
44775 a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
44776 d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
44777 c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
44778 b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
44779 a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
44780 d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
44781 c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
44782 b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
44783 a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
44784 d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
44785 c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
44786 b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
44787 a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
44788 d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
44789 c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
44790 b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
44792 a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
44793 d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
44794 c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
44795 b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
44796 a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
44797 d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
44798 c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
44799 b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
44800 a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
44801 d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
44802 c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
44803 b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
44804 a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
44805 d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
44806 c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
44807 b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
44809 a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
44810 d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
44811 c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
44812 b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
44813 a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
44814 d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
44815 c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
44816 b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
44817 a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
44818 d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
44819 c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
44820 b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
44821 a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
44822 d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
44823 c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
44824 b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
44826 a = safe_add(a, olda);
44827 b = safe_add(b, oldb);
44828 c = safe_add(c, oldc);
44829 d = safe_add(d, oldd);
44831 return Array(a, b, c, d);
44835 * These functions implement the four basic operations the algorithm uses.
44838 function md5_cmn(q, a, b, x, s, t) {
44839 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
44842 function md5_ff(a, b, c, d, x, s, t) {
44843 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
44846 function md5_gg(a, b, c, d, x, s, t) {
44847 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
44850 function md5_hh(a, b, c, d, x, s, t) {
44851 return md5_cmn(b ^ c ^ d, a, b, x, s, t);
44854 function md5_ii(a, b, c, d, x, s, t) {
44855 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
44860 * @class Hashes.SHA1
44861 * @param {Object} [config]
44864 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
44865 * Version 2.2 Copyright Paul Johnston 2000 - 2009.
44866 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
44867 * See http://pajhome.org.uk/crypt/md5 for details.
44869 SHA1: function(options) {
44871 * Private config properties. You may need to tweak these to be compatible with
44872 * the server-side, but the defaults work in most cases.
44873 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
44875 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
44876 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
44877 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
44880 this.hex = function(s) {
44881 return rstr2hex(rstr(s, utf8), hexcase);
44883 this.b64 = function(s) {
44884 return rstr2b64(rstr(s, utf8), b64pad);
44886 this.any = function(s, e) {
44887 return rstr2any(rstr(s, utf8), e);
44889 this.raw = function(s) {
44890 return rstr(s, utf8);
44892 this.hex_hmac = function(k, d) {
44893 return rstr2hex(rstr_hmac(k, d));
44895 this.b64_hmac = function(k, d) {
44896 return rstr2b64(rstr_hmac(k, d), b64pad);
44898 this.any_hmac = function(k, d, e) {
44899 return rstr2any(rstr_hmac(k, d), e);
44902 * Perform a simple self-test to see if the VM is working
44903 * @return {String} Hexadecimal hash sample
44906 this.vm_test = function() {
44907 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
44910 * @description Enable/disable uppercase hexadecimal returned string
44912 * @return {Object} this
44915 this.setUpperCase = function(a) {
44916 if (typeof a === 'boolean') {
44922 * @description Defines a base64 pad string
44923 * @param {string} Pad
44924 * @return {Object} this
44927 this.setPad = function(a) {
44928 b64pad = a || b64pad;
44932 * @description Defines a base64 pad string
44934 * @return {Object} this
44937 this.setUTF8 = function(a) {
44938 if (typeof a === 'boolean') {
44947 * Calculate the SHA-512 of a raw string
44951 s = (utf8) ? utf8Encode(s) : s;
44952 return binb2rstr(binb(rstr2binb(s), s.length * 8));
44956 * Calculate the HMAC-SHA1 of a key and some data (raw strings)
44959 function rstr_hmac(key, data) {
44960 var bkey, ipad, opad, i, hash;
44961 key = (utf8) ? utf8Encode(key) : key;
44962 data = (utf8) ? utf8Encode(data) : data;
44963 bkey = rstr2binb(key);
44965 if (bkey.length > 16) {
44966 bkey = binb(bkey, key.length * 8);
44968 ipad = Array(16), opad = Array(16);
44969 for (i = 0; i < 16; i += 1) {
44970 ipad[i] = bkey[i] ^ 0x36363636;
44971 opad[i] = bkey[i] ^ 0x5C5C5C5C;
44973 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
44974 return binb2rstr(binb(opad.concat(hash), 512 + 160));
44978 * Calculate the SHA-1 of an array of big-endian words, and a bit length
44981 function binb(x, len) {
44982 var i, j, t, olda, oldb, oldc, oldd, olde,
44990 /* append padding */
44991 x[len >> 5] |= 0x80 << (24 - len % 32);
44992 x[((len + 64 >> 9) << 4) + 15] = len;
44994 for (i = 0; i < x.length; i += 16) {
45001 for (j = 0; j < 80; j += 1) {
45005 w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
45007 t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
45008 safe_add(safe_add(e, w[j]), sha1_kt(j)));
45011 c = bit_rol(b, 30);
45016 a = safe_add(a, olda);
45017 b = safe_add(b, oldb);
45018 c = safe_add(c, oldc);
45019 d = safe_add(d, oldd);
45020 e = safe_add(e, olde);
45022 return Array(a, b, c, d, e);
45026 * Perform the appropriate triplet combination function for the current
45030 function sha1_ft(t, b, c, d) {
45032 return (b & c) | ((~b) & d);
45038 return (b & c) | (b & d) | (c & d);
45044 * Determine the appropriate additive constant for the current iteration
45047 function sha1_kt(t) {
45048 return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
45049 (t < 60) ? -1894007588 : -899497514;
45053 * @class Hashes.SHA256
45056 * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
45057 * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
45058 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45059 * See http://pajhome.org.uk/crypt/md5 for details.
45060 * Also http://anmar.eu.org/projects/jssha2/
45062 SHA256: function(options) {
45064 * Private properties configuration variables. You may need to tweak these to be compatible with
45065 * the server-side, but the defaults work in most cases.
45066 * @see this.setUpperCase() method
45067 * @see this.setPad() method
45069 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase */
45070 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45071 /* base-64 pad character. Default '=' for strict RFC compliance */
45072 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45073 /* enable/disable utf8 encoding */
45076 /* privileged (public) methods */
45077 this.hex = function(s) {
45078 return rstr2hex(rstr(s, utf8));
45080 this.b64 = function(s) {
45081 return rstr2b64(rstr(s, utf8), b64pad);
45083 this.any = function(s, e) {
45084 return rstr2any(rstr(s, utf8), e);
45086 this.raw = function(s) {
45087 return rstr(s, utf8);
45089 this.hex_hmac = function(k, d) {
45090 return rstr2hex(rstr_hmac(k, d));
45092 this.b64_hmac = function(k, d) {
45093 return rstr2b64(rstr_hmac(k, d), b64pad);
45095 this.any_hmac = function(k, d, e) {
45096 return rstr2any(rstr_hmac(k, d), e);
45099 * Perform a simple self-test to see if the VM is working
45100 * @return {String} Hexadecimal hash sample
45103 this.vm_test = function() {
45104 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45107 * Enable/disable uppercase hexadecimal returned string
45109 * @return {Object} this
45112 this.setUpperCase = function(a) {
45113 if (typeof a === 'boolean') {
45119 * @description Defines a base64 pad string
45120 * @param {string} Pad
45121 * @return {Object} this
45124 this.setPad = function(a) {
45125 b64pad = a || b64pad;
45129 * Defines a base64 pad string
45131 * @return {Object} this
45134 this.setUTF8 = function(a) {
45135 if (typeof a === 'boolean') {
45144 * Calculate the SHA-512 of a raw string
45147 function rstr(s, utf8) {
45148 s = (utf8) ? utf8Encode(s) : s;
45149 return binb2rstr(binb(rstr2binb(s), s.length * 8));
45153 * Calculate the HMAC-sha256 of a key and some data (raw strings)
45156 function rstr_hmac(key, data) {
45157 key = (utf8) ? utf8Encode(key) : key;
45158 data = (utf8) ? utf8Encode(data) : data;
45160 bkey = rstr2binb(key),
45164 if (bkey.length > 16) {
45165 bkey = binb(bkey, key.length * 8);
45168 for (; i < 16; i += 1) {
45169 ipad[i] = bkey[i] ^ 0x36363636;
45170 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45173 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
45174 return binb2rstr(binb(opad.concat(hash), 512 + 256));
45178 * Main sha256 function, with its support functions
45181 function sha256_S(X, n) {
45182 return (X >>> n) | (X << (32 - n));
45185 function sha256_R(X, n) {
45189 function sha256_Ch(x, y, z) {
45190 return ((x & y) ^ ((~x) & z));
45193 function sha256_Maj(x, y, z) {
45194 return ((x & y) ^ (x & z) ^ (y & z));
45197 function sha256_Sigma0256(x) {
45198 return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
45201 function sha256_Sigma1256(x) {
45202 return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
45205 function sha256_Gamma0256(x) {
45206 return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
45209 function sha256_Gamma1256(x) {
45210 return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
45214 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
45215 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
45216 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
45217 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
45218 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
45219 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
45220 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
45223 function binb(m, l) {
45224 var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
45225 1359893119, -1694144372, 528734635, 1541459225
45227 var W = new Array(64);
45228 var a, b, c, d, e, f, g, h;
45231 /* append padding */
45232 m[l >> 5] |= 0x80 << (24 - l % 32);
45233 m[((l + 64 >> 9) << 4) + 15] = l;
45235 for (i = 0; i < m.length; i += 16) {
45245 for (j = 0; j < 64; j += 1) {
45249 W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
45250 sha256_Gamma0256(W[j - 15])), W[j - 16]);
45253 T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
45254 sha256_K[j]), W[j]);
45255 T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
45259 e = safe_add(d, T1);
45263 a = safe_add(T1, T2);
45266 HASH[0] = safe_add(a, HASH[0]);
45267 HASH[1] = safe_add(b, HASH[1]);
45268 HASH[2] = safe_add(c, HASH[2]);
45269 HASH[3] = safe_add(d, HASH[3]);
45270 HASH[4] = safe_add(e, HASH[4]);
45271 HASH[5] = safe_add(f, HASH[5]);
45272 HASH[6] = safe_add(g, HASH[6]);
45273 HASH[7] = safe_add(h, HASH[7]);
45281 * @class Hashes.SHA512
45284 * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
45285 * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
45286 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45287 * See http://pajhome.org.uk/crypt/md5 for details.
45289 SHA512: function(options) {
45291 * Private properties configuration variables. You may need to tweak these to be compatible with
45292 * the server-side, but the defaults work in most cases.
45293 * @see this.setUpperCase() method
45294 * @see this.setPad() method
45296 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
45297 /* hexadecimal output case format. false - lowercase; true - uppercase */
45298 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45299 /* base-64 pad character. Default '=' for strict RFC compliance */
45300 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45301 /* enable/disable utf8 encoding */
45304 /* privileged (public) methods */
45305 this.hex = function(s) {
45306 return rstr2hex(rstr(s));
45308 this.b64 = function(s) {
45309 return rstr2b64(rstr(s), b64pad);
45311 this.any = function(s, e) {
45312 return rstr2any(rstr(s), e);
45314 this.raw = function(s) {
45315 return rstr(s, utf8);
45317 this.hex_hmac = function(k, d) {
45318 return rstr2hex(rstr_hmac(k, d));
45320 this.b64_hmac = function(k, d) {
45321 return rstr2b64(rstr_hmac(k, d), b64pad);
45323 this.any_hmac = function(k, d, e) {
45324 return rstr2any(rstr_hmac(k, d), e);
45327 * Perform a simple self-test to see if the VM is working
45328 * @return {String} Hexadecimal hash sample
45331 this.vm_test = function() {
45332 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45335 * @description Enable/disable uppercase hexadecimal returned string
45337 * @return {Object} this
45340 this.setUpperCase = function(a) {
45341 if (typeof a === 'boolean') {
45347 * @description Defines a base64 pad string
45348 * @param {string} Pad
45349 * @return {Object} this
45352 this.setPad = function(a) {
45353 b64pad = a || b64pad;
45357 * @description Defines a base64 pad string
45359 * @return {Object} this
45362 this.setUTF8 = function(a) {
45363 if (typeof a === 'boolean') {
45369 /* private methods */
45372 * Calculate the SHA-512 of a raw string
45376 s = (utf8) ? utf8Encode(s) : s;
45377 return binb2rstr(binb(rstr2binb(s), s.length * 8));
45380 * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
45383 function rstr_hmac(key, data) {
45384 key = (utf8) ? utf8Encode(key) : key;
45385 data = (utf8) ? utf8Encode(data) : data;
45388 bkey = rstr2binb(key),
45392 if (bkey.length > 32) {
45393 bkey = binb(bkey, key.length * 8);
45396 for (; i < 32; i += 1) {
45397 ipad[i] = bkey[i] ^ 0x36363636;
45398 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45401 hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
45402 return binb2rstr(binb(opad.concat(hash), 1024 + 512));
45406 * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
45409 function binb(x, len) {
45412 hash = new Array(16),
45413 //Initial hash values
45415 new int64(0x6a09e667, -205731576),
45416 new int64(-1150833019, -2067093701),
45417 new int64(0x3c6ef372, -23791573),
45418 new int64(-1521486534, 0x5f1d36f1),
45419 new int64(0x510e527f, -1377402159),
45420 new int64(-1694144372, 0x2b3e6c1f),
45421 new int64(0x1f83d9ab, -79577749),
45422 new int64(0x5be0cd19, 0x137e2179)
45424 T1 = new int64(0, 0),
45425 T2 = new int64(0, 0),
45426 a = new int64(0, 0),
45427 b = new int64(0, 0),
45428 c = new int64(0, 0),
45429 d = new int64(0, 0),
45430 e = new int64(0, 0),
45431 f = new int64(0, 0),
45432 g = new int64(0, 0),
45433 h = new int64(0, 0),
45434 //Temporary variables not specified by the document
45435 s0 = new int64(0, 0),
45436 s1 = new int64(0, 0),
45437 Ch = new int64(0, 0),
45438 Maj = new int64(0, 0),
45439 r1 = new int64(0, 0),
45440 r2 = new int64(0, 0),
45441 r3 = new int64(0, 0);
45443 if (sha512_k === undefined) {
45446 new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
45447 new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
45448 new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
45449 new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
45450 new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
45451 new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
45452 new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
45453 new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
45454 new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
45455 new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
45456 new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
45457 new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
45458 new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
45459 new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
45460 new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
45461 new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
45462 new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
45463 new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
45464 new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
45465 new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
45466 new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
45467 new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
45468 new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
45469 new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
45470 new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
45471 new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
45472 new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
45473 new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
45474 new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
45475 new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
45476 new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
45477 new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
45478 new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
45479 new int64(-354779690, -840897762), new int64(-176337025, -294727304),
45480 new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
45481 new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
45482 new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
45483 new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
45484 new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
45485 new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
45489 for (i = 0; i < 80; i += 1) {
45490 W[i] = new int64(0, 0);
45493 // append padding to the source string. The format is described in the FIPS.
45494 x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
45495 x[((len + 128 >> 10) << 5) + 31] = len;
45497 for (i = 0; i < l; i += 32) { //32 dwords is the block size
45498 int64copy(a, H[0]);
45499 int64copy(b, H[1]);
45500 int64copy(c, H[2]);
45501 int64copy(d, H[3]);
45502 int64copy(e, H[4]);
45503 int64copy(f, H[5]);
45504 int64copy(g, H[6]);
45505 int64copy(h, H[7]);
45507 for (j = 0; j < 16; j += 1) {
45508 W[j].h = x[i + 2 * j];
45509 W[j].l = x[i + 2 * j + 1];
45512 for (j = 16; j < 80; j += 1) {
45514 int64rrot(r1, W[j - 2], 19);
45515 int64revrrot(r2, W[j - 2], 29);
45516 int64shr(r3, W[j - 2], 6);
45517 s1.l = r1.l ^ r2.l ^ r3.l;
45518 s1.h = r1.h ^ r2.h ^ r3.h;
45520 int64rrot(r1, W[j - 15], 1);
45521 int64rrot(r2, W[j - 15], 8);
45522 int64shr(r3, W[j - 15], 7);
45523 s0.l = r1.l ^ r2.l ^ r3.l;
45524 s0.h = r1.h ^ r2.h ^ r3.h;
45526 int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
45529 for (j = 0; j < 80; j += 1) {
45531 Ch.l = (e.l & f.l) ^ (~e.l & g.l);
45532 Ch.h = (e.h & f.h) ^ (~e.h & g.h);
45535 int64rrot(r1, e, 14);
45536 int64rrot(r2, e, 18);
45537 int64revrrot(r3, e, 9);
45538 s1.l = r1.l ^ r2.l ^ r3.l;
45539 s1.h = r1.h ^ r2.h ^ r3.h;
45542 int64rrot(r1, a, 28);
45543 int64revrrot(r2, a, 2);
45544 int64revrrot(r3, a, 7);
45545 s0.l = r1.l ^ r2.l ^ r3.l;
45546 s0.h = r1.h ^ r2.h ^ r3.h;
45549 Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
45550 Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
45552 int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
45553 int64add(T2, s0, Maj);
45558 int64add(e, d, T1);
45562 int64add(a, T1, T2);
45564 int64add(H[0], H[0], a);
45565 int64add(H[1], H[1], b);
45566 int64add(H[2], H[2], c);
45567 int64add(H[3], H[3], d);
45568 int64add(H[4], H[4], e);
45569 int64add(H[5], H[5], f);
45570 int64add(H[6], H[6], g);
45571 int64add(H[7], H[7], h);
45574 //represent the hash as an array of 32-bit dwords
45575 for (i = 0; i < 8; i += 1) {
45576 hash[2 * i] = H[i].h;
45577 hash[2 * i + 1] = H[i].l;
45582 //A constructor for 64-bit numbers
45584 function int64(h, l) {
45587 //this.toString = int64toString;
45590 //Copies src into dst, assuming both are 64-bit numbers
45592 function int64copy(dst, src) {
45597 //Right-rotates a 64-bit number by shift
45598 //Won't handle cases of shift>=32
45599 //The function revrrot() is for that
45601 function int64rrot(dst, x, shift) {
45602 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45603 dst.h = (x.h >>> shift) | (x.l << (32 - shift));
45606 //Reverses the dwords of the source and then rotates right by shift.
45607 //This is equivalent to rotation by 32+shift
45609 function int64revrrot(dst, x, shift) {
45610 dst.l = (x.h >>> shift) | (x.l << (32 - shift));
45611 dst.h = (x.l >>> shift) | (x.h << (32 - shift));
45614 //Bitwise-shifts right a 64-bit number by shift
45615 //Won't handle shift>=32, but it's never needed in SHA512
45617 function int64shr(dst, x, shift) {
45618 dst.l = (x.l >>> shift) | (x.h << (32 - shift));
45619 dst.h = (x.h >>> shift);
45622 //Adds two 64-bit numbers
45623 //Like the original implementation, does not rely on 32-bit operations
45625 function int64add(dst, x, y) {
45626 var w0 = (x.l & 0xffff) + (y.l & 0xffff);
45627 var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
45628 var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
45629 var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
45630 dst.l = (w0 & 0xffff) | (w1 << 16);
45631 dst.h = (w2 & 0xffff) | (w3 << 16);
45634 //Same, except with 4 addends. Works faster than adding them one by one.
45636 function int64add4(dst, a, b, c, d) {
45637 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
45638 var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
45639 var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
45640 var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
45641 dst.l = (w0 & 0xffff) | (w1 << 16);
45642 dst.h = (w2 & 0xffff) | (w3 << 16);
45645 //Same, except with 5 addends
45647 function int64add5(dst, a, b, c, d, e) {
45648 var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
45649 w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
45650 w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
45651 w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
45652 dst.l = (w0 & 0xffff) | (w1 << 16);
45653 dst.h = (w2 & 0xffff) | (w3 << 16);
45657 * @class Hashes.RMD160
45659 * @param {Object} [config]
45661 * A JavaScript implementation of the RIPEMD-160 Algorithm
45662 * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
45663 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
45664 * See http://pajhome.org.uk/crypt/md5 for details.
45665 * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
45667 RMD160: function(options) {
45669 * Private properties configuration variables. You may need to tweak these to be compatible with
45670 * the server-side, but the defaults work in most cases.
45671 * @see this.setUpperCase() method
45672 * @see this.setPad() method
45674 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
45675 /* hexadecimal output case format. false - lowercase; true - uppercase */
45676 b64pad = (options && typeof options.pad === 'string') ? options.pda : '=',
45677 /* base-64 pad character. Default '=' for strict RFC compliance */
45678 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
45679 /* enable/disable utf8 encoding */
45681 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
45682 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
45683 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
45684 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
45685 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
45688 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
45689 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
45690 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
45691 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
45692 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
45695 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
45696 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
45697 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
45698 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
45699 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
45702 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
45703 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
45704 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
45705 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
45706 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
45709 /* privileged (public) methods */
45710 this.hex = function(s) {
45711 return rstr2hex(rstr(s, utf8));
45713 this.b64 = function(s) {
45714 return rstr2b64(rstr(s, utf8), b64pad);
45716 this.any = function(s, e) {
45717 return rstr2any(rstr(s, utf8), e);
45719 this.raw = function(s) {
45720 return rstr(s, utf8);
45722 this.hex_hmac = function(k, d) {
45723 return rstr2hex(rstr_hmac(k, d));
45725 this.b64_hmac = function(k, d) {
45726 return rstr2b64(rstr_hmac(k, d), b64pad);
45728 this.any_hmac = function(k, d, e) {
45729 return rstr2any(rstr_hmac(k, d), e);
45732 * Perform a simple self-test to see if the VM is working
45733 * @return {String} Hexadecimal hash sample
45736 this.vm_test = function() {
45737 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
45740 * @description Enable/disable uppercase hexadecimal returned string
45742 * @return {Object} this
45745 this.setUpperCase = function(a) {
45746 if (typeof a === 'boolean') {
45752 * @description Defines a base64 pad string
45753 * @param {string} Pad
45754 * @return {Object} this
45757 this.setPad = function(a) {
45758 if (typeof a !== 'undefined') {
45764 * @description Defines a base64 pad string
45766 * @return {Object} this
45769 this.setUTF8 = function(a) {
45770 if (typeof a === 'boolean') {
45776 /* private methods */
45779 * Calculate the rmd160 of a raw string
45783 s = (utf8) ? utf8Encode(s) : s;
45784 return binl2rstr(binl(rstr2binl(s), s.length * 8));
45788 * Calculate the HMAC-rmd160 of a key and some data (raw strings)
45791 function rstr_hmac(key, data) {
45792 key = (utf8) ? utf8Encode(key) : key;
45793 data = (utf8) ? utf8Encode(data) : data;
45795 bkey = rstr2binl(key),
45799 if (bkey.length > 16) {
45800 bkey = binl(bkey, key.length * 8);
45803 for (i = 0; i < 16; i += 1) {
45804 ipad[i] = bkey[i] ^ 0x36363636;
45805 opad[i] = bkey[i] ^ 0x5C5C5C5C;
45807 hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
45808 return binl2rstr(binl(opad.concat(hash), 512 + 160));
45812 * Convert an array of little-endian words to a string
45815 function binl2rstr(input) {
45816 var i, output = '',
45817 l = input.length * 32;
45818 for (i = 0; i < l; i += 8) {
45819 output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
45825 * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
45828 function binl(x, len) {
45835 A1, B1, C1, D1, E1,
45836 A2, B2, C2, D2, E2;
45838 /* append padding */
45839 x[len >> 5] |= 0x80 << (len % 32);
45840 x[(((len + 64) >>> 9) << 4) + 14] = len;
45843 for (i = 0; i < l; i += 16) {
45849 for (j = 0; j <= 79; j += 1) {
45850 T = safe_add(A1, rmd160_f(j, B1, C1, D1));
45851 T = safe_add(T, x[i + rmd160_r1[j]]);
45852 T = safe_add(T, rmd160_K1(j));
45853 T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
45856 D1 = bit_rol(C1, 10);
45859 T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
45860 T = safe_add(T, x[i + rmd160_r2[j]]);
45861 T = safe_add(T, rmd160_K2(j));
45862 T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
45865 D2 = bit_rol(C2, 10);
45870 T = safe_add(h1, safe_add(C1, D2));
45871 h1 = safe_add(h2, safe_add(D1, E2));
45872 h2 = safe_add(h3, safe_add(E1, A2));
45873 h3 = safe_add(h4, safe_add(A1, B2));
45874 h4 = safe_add(h0, safe_add(B1, C2));
45877 return [h0, h1, h2, h3, h4];
45880 // specific algorithm methods
45882 function rmd160_f(j, x, y, z) {
45883 return (0 <= j && j <= 15) ? (x ^ y ^ z) :
45884 (16 <= j && j <= 31) ? (x & y) | (~x & z) :
45885 (32 <= j && j <= 47) ? (x | ~y) ^ z :
45886 (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
45887 (64 <= j && j <= 79) ? x ^ (y | ~z) :
45888 'rmd160_f: j out of range';
45891 function rmd160_K1(j) {
45892 return (0 <= j && j <= 15) ? 0x00000000 :
45893 (16 <= j && j <= 31) ? 0x5a827999 :
45894 (32 <= j && j <= 47) ? 0x6ed9eba1 :
45895 (48 <= j && j <= 63) ? 0x8f1bbcdc :
45896 (64 <= j && j <= 79) ? 0xa953fd4e :
45897 'rmd160_K1: j out of range';
45900 function rmd160_K2(j) {
45901 return (0 <= j && j <= 15) ? 0x50a28be6 :
45902 (16 <= j && j <= 31) ? 0x5c4dd124 :
45903 (32 <= j && j <= 47) ? 0x6d703ef3 :
45904 (48 <= j && j <= 63) ? 0x7a6d76e9 :
45905 (64 <= j && j <= 79) ? 0x00000000 :
45906 'rmd160_K2: j out of range';
45912 (function(window, undefined) {
45913 var freeExports = false;
45915 freeExports = exports;
45916 if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
45917 window = commonjsGlobal;
45921 if (typeof undefined === 'function' && typeof undefined.amd === 'object' && undefined.amd) {
45922 // define as an anonymous module, so, through path mapping, it can be aliased
45923 undefined(function() {
45926 } else if (freeExports) {
45927 // in Node.js or RingoJS v0.8.0+
45928 if ('object' === 'object' && module && module.exports === freeExports) {
45929 module.exports = Hashes;
45931 // in Narwhal or RingoJS v0.7.0-
45933 freeExports.Hashes = Hashes;
45936 // in a browser or Rhino
45937 window.Hashes = Hashes;
45943 var immutable = extend$2;
45945 var hasOwnProperty = Object.prototype.hasOwnProperty;
45947 function extend$2() {
45950 for (var i = 0; i < arguments.length; i++) {
45951 var source = arguments[i];
45953 for (var key in source) {
45954 if (hasOwnProperty.call(source, key)) {
45955 target[key] = source[key];
45963 var hashes = hashes$1;
45964 var xtend$1 = immutable;
45965 var sha1 = new hashes.SHA1();
45969 ohauth$1.qsString = function(obj) {
45970 return Object.keys(obj).sort().map(function(key) {
45971 return ohauth$1.percentEncode(key) + '=' +
45972 ohauth$1.percentEncode(obj[key]);
45976 ohauth$1.stringQs = function(str) {
45977 return str.split('&').filter(function (pair) {
45978 return pair !== '';
45979 }).reduce(function(obj, pair){
45980 var parts = pair.split('=');
45981 obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
45982 '' : decodeURIComponent(parts[1]);
45987 ohauth$1.rawxhr = function(method, url, data, headers, callback) {
45988 var xhr = new XMLHttpRequest(),
45989 twoHundred = /^20\d$/;
45990 xhr.onreadystatechange = function() {
45991 if (4 === xhr.readyState && 0 !== xhr.status) {
45992 if (twoHundred.test(xhr.status)) callback(null, xhr);
45993 else return callback(xhr, null);
45996 xhr.onerror = function(e) { return callback(e, null); };
45997 xhr.open(method, url, true);
45998 for (var h in headers) xhr.setRequestHeader(h, headers[h]);
46003 ohauth$1.xhr = function(method, url, auth, data, options, callback) {
46004 var headers = (options && options.header) || {
46005 'Content-Type': 'application/x-www-form-urlencoded'
46007 headers.Authorization = 'OAuth ' + ohauth$1.authHeader(auth);
46008 return ohauth$1.rawxhr(method, url, data, headers, callback);
46011 ohauth$1.nonce = function() {
46012 for (var o = ''; o.length < 6;) {
46013 o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
46018 ohauth$1.authHeader = function(obj) {
46019 return Object.keys(obj).sort().map(function(key) {
46020 return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
46024 ohauth$1.timestamp = function() { return ~~((+new Date()) / 1000); };
46026 ohauth$1.percentEncode = function(s) {
46027 return encodeURIComponent(s)
46028 .replace(/\!/g, '%21').replace(/\'/g, '%27')
46029 .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
46032 ohauth$1.baseString = function(method, url, params) {
46033 if (params.oauth_signature) delete params.oauth_signature;
46036 ohauth$1.percentEncode(url),
46037 ohauth$1.percentEncode(ohauth$1.qsString(params))].join('&');
46040 ohauth$1.signature = function(oauth_secret, token_secret, baseString) {
46041 return sha1.b64_hmac(
46042 ohauth$1.percentEncode(oauth_secret) + '&' +
46043 ohauth$1.percentEncode(token_secret),
46048 * Takes an options object for configuration (consumer_key,
46049 * consumer_secret, version, signature_method, token, token_secret)
46050 * and returns a function that generates the Authorization header
46053 * The returned function takes these parameters:
46054 * - method: GET/POST/...
46055 * - uri: full URI with protocol, port, path and query string
46056 * - extra_params: any extra parameters (that are passed in the POST data),
46057 * can be an object or a from-urlencoded string.
46059 * Returned function returns full OAuth header with "OAuth" string in it.
46062 ohauth$1.headerGenerator = function(options) {
46063 options = options || {};
46064 var consumer_key = options.consumer_key || '',
46065 consumer_secret = options.consumer_secret || '',
46066 signature_method = options.signature_method || 'HMAC-SHA1',
46067 version = options.version || '1.0',
46068 token = options.token || '',
46069 token_secret = options.token_secret || '';
46071 return function(method, uri, extra_params) {
46072 method = method.toUpperCase();
46073 if (typeof extra_params === 'string' && extra_params.length > 0) {
46074 extra_params = ohauth$1.stringQs(extra_params);
46077 var uri_parts = uri.split('?', 2),
46078 base_uri = uri_parts[0];
46080 var query_params = uri_parts.length === 2 ?
46081 ohauth$1.stringQs(uri_parts[1]) : {};
46083 var oauth_params = {
46084 oauth_consumer_key: consumer_key,
46085 oauth_signature_method: signature_method,
46086 oauth_version: version,
46087 oauth_timestamp: ohauth$1.timestamp(),
46088 oauth_nonce: ohauth$1.nonce()
46091 if (token) oauth_params.oauth_token = token;
46093 var all_params = xtend$1({}, oauth_params, query_params, extra_params),
46094 base_str = ohauth$1.baseString(method, base_uri, all_params);
46096 oauth_params.oauth_signature = ohauth$1.signature(consumer_secret, token_secret, base_str);
46098 return 'OAuth ' + ohauth$1.authHeader(oauth_params);
46102 var index$13 = ohauth$1;
46104 var store$1 = createCommonjsModule(function (module, exports) {
46106 // Module export pattern from
46107 // https://github.com/umdjs/umd/blob/master/returnExports.js
46108 ;(function (root, factory) {
46109 if (typeof undefined === 'function' && undefined.amd) {
46110 // AMD. Register as an anonymous module.
46111 undefined([], factory);
46113 // Node. Does not work with strict CommonJS, but
46114 // only CommonJS-like environments that support module.exports,
46116 module.exports = factory();
46118 }(commonjsGlobal, function () {
46122 win = (typeof window != 'undefined' ? window : commonjsGlobal),
46123 doc = win.document,
46124 localStorageName = 'localStorage',
46125 scriptTag = 'script',
46128 store.disabled = false;
46129 store.version = '1.3.20';
46130 store.set = function(key, value) {};
46131 store.get = function(key, defaultVal) {};
46132 store.has = function(key) { return store.get(key) !== undefined };
46133 store.remove = function(key) {};
46134 store.clear = function() {};
46135 store.transact = function(key, defaultVal, transactionFn) {
46136 if (transactionFn == null) {
46137 transactionFn = defaultVal;
46140 if (defaultVal == null) {
46143 var val = store.get(key, defaultVal);
46144 transactionFn(val);
46145 store.set(key, val);
46147 store.getAll = function() {};
46148 store.forEach = function() {};
46150 store.serialize = function(value) {
46151 return JSON.stringify(value)
46153 store.deserialize = function(value) {
46154 if (typeof value != 'string') { return undefined }
46155 try { return JSON.parse(value) }
46156 catch(e) { return value || undefined }
46159 // Functions to encapsulate questionable FireFox 3.6.13 behavior
46160 // when about.config::dom.storage.enabled === false
46161 // See https://github.com/marcuswestin/store.js/issues#issue/13
46162 function isLocalStorageNameSupported() {
46163 try { return (localStorageName in win && win[localStorageName]) }
46164 catch(err) { return false }
46167 if (isLocalStorageNameSupported()) {
46168 storage = win[localStorageName];
46169 store.set = function(key, val) {
46170 if (val === undefined) { return store.remove(key) }
46171 storage.setItem(key, store.serialize(val));
46174 store.get = function(key, defaultVal) {
46175 var val = store.deserialize(storage.getItem(key));
46176 return (val === undefined ? defaultVal : val)
46178 store.remove = function(key) { storage.removeItem(key); };
46179 store.clear = function() { storage.clear(); };
46180 store.getAll = function() {
46182 store.forEach(function(key, val) {
46187 store.forEach = function(callback) {
46188 for (var i=0; i<storage.length; i++) {
46189 var key = storage.key(i);
46190 callback(key, store.get(key));
46193 } else if (doc && doc.documentElement.addBehavior) {
46196 // Since #userData storage applies only to specific paths, we need to
46197 // somehow link our data to a specific path. We choose /favicon.ico
46198 // as a pretty safe option, since all browsers already make a request to
46199 // this URL anyway and being a 404 will not hurt us here. We wrap an
46200 // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
46201 // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
46202 // since the iframe access rules appear to allow direct access and
46203 // manipulation of the document element, even for a 404 page. This
46204 // document can be used instead of the current document (which would
46205 // have been limited to the current path) to perform #userData storage.
46207 storageContainer = new ActiveXObject('htmlfile');
46208 storageContainer.open();
46209 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
46210 storageContainer.close();
46211 storageOwner = storageContainer.w.frames[0].document;
46212 storage = storageOwner.createElement('div');
46214 // somehow ActiveXObject instantiation failed (perhaps some special
46215 // security settings or otherwse), fall back to per-path storage
46216 storage = doc.createElement('div');
46217 storageOwner = doc.body;
46219 var withIEStorage = function(storeFunction) {
46220 return function() {
46221 var args = Array.prototype.slice.call(arguments, 0);
46222 args.unshift(storage);
46223 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
46224 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
46225 storageOwner.appendChild(storage);
46226 storage.addBehavior('#default#userData');
46227 storage.load(localStorageName);
46228 var result = storeFunction.apply(store, args);
46229 storageOwner.removeChild(storage);
46234 // In IE7, keys cannot start with a digit or contain certain chars.
46235 // See https://github.com/marcuswestin/store.js/issues/40
46236 // See https://github.com/marcuswestin/store.js/issues/83
46237 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
46238 var ieKeyFix = function(key) {
46239 return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')
46241 store.set = withIEStorage(function(storage, key, val) {
46242 key = ieKeyFix(key);
46243 if (val === undefined) { return store.remove(key) }
46244 storage.setAttribute(key, store.serialize(val));
46245 storage.save(localStorageName);
46248 store.get = withIEStorage(function(storage, key, defaultVal) {
46249 key = ieKeyFix(key);
46250 var val = store.deserialize(storage.getAttribute(key));
46251 return (val === undefined ? defaultVal : val)
46253 store.remove = withIEStorage(function(storage, key) {
46254 key = ieKeyFix(key);
46255 storage.removeAttribute(key);
46256 storage.save(localStorageName);
46258 store.clear = withIEStorage(function(storage) {
46259 var attributes = storage.XMLDocument.documentElement.attributes;
46260 storage.load(localStorageName);
46261 for (var i=attributes.length-1; i>=0; i--) {
46262 storage.removeAttribute(attributes[i].name);
46264 storage.save(localStorageName);
46266 store.getAll = function(storage) {
46268 store.forEach(function(key, val) {
46273 store.forEach = withIEStorage(function(storage, callback) {
46274 var attributes = storage.XMLDocument.documentElement.attributes;
46275 for (var i=0, attr; attr=attributes[i]; ++i) {
46276 callback(attr.name, store.deserialize(storage.getAttribute(attr.name)));
46282 var testKey = '__storejs__';
46283 store.set(testKey, testKey);
46284 if (store.get(testKey) != testKey) { store.disabled = true; }
46285 store.remove(testKey);
46287 store.disabled = true;
46289 store.enabled = !store.disabled;
46295 var ohauth = index$13;
46296 var xtend = immutable;
46297 var store = store$1;
46301 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
46302 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
46303 // does not support custom headers, which this uses everywhere.
46304 var index$12 = function(o) {
46308 // authenticated users will also have a request token secret, but it's
46309 // not used in transactions with the server
46310 oauth.authenticated = function() {
46311 return !!(token('oauth_token') && token('oauth_token_secret'));
46314 oauth.logout = function() {
46315 token('oauth_token', '');
46316 token('oauth_token_secret', '');
46317 token('oauth_request_token_secret', '');
46321 // TODO: detect lack of click event
46322 oauth.authenticate = function(callback) {
46323 if (oauth.authenticated()) return callback();
46327 // ## Getting a request token
46328 var params = timenonce(getAuth(o)),
46329 url = o.url + '/oauth/request_token';
46331 params.oauth_signature = ohauth.signature(
46332 o.oauth_secret, '',
46333 ohauth.baseString('POST', url, params));
46335 if (!o.singlepage) {
46336 // Create a 600x550 popup window in the center of the screen
46337 var w = 600, h = 550,
46339 ['width', w], ['height', h],
46340 ['left', screen.width / 2 - w / 2],
46341 ['top', screen.height / 2 - h / 2]].map(function(x) {
46342 return x.join('=');
46344 popup = window.open('about:blank', 'oauth_window', settings);
46347 // Request a request token. When this is complete, the popup
46348 // window is redirected to OSM's authorization page.
46349 ohauth.xhr('POST', url, params, null, {}, reqTokenDone);
46352 function reqTokenDone(err, xhr) {
46354 if (err) return callback(err);
46355 var resp = ohauth.stringQs(xhr.response);
46356 token('oauth_request_token_secret', resp.oauth_token_secret);
46357 var authorize_url = o.url + '/oauth/authorize?' + ohauth.qsString({
46358 oauth_token: resp.oauth_token,
46359 oauth_callback: location.href.replace('index.html', '')
46360 .replace(/#.*/, '').replace(location.search, '') + o.landing
46363 if (o.singlepage) {
46364 location.href = authorize_url;
46366 popup.location = authorize_url;
46370 // Called by a function in a landing page, in the popup window. The
46371 // window closes itself.
46372 window.authComplete = function(token) {
46373 var oauth_token = ohauth.stringQs(token.split('?')[1]);
46374 get_access_token(oauth_token.oauth_token);
46375 delete window.authComplete;
46378 // ## Getting an request token
46380 // At this point we have an `oauth_token`, brought in from a function
46381 // call on a landing page popup.
46382 function get_access_token(oauth_token) {
46383 var url = o.url + '/oauth/access_token',
46384 params = timenonce(getAuth(o)),
46385 request_token_secret = token('oauth_request_token_secret');
46386 params.oauth_token = oauth_token;
46387 params.oauth_signature = ohauth.signature(
46389 request_token_secret,
46390 ohauth.baseString('POST', url, params));
46392 // ## Getting an access token
46394 // The final token required for authentication. At this point
46395 // we have a `request token secret`
46396 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
46400 function accessTokenDone(err, xhr) {
46402 if (err) return callback(err);
46403 var access_token = ohauth.stringQs(xhr.response);
46404 token('oauth_token', access_token.oauth_token);
46405 token('oauth_token_secret', access_token.oauth_token_secret);
46406 callback(null, oauth);
46410 oauth.bootstrapToken = function(oauth_token, callback) {
46411 // ## Getting an request token
46412 // At this point we have an `oauth_token`, brought in from a function
46413 // call on a landing page popup.
46414 function get_access_token(oauth_token) {
46415 var url = o.url + '/oauth/access_token',
46416 params = timenonce(getAuth(o)),
46417 request_token_secret = token('oauth_request_token_secret');
46418 params.oauth_token = oauth_token;
46419 params.oauth_signature = ohauth.signature(
46421 request_token_secret,
46422 ohauth.baseString('POST', url, params));
46424 // ## Getting an access token
46425 // The final token required for authentication. At this point
46426 // we have a `request token secret`
46427 ohauth.xhr('POST', url, params, null, {}, accessTokenDone);
46431 function accessTokenDone(err, xhr) {
46433 if (err) return callback(err);
46434 var access_token = ohauth.stringQs(xhr.response);
46435 token('oauth_token', access_token.oauth_token);
46436 token('oauth_token_secret', access_token.oauth_token_secret);
46437 callback(null, oauth);
46440 get_access_token(oauth_token);
46445 // A single XMLHttpRequest wrapper that does authenticated calls if the
46446 // user has logged in.
46447 oauth.xhr = function(options, callback) {
46448 if (!oauth.authenticated()) {
46450 return oauth.authenticate(run);
46452 callback('not authenticated', null);
46460 var params = timenonce(getAuth(o)),
46461 oauth_token_secret = token('oauth_token_secret'),
46462 url = (options.prefix !== false) ? o.url + options.path : options.path,
46463 url_parts = url.replace(/#.*$/, '').split('?', 2),
46464 base_url = url_parts[0],
46465 query = (url_parts.length === 2) ? url_parts[1] : '';
46467 // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
46468 if ((!options.options || !options.options.header ||
46469 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
46471 params = xtend(params, ohauth.stringQs(options.content));
46474 params.oauth_token = token('oauth_token');
46475 params.oauth_signature = ohauth.signature(
46477 oauth_token_secret,
46478 ohauth.baseString(options.method, base_url, xtend(params, ohauth.stringQs(query)))
46481 return ohauth.xhr(options.method, url, params, options.content, options.options, done);
46484 function done(err, xhr) {
46485 if (err) return callback(err);
46486 else if (xhr.responseXML) return callback(err, xhr.responseXML);
46487 else return callback(err, xhr.response);
46491 // pre-authorize this object, if we can just get a token and token_secret
46493 oauth.preauth = function(c) {
46495 if (c.oauth_token) token('oauth_token', c.oauth_token);
46496 if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
46500 oauth.options = function(_) {
46501 if (!arguments.length) return o;
46504 o.url = o.url || 'http://www.openstreetmap.org';
46505 o.landing = o.landing || 'land.html';
46506 o.singlepage = o.singlepage || false;
46508 // Optional loading and loading-done functions for nice UI feedback.
46509 // by default, no-ops
46510 o.loading = o.loading || function() {};
46511 o.done = o.done || function() {};
46513 return oauth.preauth(o);
46516 // 'stamp' an authentication object from `getAuth()`
46517 // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
46519 function timenonce(o) {
46520 o.oauth_timestamp = ohauth.timestamp();
46521 o.oauth_nonce = ohauth.nonce();
46525 // get/set tokens. These are prefixed with the base URL so that `osm-auth`
46526 // can be used with multiple APIs and the keys in `localStorage`
46530 if (store.enabled) {
46531 token = function (x, y) {
46532 if (arguments.length === 1) return store.get(o.url + x);
46533 else if (arguments.length === 2) return store.set(o.url + x, y);
46537 token = function (x, y) {
46538 if (arguments.length === 1) return storage[o.url + x];
46539 else if (arguments.length === 2) return storage[o.url + x] = y;
46543 // Get an authentication object. If you just add and remove properties
46544 // from a single object, you'll need to use `delete` to make sure that
46545 // it doesn't contain undesired properties for authentication
46546 function getAuth(o) {
46548 oauth_consumer_key: o.oauth_consumer_key,
46549 oauth_signature_method: 'HMAC-SHA1'
46553 // potentially pre-authorize
46559 var JXON = new (function () {
46561 sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
46562 aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
46564 function parseText (sValue) {
46565 if (rIsNull.test(sValue)) { return null; }
46566 if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
46567 if (isFinite(sValue)) { return parseFloat(sValue); }
46568 if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
46572 function EmptyTree () { }
46573 EmptyTree.prototype.toString = function () { return 'null'; };
46574 EmptyTree.prototype.valueOf = function () { return null; };
46576 function objectify (vValue) {
46577 return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
46580 function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
46582 nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
46583 bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
46586 sProp, vContent, nLength = 0, sCollectedTxt = '',
46587 vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
46590 for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
46591 oNode = oParentNode.childNodes.item(nItem);
46592 if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
46593 else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
46594 else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
46598 var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
46600 if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
46602 for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
46603 sProp = aCache[nElId].nodeName.toLowerCase();
46604 vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
46605 if (vResult.hasOwnProperty(sProp)) {
46606 if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
46607 vResult[sProp].push(vContent);
46609 vResult[sProp] = vContent;
46616 nAttrLen = oParentNode.attributes.length,
46617 sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
46619 for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
46620 oAttrib = oParentNode.attributes.item(nAttrib);
46621 oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
46625 if (bFreeze) { Object.freeze(oAttrParent); }
46626 vResult[sAttributesProp] = oAttrParent;
46627 nLength -= nAttrLen - 1;
46631 if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
46632 vResult[sValueProp] = vBuiltVal;
46633 } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
46634 vResult = vBuiltVal;
46637 if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
46639 aCache.length = nLevelStart;
46644 function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
46645 var vValue, oChild;
46647 if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
46648 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
46649 } else if (oParentObj.constructor === Date) {
46650 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
46653 for (var sName in oParentObj) {
46654 vValue = oParentObj[sName];
46655 if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
46656 if (sName === sValueProp) {
46657 if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
46658 } else if (sName === sAttributesProp) { /* verbosity level is 3 */
46659 for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
46660 } else if (sName.charAt(0) === sAttrPref) {
46661 oParentEl.setAttribute(sName.slice(1), vValue);
46662 } else if (vValue.constructor === Array) {
46663 for (var nItem = 0; nItem < vValue.length; nItem++) {
46664 oChild = oXMLDoc.createElement(sName);
46665 loadObjTree(oXMLDoc, oChild, vValue[nItem]);
46666 oParentEl.appendChild(oChild);
46669 oChild = oXMLDoc.createElement(sName);
46670 if (vValue instanceof Object) {
46671 loadObjTree(oXMLDoc, oChild, vValue);
46672 } else if (vValue !== null && vValue !== true) {
46673 oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
46675 oParentEl.appendChild(oChild);
46680 this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
46681 var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
46682 return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);
46685 this.unbuild = function (oObjTree) {
46686 var oNewDoc = document.implementation.createDocument('', '', null);
46687 loadObjTree(oNewDoc, oNewDoc, oObjTree);
46691 this.stringify = function (oObjTree) {
46692 return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
46696 // var myObject = JXON.build(doc);
46697 // we got our javascript object! try: alert(JSON.stringify(myObject));
46699 // var newDoc = JXON.unbuild(myObject);
46700 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
46702 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
46703 var useHttps = window.location.protocol === 'https:';
46704 var protocol = useHttps ? 'https:' : 'http:';
46705 var urlroot = protocol + '//www.openstreetmap.org';
46706 var blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
46708 var loadedTiles = {};
46709 var tileZoom$1 = 16;
46710 var oauth = index$12({
46712 oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
46713 oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
46714 loading: authLoading,
46717 var rateLimitError;
46718 var userChangesets;
46723 function authLoading() {
46724 dispatch$3.call('authLoading');
46728 function authDone() {
46729 dispatch$3.call('authDone');
46733 function abortRequest$1(i) {
46740 function getLoc(attrs) {
46741 var lon = attrs.lon && attrs.lon.value,
46742 lat = attrs.lat && attrs.lat.value;
46743 return [parseFloat(lon), parseFloat(lat)];
46747 function getNodes(obj) {
46748 var elems = obj.getElementsByTagName('nd'),
46749 nodes = new Array(elems.length);
46750 for (var i = 0, l = elems.length; i < l; i++) {
46751 nodes[i] = 'n' + elems[i].attributes.ref.value;
46757 function getTags(obj) {
46758 var elems = obj.getElementsByTagName('tag'),
46760 for (var i = 0, l = elems.length; i < l; i++) {
46761 var attrs = elems[i].attributes;
46762 tags[attrs.k.value] = attrs.v.value;
46769 function getMembers(obj) {
46770 var elems = obj.getElementsByTagName('member'),
46771 members = new Array(elems.length);
46772 for (var i = 0, l = elems.length; i < l; i++) {
46773 var attrs = elems[i].attributes;
46775 id: attrs.type.value[0] + attrs.ref.value,
46776 type: attrs.type.value,
46777 role: attrs.role.value
46784 function getVisible(attrs) {
46785 return (!attrs.visible || attrs.visible.value !== 'false');
46790 node: function nodeData(obj) {
46791 var attrs = obj.attributes;
46792 return new osmNode({
46793 id: osmEntity$$1.id.fromOSM('node', attrs.id.value),
46794 loc: getLoc(attrs),
46795 version: attrs.version.value,
46796 user: attrs.user && attrs.user.value,
46797 tags: getTags(obj),
46798 visible: getVisible(attrs)
46802 way: function wayData(obj) {
46803 var attrs = obj.attributes;
46804 return new osmWay({
46805 id: osmEntity$$1.id.fromOSM('way', attrs.id.value),
46806 version: attrs.version.value,
46807 user: attrs.user && attrs.user.value,
46808 tags: getTags(obj),
46809 nodes: getNodes(obj),
46810 visible: getVisible(attrs)
46814 relation: function relationData(obj) {
46815 var attrs = obj.attributes;
46816 return new osmRelation({
46817 id: osmEntity$$1.id.fromOSM('relation', attrs.id.value),
46818 version: attrs.version.value,
46819 user: attrs.user && attrs.user.value,
46820 tags: getTags(obj),
46821 members: getMembers(obj),
46822 visible: getVisible(attrs)
46828 function parse(xml$$1) {
46829 if (!xml$$1 || !xml$$1.childNodes) return;
46831 var root = xml$$1.childNodes[0],
46832 children = root.childNodes,
46835 for (var i = 0, l = children.length; i < l; i++) {
46836 var child = children[i],
46837 parser = parsers[child.nodeName];
46839 entities.push(parser(child));
46850 utilRebind(this, dispatch$3, 'on');
46854 reset: function() {
46855 userChangesets = undefined;
46856 userDetails = undefined;
46857 rateLimitError = undefined;
46858 lodash.forEach(inflight, abortRequest$1);
46865 changesetURL: function(changesetId) {
46866 return urlroot + '/changeset/' + changesetId;
46870 changesetsURL: function(center, zoom$$1) {
46871 var precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2));
46872 return urlroot + '/history#map=' +
46873 Math.floor(zoom$$1) + '/' +
46874 center[1].toFixed(precision) + '/' +
46875 center[0].toFixed(precision);
46879 entityURL: function(entity) {
46880 return urlroot + '/' + entity.type + '/' + entity.osmId();
46884 userURL: function(username) {
46885 return urlroot + '/user/' + username;
46889 loadFromAPI: function(path$$1, callback) {
46892 function done(err, xml$$1) {
46893 var isAuthenticated = that.authenticated();
46895 // 400 Bad Request, 401 Unauthorized, 403 Forbidden
46896 // Logout and retry the request..
46897 if (isAuthenticated && err &&
46898 (err.status === 400 || err.status === 401 || err.status === 403)) {
46900 that.loadFromAPI(path$$1, callback);
46902 // else, no retry..
46904 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
46905 // Set the rateLimitError flag and trigger a warning..
46906 if (!isAuthenticated && !rateLimitError && err &&
46907 (err.status === 509 || err.status === 429)) {
46908 rateLimitError = err;
46909 dispatch$3.call('change');
46913 callback(err, parse(xml$$1));
46918 if (this.authenticated()) {
46919 return oauth.xhr({ method: 'GET', path: path$$1 }, done);
46921 var url = urlroot + path$$1;
46922 return xml(url).get(done);
46927 loadEntity: function(id, callback) {
46928 var type = osmEntity$$1.id.type(id),
46929 osmID = osmEntity$$1.id.toOSM(id);
46932 '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
46933 function(err, entities) {
46934 if (callback) callback(err, { data: entities });
46940 loadEntityVersion: function(id, version$$1, callback) {
46941 var type = osmEntity$$1.id.type(id),
46942 osmID = osmEntity$$1.id.toOSM(id);
46945 '/api/0.6/' + type + '/' + osmID + '/' + version$$1,
46946 function(err, entities) {
46947 if (callback) callback(err, { data: entities });
46953 loadMultiple: function(ids, callback) {
46955 lodash.each(lodash.groupBy(lodash.uniq(ids), osmEntity$$1.id.type), function(v, k) {
46956 var type = k + 's',
46957 osmIDs = lodash.map(v, osmEntity$$1.id.toOSM);
46959 lodash.each(lodash.chunk(osmIDs, 150), function(arr) {
46961 '/api/0.6/' + type + '?' + type + '=' + arr.join(),
46962 function(err, entities) {
46963 if (callback) callback(err, { data: entities });
46971 authenticated: function() {
46972 return oauth.authenticated();
46976 // Generate Changeset XML. Returns a string.
46977 changesetJXON: function(tags) {
46981 tag: lodash.map(tags, function(value, key) {
46982 return { '@k': key, '@v': value };
46992 // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
46993 // XML. Returns a string.
46994 osmChangeJXON: function(changeset_id, changes) {
46995 function nest$$1(x, order) {
46997 for (var i = 0; i < x.length; i++) {
46998 var tagName = Object.keys(x[i])[0];
46999 if (!groups[tagName]) groups[tagName] = [];
47000 groups[tagName].push(x[i][tagName]);
47003 order.forEach(function(o) {
47004 if (groups[o]) ordered[o] = groups[o];
47009 function rep(entity) {
47010 return entity.asJXON(changeset_id);
47016 '@generator': 'iD',
47017 'create': nest$$1(changes.created.map(rep), ['node', 'way', 'relation']),
47018 'modify': nest$$1(changes.modified.map(rep), ['node', 'way', 'relation']),
47019 'delete': lodash.extend(nest$$1(changes.deleted.map(rep), ['relation', 'way', 'node']), {'@if-unused': true})
47025 changesetTags: function(version$$1, comment, imageryUsed) {
47026 var detected = utilDetect(),
47028 created_by: ('iD ' + version$$1).substr(0, 255),
47029 imagery_used: imageryUsed.join(';').substr(0, 255),
47030 host: detected.host.substr(0, 255),
47031 locale: detected.locale.substr(0, 255)
47035 tags.comment = comment.substr(0, 255);
47042 putChangeset: function(changes, version$$1, comment, imageryUsed, callback) {
47046 path: '/api/0.6/changeset/create',
47047 options: { header: { 'Content-Type': 'text/xml' } },
47048 content: JXON.stringify(that.changesetJXON(that.changesetTags(version$$1, comment, imageryUsed)))
47049 }, function(err, changeset_id) {
47050 if (err) return callback(err);
47053 path: '/api/0.6/changeset/' + changeset_id + '/upload',
47054 options: { header: { 'Content-Type': 'text/xml' } },
47055 content: JXON.stringify(that.osmChangeJXON(changeset_id, changes))
47057 if (err) return callback(err);
47058 // POST was successful, safe to call the callback.
47059 // Still attempt to close changeset, but ignore response because #2667
47060 // Add delay to allow for postgres replication #1646 #2678
47061 window.setTimeout(function() { callback(null, changeset_id); }, 2500);
47064 path: '/api/0.6/changeset/' + changeset_id + '/close',
47065 options: { header: { 'Content-Type': 'text/xml' } }
47066 }, function() { return true; });
47072 userDetails: function(callback) {
47074 callback(undefined, userDetails);
47078 function done(err, user_details) {
47079 if (err) return callback(err);
47081 var u = user_details.getElementsByTagName('user')[0],
47082 img = u.getElementsByTagName('img'),
47085 if (img && img[0] && img[0].getAttribute('href')) {
47086 image_url = img[0].getAttribute('href');
47090 display_name: u.attributes.display_name.value,
47091 image_url: image_url,
47092 id: u.attributes.id.value
47095 callback(undefined, userDetails);
47098 oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
47102 userChangesets: function(callback) {
47103 if (userChangesets) {
47104 callback(undefined, userChangesets);
47108 this.userDetails(function(err, user) {
47114 function done(err, changesets) {
47118 userChangesets = Array.prototype.map.call(
47119 changesets.getElementsByTagName('changeset'),
47120 function (changeset) {
47121 return { tags: getTags(changeset) };
47124 callback(undefined, userChangesets);
47128 oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
47133 status: function(callback) {
47134 function done(xml$$1) {
47135 // update blacklists
47136 var elements = xml$$1.getElementsByTagName('blacklist'),
47138 for (var i = 0; i < elements.length; i++) {
47139 var regex = elements[i].getAttribute('regex'); // needs unencode?
47141 regexes.push(regex);
47144 if (regexes.length) {
47145 blacklists = regexes;
47149 if (rateLimitError) {
47150 callback(rateLimitError, 'rateLimited');
47152 var apiStatus = xml$$1.getElementsByTagName('status'),
47153 val = apiStatus[0].getAttribute('api');
47155 callback(undefined, val);
47159 xml(urlroot + '/api/capabilities').get()
47161 .on('error', callback);
47165 imageryBlacklists: function() {
47170 tileZoom: function(_) {
47171 if (!arguments.length) return tileZoom$1;
47177 loadTiles: function(projection, dimensions, callback) {
47181 s = projection.scale() * 2 * Math.PI,
47182 z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
47183 ts = 256 * Math.pow(2, z - tileZoom$1),
47185 s / 2 - projection.translate()[0],
47186 s / 2 - projection.translate()[1]
47189 var tiles = d3geoTile()
47190 .scaleExtent([tileZoom$1, tileZoom$1])
47193 .translate(projection.translate())()
47194 .map(function(tile) {
47195 var x = tile[0] * ts - origin[0],
47196 y = tile[1] * ts - origin[1];
47199 id: tile.toString(),
47200 extent: geoExtent$$1(
47201 projection.invert([x, y + ts]),
47202 projection.invert([x + ts, y]))
47206 lodash.filter(inflight, function(v, i) {
47207 var wanted = lodash.find(tiles, function(tile) {
47208 return i === tile.id;
47210 if (!wanted) delete inflight[i];
47212 }).map(abortRequest$1);
47214 tiles.forEach(function(tile) {
47217 if (loadedTiles[id] || inflight[id]) return;
47219 if (lodash.isEmpty(inflight)) {
47220 dispatch$3.call('loading');
47223 inflight[id] = that.loadFromAPI(
47224 '/api/0.6/map?bbox=' + tile.extent.toParam(),
47225 function(err, parsed) {
47226 delete inflight[id];
47228 loadedTiles[id] = true;
47232 callback(err, lodash.extend({ data: parsed }, tile));
47235 if (lodash.isEmpty(inflight)) {
47236 dispatch$3.call('loaded');
47244 switch: function(options) {
47245 urlroot = options.urlroot;
47247 oauth.options(lodash.extend({
47249 loading: authLoading,
47253 dispatch$3.call('change');
47255 this.userChangesets(function() {}); // eagerly load user details/changesets
47260 toggle: function(_) {
47266 loadedTiles: function(_) {
47267 if (!arguments.length) return loadedTiles;
47273 logout: function() {
47274 userChangesets = undefined;
47275 userDetails = undefined;
47277 dispatch$3.call('change');
47282 authenticate: function(callback) {
47284 userChangesets = undefined;
47285 userDetails = undefined;
47287 function done(err, res) {
47288 rateLimitError = undefined;
47289 dispatch$3.call('change');
47290 if (callback) callback(err, res);
47291 that.userChangesets(function() {}); // eagerly load user details/changesets
47294 return oauth.authenticate(done);
47298 var endpoint = 'https://taginfo.openstreetmap.org/api/4/';
47299 var taginfoCache = {};
47301 point: 'count_nodes',
47302 vertex: 'count_nodes',
47303 area: 'count_ways',
47306 var tag_sort_members = {
47307 point: 'count_node_members',
47308 vertex: 'count_node_members',
47309 area: 'count_way_members',
47310 line: 'count_way_members',
47311 relation: 'count_relation_members'
47313 var tag_filters = {
47319 var tag_members_fractions = {
47320 point: 'count_node_members_fraction',
47321 vertex: 'count_node_members_fraction',
47322 area: 'count_way_members_fraction',
47323 line: 'count_way_members_fraction',
47324 relation: 'count_relation_members_fraction'
47328 function sets(parameters, n, o) {
47329 if (parameters.geometry && o[parameters.geometry]) {
47330 parameters[n] = o[parameters.geometry];
47336 function setFilter(parameters) {
47337 return sets(parameters, 'filter', tag_filters);
47341 function setSort(parameters) {
47342 return sets(parameters, 'sortname', tag_sorts);
47346 function setSortMembers(parameters) {
47347 return sets(parameters, 'sortname', tag_sort_members);
47351 function clean(parameters) {
47352 return lodash.omit(parameters, 'geometry', 'debounce');
47356 function filterKeys(type) {
47357 var count_type = type ? 'count_' + type : 'count_all';
47358 return function(d) {
47359 return parseFloat(d[count_type]) > 2500 || d.in_wiki;
47364 function filterMultikeys(prefix) {
47365 return function(d) {
47366 // d.key begins with prefix, and d.key contains no additional ':'s
47367 var re = new RegExp('^' + prefix + '(.*)$');
47368 var matches = d.key.match(re) || [];
47369 return (matches.length === 2 && matches[1].indexOf(':') === -1);
47374 function filterValues(allowUpperCase) {
47375 return function(d) {
47376 if (d.value.match(/[;,]/) !== null) return false; // exclude some punctuation
47377 if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false; // exclude uppercase letters
47378 return parseFloat(d.fraction) > 0.0 || d.in_wiki;
47383 function filterRoles(geometry) {
47384 return function(d) {
47385 if (d.role === '') return false; // exclude empty role
47386 if (d.role.match(/[A-Z*;,]/) !== null) return false; // exclude uppercase letters and some punctuation
47387 return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
47392 function valKey(d) {
47400 function valKeyDescription(d) {
47403 title: d.description || d.value
47408 function roleKey(d) {
47416 // sort keys with ':' lower than keys without ':'
47417 function sortKeys(a, b) {
47418 return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
47419 : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
47424 var debounced = lodash.debounce(json, 100, true);
47427 function request$1(url, debounce, callback) {
47428 if (taginfoCache[url]) {
47429 callback(null, taginfoCache[url]);
47430 } else if (debounce) {
47431 debounced(url, done);
47436 function done(err, data) {
47438 taginfoCache[url] = data;
47440 callback(err, data);
47445 var serviceTaginfo = {
47447 init: function() { taginfoCache = {}; },
47448 reset: function() { taginfoCache = {}; },
47451 keys: function(parameters, callback) {
47452 var debounce = parameters.debounce;
47453 parameters = clean(setSort(parameters));
47454 request$1(endpoint + 'keys/all?' +
47455 utilQsString(lodash.extend({
47457 sortname: 'count_all',
47460 }, parameters)), debounce, function(err, d) {
47464 var f = filterKeys(parameters.filter);
47465 callback(null, d.data.filter(f).sort(sortKeys).map(valKey));
47472 multikeys: function(parameters, callback) {
47473 var debounce = parameters.debounce;
47474 parameters = clean(setSort(parameters));
47475 var prefix = parameters.query;
47476 request$1(endpoint + 'keys/all?' +
47477 utilQsString(lodash.extend({
47479 sortname: 'count_all',
47482 }, parameters)), debounce, function(err, d) {
47486 var f = filterMultikeys(prefix);
47487 callback(null, d.data.filter(f).map(valKey));
47494 values: function(parameters, callback) {
47495 var debounce = parameters.debounce;
47496 parameters = clean(setSort(setFilter(parameters)));
47497 request$1(endpoint + 'key/values?' +
47498 utilQsString(lodash.extend({
47500 sortname: 'count_all',
47503 }, parameters)), debounce, function(err, d) {
47507 // In most cases we prefer taginfo value results with lowercase letters.
47508 // A few OSM keys expect values to contain uppercase values (see #3377).
47509 // This is not an exhaustive list (e.g. `name` also has uppercase values)
47510 // but these are the fields where taginfo value lookup is most useful.
47511 var re = /network|taxon|genus|species/;
47512 var allowUpperCase = (parameters.key.match(re) !== null);
47513 var f = filterValues(allowUpperCase);
47514 callback(null, d.data.filter(f).map(valKeyDescription));
47521 roles: function(parameters, callback) {
47522 var debounce = parameters.debounce;
47523 var geometry = parameters.geometry;
47524 parameters = clean(setSortMembers(parameters));
47525 request$1(endpoint + 'relation/roles?' +
47526 utilQsString(lodash.extend({
47528 sortname: 'count_all_members',
47531 }, parameters)), debounce, function(err, d) {
47535 var f = filterRoles(geometry);
47536 callback(null, d.data.filter(f).map(roleKey));
47543 docs: function(parameters, callback) {
47544 var debounce = parameters.debounce;
47545 parameters = clean(setSort(parameters));
47547 var path$$1 = 'key/wiki_pages?';
47548 if (parameters.value) path$$1 = 'tag/wiki_pages?';
47549 else if (parameters.rtype) path$$1 = 'relation/wiki_pages?';
47551 request$1(endpoint + path$$1 + utilQsString(parameters), debounce, function(err, d) {
47555 callback(null, d.data);
47561 endpoint: function(_) {
47562 if (!arguments.length) return endpoint;
47569 var jsonpCache = {};
47570 window.jsonpCache = jsonpCache;
47572 function jsonpRequest(url, callback) {
47574 if (window.JSONP_FIX) {
47575 if (window.JSONP_DELAY === 0) {
47576 callback(window.JSONP_FIX);
47578 setTimeout(function() {
47579 callback(window.JSONP_FIX);
47580 }, window.JSONP_DELAY || 0);
47586 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
47588 while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
47592 function create(url) {
47593 var e = url.match(/callback=(\w+)/),
47594 c = e ? e[1] : rand();
47595 jsonpCache[c] = function(data) {
47597 delete jsonpCache[c];
47600 return 'jsonpCache.' + c;
47603 var cb = create(url),
47604 script = select('head')
47606 .attr('type', 'text/javascript')
47607 .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
47610 var endpoint$1 = 'https://www.wikidata.org/w/api.php?';
47612 var serviceWikidata = {
47614 init: function() {},
47615 reset: function() {},
47618 // Given a Wikipedia language and article title, return an array of
47619 // corresponding Wikidata entities.
47620 itemsByTitle: function(lang, title, callback) {
47626 lang = lang || 'en';
47627 jsonpRequest(endpoint$1 + utilQsString({
47628 action: 'wbgetentities',
47630 sites: lang.replace(/-/g, '_') + 'wiki',
47632 languages: 'en', // shrink response by filtering to one language
47633 callback: '{callback}'
47634 }), function(data) {
47635 if (!data || data.error) {
47638 callback(title, data.entities || {});
47645 var endpoint$2 = 'https://en.wikipedia.org/w/api.php?';
47647 var serviceWikipedia = {
47649 init: function() {},
47650 reset: function() {},
47653 search: function(lang, query, callback) {
47659 lang = lang || 'en';
47660 jsonpRequest(endpoint$2.replace('en', lang) +
47665 srinfo: 'suggestion',
47667 callback: '{callback}',
47669 }), function(data) {
47670 if (!data || !data.query || !data.query.search || data.error) {
47673 var results = data.query.search.map(function(d) { return d.title; });
47674 callback(query, results);
47681 suggestions: function(lang, query, callback) {
47687 lang = lang || 'en';
47688 jsonpRequest(endpoint$2.replace('en', lang) +
47690 action: 'opensearch',
47694 callback: '{callback}',
47696 }), function(data) {
47697 if (!data || data.error) {
47700 callback(data[0], data[1] || []);
47707 translations: function(lang, title, callback) {
47713 jsonpRequest(endpoint$2.replace('en', lang) +
47718 callback: '{callback}',
47721 }), function(data) {
47722 if (!data || !data.query || !data.query.pages || data.error) {
47725 var list = data.query.pages[Object.keys(data.query.pages)[0]],
47727 if (list && list.langlinks) {
47728 list.langlinks.forEach(function(d) {
47729 translations[d.lang] = d['*'];
47732 callback(translations);
47741 mapillary: serviceMapillary,
47742 geocoder: serviceNominatim,
47744 taginfo: serviceTaginfo,
47745 wikidata: serviceWikidata,
47746 wikipedia: serviceWikipedia
47749 function svgMapillaryImages(projection, context, dispatch$$1) {
47750 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47752 minViewfieldZoom = 17,
47753 layer = select(null),
47758 if (svgMapillaryImages.initialized) return; // run once
47759 svgMapillaryImages.enabled = false;
47760 svgMapillaryImages.initialized = true;
47764 function getMapillary() {
47765 if (services.mapillary && !_mapillary) {
47766 _mapillary = services.mapillary;
47767 _mapillary.event.on('loadedImages', throttledRedraw);
47768 } else if (!services.mapillary && _mapillary) {
47776 function showLayer() {
47777 var mapillary = getMapillary();
47778 if (!mapillary) return;
47780 mapillary.loadViewer(context);
47784 .style('opacity', 0)
47787 .style('opacity', 1)
47788 .on('end', function () { dispatch$$1.call('change'); });
47792 function hideLayer() {
47793 var mapillary = getMapillary();
47795 mapillary.hideViewer();
47798 throttledRedraw.cancel();
47803 .style('opacity', 0)
47804 .on('end', editOff);
47808 function editOn() {
47809 layer.style('display', 'block');
47813 function editOff() {
47814 layer.selectAll('.viewfield-group').remove();
47815 layer.style('display', 'none');
47819 function click(d) {
47820 var mapillary = getMapillary();
47821 if (!mapillary) return;
47823 context.map().centerEase(d.loc);
47826 .selectedImage(d.key, true)
47827 .updateViewer(d.key, context)
47832 function transform(d) {
47833 var t = svgPointTransform(projection)(d);
47834 if (d.ca) t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
47839 function update() {
47840 var mapillary = getMapillary(),
47841 data = (mapillary ? mapillary.images(projection) : []),
47842 imageKey = mapillary ? mapillary.selectedImage() : null;
47844 var markers = layer.selectAll('.viewfield-group')
47845 .data(data, function(d) { return d.key; });
47850 var enter = markers.enter()
47852 .attr('class', 'viewfield-group')
47853 .classed('selected', function(d) { return d.key === imageKey; })
47854 .on('click', click);
47858 .attr('transform', transform);
47861 var viewfields = markers.selectAll('.viewfield')
47862 .data(~~context.map().zoom() >= minViewfieldZoom ? [0] : []);
47869 .attr('class', 'viewfield')
47870 .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
47871 .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');
47873 markers.selectAll('circle')
47883 function drawImages(selection$$1) {
47884 var enabled = svgMapillaryImages.enabled,
47885 mapillary = getMapillary();
47887 layer = selection$$1.selectAll('.layer-mapillary-images')
47888 .data(mapillary ? [0] : []);
47893 layer = layer.enter()
47895 .attr('class', 'layer-mapillary-images')
47896 .style('display', enabled ? 'block' : 'none')
47900 if (mapillary && ~~context.map().zoom() >= minZoom) {
47903 mapillary.loadImages(projection);
47911 drawImages.enabled = function(_) {
47912 if (!arguments.length) return svgMapillaryImages.enabled;
47913 svgMapillaryImages.enabled = _;
47914 if (svgMapillaryImages.enabled) {
47919 dispatch$$1.call('change');
47924 drawImages.supported = function() {
47925 return !!getMapillary();
47933 function svgMapillarySigns(projection, context, dispatch$$1) {
47934 var throttledRedraw = lodash.throttle(function () { dispatch$$1.call('change'); }, 1000),
47936 layer = select(null),
47941 if (svgMapillarySigns.initialized) return; // run once
47942 svgMapillarySigns.enabled = false;
47943 svgMapillarySigns.initialized = true;
47947 function getMapillary() {
47948 if (services.mapillary && !_mapillary) {
47949 _mapillary = services.mapillary;
47950 _mapillary.event.on('loadedSigns', throttledRedraw);
47951 } else if (!services.mapillary && _mapillary) {
47958 function showLayer() {
47963 function hideLayer() {
47964 throttledRedraw.cancel();
47969 function editOn() {
47970 layer.style('display', 'block');
47974 function editOff() {
47975 layer.selectAll('.icon-sign').remove();
47976 layer.style('display', 'none');
47980 function click(d) {
47981 var mapillary = getMapillary();
47982 if (!mapillary) return;
47984 context.map().centerEase(d.loc);
47987 .selectedImage(d.key, true)
47988 .updateViewer(d.key, context)
47993 function update() {
47994 var mapillary = getMapillary(),
47995 data = (mapillary ? mapillary.signs(projection) : []),
47996 imageKey = mapillary ? mapillary.selectedImage() : null;
47998 var signs = layer.selectAll('.icon-sign')
47999 .data(data, function(d) { return d.key; });
48004 var enter = signs.enter()
48005 .append('foreignObject')
48006 .attr('class', 'icon-sign')
48007 .attr('width', '32px') // for Firefox
48008 .attr('height', '32px') // for Firefox
48009 .classed('selected', function(d) { return d.key === imageKey; })
48010 .on('click', click);
48013 .append('xhtml:body')
48014 .attr('class', 'icon-sign-body')
48015 .html(mapillary.signHTML);
48019 .attr('x', function(d) { return projection(d.loc)[0] - 16; }) // offset by -16px to
48020 .attr('y', function(d) { return projection(d.loc)[1] - 16; }); // center signs on loc
48024 function drawSigns(selection$$1) {
48025 var enabled = svgMapillarySigns.enabled,
48026 mapillary = getMapillary();
48028 layer = selection$$1.selectAll('.layer-mapillary-signs')
48029 .data(mapillary ? [0] : []);
48034 layer = layer.enter()
48036 .attr('class', 'layer-mapillary-signs')
48037 .style('display', enabled ? 'block' : 'none')
48041 if (mapillary && ~~context.map().zoom() >= minZoom) {
48044 mapillary.loadSigns(context, projection);
48052 drawSigns.enabled = function(_) {
48053 if (!arguments.length) return svgMapillarySigns.enabled;
48054 svgMapillarySigns.enabled = _;
48055 if (svgMapillarySigns.enabled) {
48060 dispatch$$1.call('change');
48065 drawSigns.supported = function() {
48066 var mapillary = getMapillary();
48067 return (mapillary && mapillary.signsSupported());
48075 function svgOsm() {
48076 return function drawOsm(selection) {
48077 var layers = selection.selectAll('.layer-osm')
48078 .data(['areas', 'lines', 'hit', 'halo', 'label']);
48082 .attr('class', function(d) { return 'layer-osm layer-' + d; });
48086 function svgLayers(projection, context) {
48087 var dispatch$$1 = dispatch('change'),
48088 svg = select(null),
48090 { id: 'osm', layer: svgOsm(projection, context, dispatch$$1) },
48091 { id: 'gpx', layer: svgGpx(projection, context, dispatch$$1) },
48092 { id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch$$1) },
48093 { id: 'mapillary-signs', layer: svgMapillarySigns(projection, context, dispatch$$1) },
48094 { id: 'debug', layer: svgDebug(projection, context, dispatch$$1) }
48098 function drawLayers(selection$$1) {
48099 svg = selection$$1.selectAll('.surface')
48104 .attr('class', 'surface')
48107 var defs = svg.selectAll('.surface-defs')
48112 .attr('class', 'surface-defs');
48114 var groups = svg.selectAll('.data-layer')
48122 .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
48124 .each(function(d) { select(this).call(d.layer); });
48128 drawLayers.all = function() {
48133 drawLayers.layer = function(id) {
48134 var obj = lodash.find(layers, function(o) {return o.id === id;});
48135 return obj && obj.layer;
48139 drawLayers.only = function(what) {
48140 var arr = [].concat(what);
48141 drawLayers.remove(lodash.difference(lodash.map(layers, 'id'), arr));
48146 drawLayers.remove = function(what) {
48147 var arr = [].concat(what);
48148 arr.forEach(function(id) {
48149 layers = lodash.reject(layers, function(o) {return o.id === id;});
48151 dispatch$$1.call('change');
48156 drawLayers.add = function(what) {
48157 var arr = [].concat(what);
48158 arr.forEach(function(obj) {
48159 if ('id' in obj && 'layer' in obj) {
48163 dispatch$$1.call('change');
48168 drawLayers.dimensions = function(_) {
48169 if (!arguments.length) return utilGetDimensions(svg);
48170 utilSetDimensions(svg, _);
48175 return utilRebind(drawLayers, dispatch$$1, 'on');
48178 function svgLines$$1(projection) {
48179 var detected = utilDetect();
48181 var highway_stack = {
48196 function waystack(a, b) {
48197 var as = 0, bs = 0;
48198 if (a.tags.highway) { as -= highway_stack[a.tags.highway]; }
48199 if (b.tags.highway) { bs -= highway_stack[b.tags.highway]; }
48204 return function drawLines(selection$$1, graph, entities, filter) {
48205 var ways = [], pathdata = {}, onewaydata = {},
48206 getPath = svgPath(projection, graph);
48208 for (var i = 0; i < entities.length; i++) {
48209 var entity = entities[i],
48210 outer = osmSimpleMultipolygonOuterMember(entity, graph);
48212 ways.push(entity.mergeTags(outer.tags));
48213 } else if (entity.geometry(graph) === 'line') {
48218 ways = ways.filter(getPath);
48220 pathdata = lodash.groupBy(ways, function(way) { return way.layer(); });
48222 lodash.forOwn(pathdata, function(v, k) {
48223 onewaydata[k] = lodash(v)
48224 .filter(function(d) { return d.isOneWay(); })
48225 .map(svgOneWaySegments(projection, graph, 35))
48230 var layer = selection$$1.selectAll('.layer-lines');
48232 var layergroup = layer
48233 .selectAll('g.layergroup')
48234 .data(sequence(-10, 11));
48236 layergroup = layergroup.enter()
48238 .attr('class', function(d) { return 'layergroup layer' + String(d); })
48239 .merge(layergroup);
48242 var linegroup = layergroup
48243 .selectAll('g.linegroup')
48244 .data(['shadow', 'casing', 'stroke']);
48246 linegroup = linegroup.enter()
48248 .attr('class', function(d) { return 'linegroup line-' + d; })
48252 var lines = linegroup
48256 function() { return pathdata[this.parentNode.__data__] || []; },
48263 // Optimization: call simple TagClasses only on enter selection. This
48264 // works because osmEntity.key is defined to include the entity v attribute.
48267 .attr('class', function(d) { return 'way line ' + this.parentNode.__data__ + ' ' + d.id; })
48268 .call(svgTagClasses())
48271 .attr('d', getPath)
48272 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
48275 var onewaygroup = layergroup
48276 .selectAll('g.onewaygroup')
48279 onewaygroup = onewaygroup.enter()
48281 .attr('class', 'onewaygroup')
48282 .merge(onewaygroup);
48285 var oneways = onewaygroup
48289 function() { return onewaydata[this.parentNode.__data__] || []; },
48290 function(d) { return [d.id, d.index]; }
48296 oneways = oneways.enter()
48298 .attr('class', 'oneway')
48299 .attr('marker-mid', 'url(#oneway-marker)')
48301 .attr('d', function(d) { return d.d; });
48304 oneways.each(function() { this.parentNode.insertBefore(this, this); });
48309 function svgMidpoints$$1(projection, context) {
48311 return function drawMidpoints(selection, graph, entities, filter, extent) {
48312 var poly = extent.polygon(),
48315 for (var i = 0; i < entities.length; i++) {
48316 var entity = entities[i];
48318 if (entity.type !== 'way')
48320 if (!filter(entity))
48322 if (context.selectedIDs().indexOf(entity.id) < 0)
48325 var nodes = graph.childNodes(entity);
48326 for (var j = 0; j < nodes.length - 1; j++) {
48330 id = [a.id, b.id].sort().join('-');
48332 if (midpoints[id]) {
48333 midpoints[id].parents.push(entity);
48335 if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
48336 var point = geoInterp(a.loc, b.loc, 0.5),
48339 if (extent.intersects(point)) {
48342 for (var k = 0; k < 4; k++) {
48343 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
48345 geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
48346 geoEuclideanDistance(projection(b.loc), projection(point)) > 20)
48359 edge: [a.id, b.id],
48369 function midpointFilter(d) {
48370 if (midpoints[d.id])
48373 for (var i = 0; i < d.parents.length; i++) {
48374 if (filter(d.parents[i])) {
48383 var layer = selection.selectAll('.layer-hit');
48386 .selectAll('g.midpoint')
48387 .filter(midpointFilter)
48388 .data(lodash.values(midpoints), function(d) { return d.id; });
48393 var enter = groups.enter()
48394 .insert('g', ':first-child')
48395 .attr('class', 'midpoint');
48397 enter.append('polygon')
48398 .attr('points', '-6,8 10,0 -6,-8')
48399 .attr('class', 'shadow');
48401 enter.append('polygon')
48402 .attr('points', '-3,4 5,0 -3,-4')
48403 .attr('class', 'fill');
48407 .attr('transform', function(d) {
48408 var translate = svgPointTransform(projection),
48409 a = graph.entity(d.edge[0]),
48410 b = graph.entity(d.edge[1]),
48411 angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
48412 return translate(d) + ' rotate(' + angleVal + ')';
48414 .call(svgTagClasses().tags(
48415 function(d) { return d.parents[0].tags; }
48418 // Propagate data bindings.
48419 groups.select('polygon.shadow');
48420 groups.select('polygon.fill');
48425 function svgOneWaySegments(projection, graph, dt) {
48426 return function(entity) {
48432 clip = identity$5().clipExtent(projection.clipExtent()).stream,
48433 coordinates = graph.childNodes(entity).map(function(n) {
48437 if (entity.tags.oneway === '-1') coordinates.reverse();
48440 type: 'LineString',
48441 coordinates: coordinates
48442 }, projection.stream(clip({
48443 lineStart: function() {},
48444 lineEnd: function() {
48447 point: function(x, y) {
48451 var span = geoEuclideanDistance(a, b) - offset;
48454 var angle = Math.atan2(b[1] - a[1], b[0] - a[0]),
48455 dx = dt * Math.cos(angle),
48456 dy = dt * Math.sin(angle),
48457 p = [a[0] + offset * Math.cos(angle),
48458 a[1] + offset * Math.sin(angle)];
48460 var segment = 'M' + a[0] + ',' + a[1] +
48461 'L' + p[0] + ',' + p[1];
48463 for (span -= dt; span >= 0; span -= dt) {
48466 segment += 'L' + p[0] + ',' + p[1];
48469 segment += 'L' + b[0] + ',' + b[1];
48470 segments.push({id: entity.id, index: i, d: segment});
48485 function svgPath(projection, graph, isArea) {
48487 // Explanation of magic numbers:
48488 // "padding" here allows space for strokes to extend beyond the viewport,
48489 // so that the stroke isn't drawn along the edge of the viewport when
48490 // the shape is clipped.
48492 // When drawing lines, pad viewport by 5px.
48493 // When drawing areas, pad viewport by 65px in each direction to allow
48494 // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
48497 padding = isArea ? 65 : 5,
48498 viewport = projection.clipExtent(),
48500 [viewport[0][0] - padding, viewport[0][1] - padding],
48501 [viewport[1][0] + padding, viewport[1][1] + padding]
48503 clip = identity$5().clipExtent(paddedExtent).stream,
48504 project = projection.stream,
48505 path$$1 = index$4()
48506 .projection({stream: function(output) { return project(clip(output)); }});
48508 return function(entity) {
48509 if (entity.id in cache) {
48510 return cache[entity.id];
48512 return cache[entity.id] = path$$1(entity.asGeoJSON(graph));
48517 function svgPoints$$1(projection, context) {
48519 function markerPath(selection, klass) {
48521 .attr('class', klass)
48522 .attr('transform', 'translate(-8, -23)')
48523 .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');
48526 function sortY(a, b) {
48527 return b.loc[1] - a.loc[1];
48531 return function drawPoints(selection, graph, entities, filter) {
48532 var wireframe = context.surface().classed('fill-wireframe'),
48533 points = wireframe ? [] : lodash.filter(entities, function(e) {
48534 return e.geometry(graph) === 'point';
48537 points.sort(sortY);
48539 var layer = selection.selectAll('.layer-hit');
48541 var groups = layer.selectAll('g.point')
48543 .data(points, osmEntity$$1.key);
48548 var enter = groups.enter()
48550 .attr('class', function(d) { return 'node point ' + d.id; })
48553 enter.append('path')
48554 .call(markerPath, 'shadow');
48556 enter.append('path')
48557 .call(markerPath, 'stroke');
48559 enter.append('use')
48560 .attr('transform', 'translate(-5, -19)')
48561 .attr('class', 'icon')
48562 .attr('width', '11px')
48563 .attr('height', '11px');
48567 .attr('transform', svgPointTransform(projection))
48568 .call(svgTagClasses());
48570 // Selecting the following implicitly
48571 // sets the data (point entity) on the element
48572 groups.select('.shadow');
48573 groups.select('.stroke');
48574 groups.select('.icon')
48575 .attr('xlink:href', function(entity) {
48576 var preset = context.presets().match(entity, graph);
48577 return (preset && preset.icon) ? '#' + preset.icon + '-11' : '';
48582 function svgRelationMemberTags(graph) {
48583 return function(entity) {
48584 var tags = entity.tags;
48585 graph.parentRelations(entity).forEach(function(relation) {
48586 var type = relation.tags.type;
48587 if (type === 'multipolygon' || type === 'boundary') {
48588 tags = lodash.extend({}, relation.tags, tags);
48595 function svgTagClasses() {
48597 'building', 'highway', 'railway', 'waterway', 'aeroway',
48598 'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
48599 'leisure', 'military', 'place'
48602 'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
48603 'razed', 'demolished', 'obliterated'
48606 'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
48607 'surface', 'tracktype', 'crossing'
48609 tagClassRe = /^tag-/,
48610 tags = function(entity) { return entity.tags; };
48613 var tagClasses = function(selection$$1) {
48614 selection$$1.each(function tagClassesEach(entity) {
48615 var value = this.className,
48616 classes, primary, status;
48618 if (value.baseVal !== undefined) value = value.baseVal;
48620 classes = value.trim().split(/\s+/).filter(function(name) {
48621 return name.length && !tagClassRe.test(name);
48624 var t = tags(entity), i, k, v;
48626 // pick at most one primary classification tag..
48627 for (i = 0; i < primaries.length; i++) {
48630 if (!v || v === 'no') continue;
48633 if (statuses.indexOf(v) !== -1) { // e.g. `railway=abandoned`
48635 classes += ' tag-' + k;
48637 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48643 // add at most one status tag, only if relates to primary tag..
48645 for (i = 0; i < statuses.length; i++) {
48648 if (!v || v === 'no') continue;
48650 if (v === 'yes') { // e.g. `railway=rail + abandoned=yes`
48653 else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
48655 } else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway`
48658 classes += ' tag-' + v;
48659 } // else ignore e.g. `highway=path + abandoned=railway`
48666 classes += ' tag-status tag-status-' + status;
48669 // add any secondary (structure) tags
48670 for (i = 0; i < secondaries.length; i++) {
48671 k = secondaries[i];
48673 if (!v || v === 'no') continue;
48674 classes += ' tag-' + k + ' tag-' + k + '-' + v;
48677 // For highways, look for surface tagging..
48678 if (primary === 'highway') {
48679 var paved = (t.highway !== 'track');
48682 if (k in osmPavedTags) {
48683 paved = !!osmPavedTags[k][v];
48688 classes += ' tag-unpaved';
48692 classes = classes.trim();
48694 if (classes !== value) {
48695 select(this).attr('class', classes);
48701 tagClasses.tags = function(_) {
48702 if (!arguments.length) return tags;
48710 function svgTurns(projection) {
48712 return function drawTurns(selection, graph, turns) {
48714 function key(turn) {
48715 return [turn.from.node + turn.via.node + turn.to.node].join('-');
48718 function icon(turn) {
48719 var u = turn.u ? '-u' : '';
48720 if (!turn.restriction)
48721 return '#turn-yes' + u;
48722 var restriction = graph.entity(turn.restriction).tags.restriction;
48724 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
48727 var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
48734 var enter = groups.enter()
48736 .attr('class', 'turn');
48739 .filter(function (turn) { return !turn.u; });
48741 nEnter.append('rect')
48742 .attr('transform', 'translate(-22, -12)')
48743 .attr('width', '44')
48744 .attr('height', '24');
48746 nEnter.append('use')
48747 .attr('transform', 'translate(-22, -12)')
48748 .attr('width', '44')
48749 .attr('height', '24');
48753 .filter(function (turn) { return turn.u; });
48755 uEnter.append('circle')
48758 uEnter.append('use')
48759 .attr('transform', 'translate(-16, -16)')
48760 .attr('width', '32')
48761 .attr('height', '32');
48768 .attr('transform', function (turn) {
48769 var v = graph.entity(turn.via.node),
48770 t = graph.entity(turn.to.node),
48771 a = geoAngle(v, t, projection),
48772 p = projection(v.loc),
48773 r = turn.u ? 0 : 60;
48775 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
48776 'rotate(' + a * 180 / Math.PI + ')';
48779 groups.select('use')
48780 .attr('xlink:href', icon);
48782 groups.select('rect');
48783 groups.select('circle');
48789 function svgVertices$$1(projection, context) {
48791 // z16-, z17, z18+, tagged
48792 shadow: [6, 7.5, 7.5, 11.5],
48793 stroke: [2.5, 3.5, 3.5, 7],
48794 fill: [1, 1.5, 1.5, 1.5]
48800 function siblingAndChildVertices(ids, graph, extent$$1) {
48803 function addChildVertices(entity) {
48804 if (!context.features().isHiddenFeature(entity, graph, entity.geometry(graph))) {
48806 if (entity.type === 'way') {
48807 for (i = 0; i < entity.nodes.length; i++) {
48808 addChildVertices(graph.entity(entity.nodes[i]));
48810 } else if (entity.type === 'relation') {
48811 for (i = 0; i < entity.members.length; i++) {
48812 var member = context.hasEntity(entity.members[i].id);
48814 addChildVertices(member);
48817 } else if (entity.intersects(extent$$1, graph)) {
48818 vertices[entity.id] = entity;
48823 ids.forEach(function(id) {
48824 var entity = context.hasEntity(id);
48825 if (entity && entity.type === 'node') {
48826 vertices[entity.id] = entity;
48827 context.graph().parentWays(entity).forEach(function(entity) {
48828 addChildVertices(entity);
48830 } else if (entity) {
48831 addChildVertices(entity);
48839 function draw(selection$$1, vertices, klass, graph, zoom$$1, siblings) {
48841 function icon(entity) {
48842 if (entity.id in icons) return icons[entity.id];
48844 entity.hasInterestingTags() &&
48845 context.presets().match(entity, graph).icon;
48846 return icons[entity.id];
48849 function setClass(klass) {
48850 return function(entity) {
48851 this.setAttribute('class', 'node vertex ' + klass + ' ' + entity.id);
48855 function setAttributes(selection$$1) {
48856 ['shadow','stroke','fill'].forEach(function(klass) {
48857 var rads = radiuses[klass];
48858 selection$$1.selectAll('.' + klass)
48859 .each(function(entity) {
48860 var i = z && icon(entity),
48862 r = rads[i ? 3 : z];
48864 // slightly increase the size of unconnected endpoints #3775
48865 if (entity.isEndpoint(graph) && !entity.isConnected(graph)) {
48869 this.setAttribute('cx', c);
48870 this.setAttribute('cy', -c);
48871 this.setAttribute('r', r);
48872 if (i && klass === 'fill') {
48873 this.setAttribute('visibility', 'hidden');
48875 this.removeAttribute('visibility');
48880 selection$$1.selectAll('use')
48883 this.removeAttribute('visibility');
48885 this.setAttribute('visibility', 'hidden');
48891 siblings = siblings || {};
48894 z = (zoom$$1 < 17 ? 0 : zoom$$1 < 18 ? 1 : 2);
48896 var groups = selection$$1
48897 .data(vertices, osmEntity$$1.key);
48902 var enter = groups.enter()
48904 .attr('class', function(d) { return 'node vertex ' + klass + ' ' + d.id; });
48906 enter.append('circle')
48907 .each(setClass('shadow'));
48909 enter.append('circle')
48910 .each(setClass('stroke'));
48912 // Vertices with icons get a `use`.
48913 enter.filter(function(d) { return icon(d); })
48915 .attr('transform', 'translate(-5, -6)')
48916 .attr('xlink:href', function(d) { return '#' + icon(d) + '-11'; })
48917 .attr('width', '11px')
48918 .attr('height', '11px')
48919 .each(setClass('icon'));
48921 // Vertices with tags get a fill.
48922 enter.filter(function(d) { return d.hasInterestingTags(); })
48924 .each(setClass('fill'));
48928 .attr('transform', svgPointTransform(projection))
48929 .classed('sibling', function(entity) { return entity.id in siblings; })
48930 .classed('shared', function(entity) { return graph.isShared(entity); })
48931 .classed('endpoint', function(entity) { return entity.isEndpoint(graph); })
48932 .call(setAttributes);
48936 function drawVertices(selection$$1, graph, entities, filter, extent$$1, zoom$$1) {
48937 var siblings = siblingAndChildVertices(context.selectedIDs(), graph, extent$$1),
48938 wireframe = context.surface().classed('fill-wireframe'),
48941 for (var i = 0; i < entities.length; i++) {
48942 var entity = entities[i],
48943 geometry = entity.geometry(graph);
48945 if (wireframe && geometry === 'point') {
48946 vertices.push(entity);
48950 if (geometry !== 'vertex')
48953 if (entity.id in siblings ||
48954 entity.hasInterestingTags() ||
48955 entity.isEndpoint(graph) ||
48956 entity.isConnected(graph)) {
48957 vertices.push(entity);
48961 var layer = selection$$1.selectAll('.layer-hit');
48962 layer.selectAll('g.vertex.vertex-persistent')
48964 .call(draw, vertices, 'vertex-persistent', graph, zoom$$1, siblings);
48966 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48970 function drawHover(selection$$1, graph, extent$$1, zoom$$1) {
48971 var hovered = hover ? siblingAndChildVertices([hover.id], graph, extent$$1) : {};
48972 var layer = selection$$1.selectAll('.layer-hit');
48974 layer.selectAll('g.vertex.vertex-hover')
48975 .call(draw, values(hovered), 'vertex-hover', graph, zoom$$1);
48979 drawVertices.drawHover = function(selection$$1, graph, target, extent$$1, zoom$$1) {
48980 if (target === hover) return;
48982 drawHover(selection$$1, graph, extent$$1, zoom$$1);
48985 return drawVertices;
48988 function behaviorEdit(context) {
48992 .minzoom(context.minEditableZoom());
48996 edit.off = function() {
49006 The hover behavior adds the `.hover` class on mouseover to all elements to which
49007 the identical datum is bound, and removes it on mouseout.
49009 The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
49010 representation may consist of several elements scattered throughout the DOM hierarchy.
49011 Only one of these elements can have the :hover pseudo-class, but all of them will
49012 have the .hover class.
49014 function behaviorHover() {
49015 var dispatch$$1 = dispatch('hover'),
49016 selection$$1 = select(null),
49022 function keydown() {
49023 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
49024 dispatch$$1.call('hover', this, null);
49025 selection$$1.selectAll('.hover')
49026 .classed('hover-suppressed', true)
49027 .classed('hover', false);
49033 if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
49034 dispatch$$1.call('hover', this, target ? target.id : null);
49035 selection$$1.selectAll('.hover-suppressed')
49036 .classed('hover-suppressed', false)
49037 .classed('hover', true);
49042 var hover = function(__) {
49046 .on('mouseover.hover', mouseover)
49047 .on('mouseout.hover', mouseout)
49048 .on('mousedown.hover', mousedown);
49051 .on('keydown.hover', keydown)
49052 .on('keyup.hover', keyup);
49055 function mouseover() {
49056 if (buttonDown) return;
49057 var target = event.target;
49058 enter(target ? target.__data__ : null);
49062 function mouseout() {
49063 if (buttonDown) return;
49064 var target = event.relatedTarget;
49065 enter(target ? target.__data__ : null);
49069 function mousedown() {
49072 .on('mouseup.hover', mouseup, true);
49076 function mouseup() {
49077 buttonDown = false;
49079 .on('mouseup.hover', null, true);
49083 function enter(d) {
49084 if (d === target) return;
49087 selection$$1.selectAll('.hover')
49088 .classed('hover', false);
49089 selection$$1.selectAll('.hover-suppressed')
49090 .classed('hover-suppressed', false);
49092 if (target instanceof osmEntity$$1) {
49093 var selector$$1 = '.' + target.id;
49095 if (target.type === 'relation') {
49096 target.members.forEach(function(member) {
49097 selector$$1 += ', .' + member.id;
49101 var suppressed = altDisables && event && event.altKey;
49103 selection$$1.selectAll(selector$$1)
49104 .classed(suppressed ? 'hover-suppressed' : 'hover', true);
49106 dispatch$$1.call('hover', this, target.id);
49108 dispatch$$1.call('hover', this, null);
49115 hover.off = function(selection$$1) {
49116 selection$$1.selectAll('.hover')
49117 .classed('hover', false);
49118 selection$$1.selectAll('.hover-suppressed')
49119 .classed('hover-suppressed', false);
49122 .on('mouseover.hover', null)
49123 .on('mouseout.hover', null)
49124 .on('mousedown.hover', null);
49127 .on('keydown.hover', null)
49128 .on('keyup.hover', null);
49132 hover.altDisables = function(_) {
49133 if (!arguments.length) return altDisables;
49139 return utilRebind(hover, dispatch$$1, 'on');
49142 function behaviorTail() {
49146 tooltipSize = [0, 0],
49147 selectionSize = [0, 0];
49150 function tail(selection$$1) {
49151 if (!text$$1) return;
49154 .on('resize.tail', function() { selectionSize = utilGetDimensions(selection$$1); });
49156 container = select(document.body)
49158 .style('display', 'none')
49159 .attr('class', 'tail tooltip-inner');
49161 container.append('div')
49165 .on('mousemove.tail', mousemove)
49166 .on('mouseenter.tail', mouseenter)
49167 .on('mouseleave.tail', mouseleave);
49170 .on('mousemove.tail', mousemove);
49172 tooltipSize = utilGetDimensions(container);
49173 selectionSize = utilGetDimensions(selection$$1);
49177 container.style('display', 'block');
49178 tooltipSize = utilGetDimensions(container);
49182 function mousemove() {
49183 if (container.style('display') === 'none') show();
49184 var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
49185 -tooltipSize[0] - xmargin : xmargin;
49186 container.classed('left', xoffset > 0);
49187 utilSetTransform(container, event.clientX + xoffset, event.clientY);
49191 function mouseleave() {
49192 if (event.relatedTarget !== container.node()) {
49193 container.style('display', 'none');
49198 function mouseenter() {
49199 if (event.relatedTarget !== container.node()) {
49206 tail.off = function(selection$$1) {
49207 if (!text$$1) return;
49210 .on('mousemove.tail', null)
49214 .on('mousemove.tail', null)
49215 .on('mouseenter.tail', null)
49216 .on('mouseleave.tail', null);
49219 .on('resize.tail', null);
49223 tail.text = function(_) {
49224 if (!arguments.length) return text$$1;
49233 behaviorDraw.usedTails = {};
49234 behaviorDraw.disableSpace = false;
49235 behaviorDraw.lastSpace = null;
49238 function behaviorDraw(context) {
49239 var dispatch$$1 = dispatch('move', 'click', 'clickWay',
49240 'clickNode', 'undo', 'cancel', 'finish'),
49241 keybinding = d3keybinding('draw'),
49242 hover = behaviorHover(context)
49244 .on('hover', context.ui().sidebar.hover),
49245 tail = behaviorTail(),
49246 edit = behaviorEdit(context),
49247 closeTolerance = 4,
49249 mouseLeave = false,
49251 cached = behaviorDraw;
49255 if (event.altKey) return {};
49257 if (event.type === 'keydown') {
49258 return (lastMouse && lastMouse.target.__data__) || {};
49260 return event.target.__data__ || {};
49265 function mousedown() {
49268 var p = context.container().node();
49269 return touchId !== null ? touches(p).filter(function(p) {
49270 return p.identifier === touchId;
49274 var element = select(this),
49275 touchId = event.touches ? event.changedTouches[0].identifier : null,
49279 element.on('mousemove.draw', null);
49281 select(window).on('mouseup.draw', function() {
49282 var t2 = +new Date(),
49284 dist = geoEuclideanDistance(p1, p2);
49286 element.on('mousemove.draw', mousemove);
49287 select(window).on('mouseup.draw', null);
49289 if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
49290 // Prevent a quick second click
49291 select(window).on('click.draw-block', function() {
49292 event.stopPropagation();
49295 context.map().dblclickEnable(false);
49297 window.setTimeout(function() {
49298 context.map().dblclickEnable(true);
49299 select(window).on('click.draw-block', null);
49308 function mousemove() {
49310 dispatch$$1.call('move', this, datum());
49314 function mouseenter() {
49315 mouseLeave = false;
49319 function mouseleave() {
49326 if (d.type === 'way') {
49327 var dims = context.map().dimensions(),
49328 mouse$$1 = context.mouse(),
49330 trySnap = mouse$$1[0] > pad && mouse$$1[0] < dims[0] - pad &&
49331 mouse$$1[1] > pad && mouse$$1[1] < dims[1] - pad;
49334 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection),
49335 edge = [d.nodes[choice.index - 1], d.nodes[choice.index]];
49336 dispatch$$1.call('clickWay', this, choice.loc, edge);
49338 dispatch$$1.call('click', this, context.map().mouseCoordinates());
49341 } else if (d.type === 'node') {
49342 dispatch$$1.call('clickNode', this, d);
49345 dispatch$$1.call('click', this, context.map().mouseCoordinates());
49351 var currSpace = context.mouse();
49352 if (cached.disableSpace && cached.lastSpace) {
49353 var dist = geoEuclideanDistance(cached.lastSpace, currSpace);
49354 if (dist > tolerance) {
49355 cached.disableSpace = false;
49359 if (cached.disableSpace || mouseLeave || !lastMouse) return;
49361 // user must move mouse or release space bar to allow another click
49362 cached.lastSpace = currSpace;
49363 cached.disableSpace = true;
49365 select(window).on('keyup.space-block', function() {
49366 cached.disableSpace = false;
49367 select(window).on('keyup.space-block', null);
49370 event.preventDefault();
49375 function backspace() {
49376 event.preventDefault();
49377 dispatch$$1.call('undo');
49382 event.preventDefault();
49383 dispatch$$1.call('cancel');
49388 event.preventDefault();
49389 dispatch$$1.call('finish');
49393 function draw(selection$$1) {
49394 context.install(hover);
49395 context.install(edit);
49397 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
49398 context.install(tail);
49402 .on('⌫', backspace)
49406 .on('space', space)
49407 .on('⌥space', space);
49410 .on('mouseenter.draw', mouseenter)
49411 .on('mouseleave.draw', mouseleave)
49412 .on('mousedown.draw', mousedown)
49413 .on('mousemove.draw', mousemove);
49422 draw.off = function(selection$$1) {
49423 context.ui().sidebar.hover.cancel();
49424 context.uninstall(hover);
49425 context.uninstall(edit);
49427 if (!context.inIntro() && !cached.usedTails[tail.text()]) {
49428 context.uninstall(tail);
49429 cached.usedTails[tail.text()] = true;
49433 .on('mouseenter.draw', null)
49434 .on('mouseleave.draw', null)
49435 .on('mousedown.draw', null)
49436 .on('mousemove.draw', null);
49439 .on('mouseup.draw', null);
49440 // note: keyup.space-block, click.draw-block should remain
49443 .call(keybinding.off);
49447 draw.tail = function(_) {
49453 return utilRebind(draw, dispatch$$1, 'on');
49456 function behaviorAddWay(context) {
49457 var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
49458 draw = behaviorDraw(context);
49460 var addWay = function(surface) {
49461 draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
49462 .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
49463 .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
49464 .on('cancel', addWay.cancel)
49465 .on('finish', addWay.cancel);
49468 .dblclickEnable(false);
49470 surface.call(draw);
49474 addWay.off = function(surface) {
49475 surface.call(draw.off);
49479 addWay.cancel = function() {
49480 window.setTimeout(function() {
49481 context.map().dblclickEnable(true);
49484 context.enter(modeBrowse(context));
49488 addWay.tail = function(text$$1) {
49489 draw.tail(text$$1);
49494 return utilRebind(addWay, dispatch$$1, 'on');
49497 function behaviorBreathe() {
49498 var duration = 800,
49500 selector$$1 = '.selected.shadow, .selected .shadow',
49501 selected = select(null),
49508 function ratchetyInterpolator(a, b, steps, units) {
49511 var sample = quantize$2()
49513 .range(quantize$1(number$1(a, b), steps));
49515 return function(t) {
49516 return String(sample(t)) + (units || '');
49521 function reset(selection$$1) {
49523 .style('stroke-opacity', null)
49524 .style('stroke-width', null)
49525 .style('fill-opacity', null)
49530 function setAnimationParams(transition$$1, fromTo) {
49531 var toFrom = (fromTo === 'from' ? 'to' : 'from');
49534 .styleTween('stroke-opacity', function(d) {
49535 return ratchetyInterpolator(
49536 params[d.id][toFrom].opacity,
49537 params[d.id][fromTo].opacity,
49541 .styleTween('stroke-width', function(d) {
49542 return ratchetyInterpolator(
49543 params[d.id][toFrom].width,
49544 params[d.id][fromTo].width,
49549 .styleTween('fill-opacity', function(d) {
49550 return ratchetyInterpolator(
49551 params[d.id][toFrom].opacity,
49552 params[d.id][fromTo].opacity,
49556 .styleTween('r', function(d) {
49557 return ratchetyInterpolator(
49558 params[d.id][toFrom].width,
49559 params[d.id][fromTo].width,
49567 function calcAnimationParams(selection$$1) {
49570 .each(function(d) {
49571 var s = select(this),
49572 tag = s.node().tagName,
49573 p = {'from': {}, 'to': {}},
49576 // determine base opacity and width
49577 if (tag === 'circle') {
49578 opacity = parseFloat(s.style('fill-opacity') || 0.5);
49579 width = parseFloat(s.style('r') || 15.5);
49581 opacity = parseFloat(s.style('stroke-opacity') || 0.7);
49582 width = parseFloat(s.style('stroke-width') || 10);
49585 // calculate from/to interpolation params..
49587 p.from.opacity = opacity * 0.6;
49588 p.to.opacity = opacity * 1.25;
49589 p.from.width = width * 0.9;
49590 p.to.width = width * (tag === 'circle' ? 1.5 : 1.25);
49596 function run(surface, fromTo) {
49597 var toFrom = (fromTo === 'from' ? 'to' : 'from'),
49598 currSelected = surface.selectAll(selector$$1),
49599 currClassed = surface.attr('class');
49601 if (done || currSelected.empty()) {
49602 selected.call(reset);
49606 if (!lodash.isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
49607 selected.call(reset);
49608 classed = currClassed;
49609 selected = currSelected.call(calcAnimationParams);
49614 .duration(duration)
49615 .call(setAnimationParams, fromTo)
49616 .on('end', function() {
49617 surface.call(run, toFrom);
49622 var breathe = function(surface) {
49624 timer$$1 = timer$1(function() {
49625 // wait for elements to actually become selected
49626 if (surface.selectAll(selector$$1).empty()) {
49630 surface.call(run, 'from');
49637 breathe.off = function() {
49651 function behaviorCopy(context) {
49652 var keybinding = d3keybinding('copy');
49655 function groupEntities(ids, graph) {
49656 var entities = ids.map(function (id) { return graph.entity(id); });
49657 return lodash.extend({relation: [], way: [], node: []},
49658 lodash.groupBy(entities, function(entity) { return entity.type; }));
49662 function getDescendants(id, graph, descendants) {
49663 var entity = graph.entity(id),
49666 descendants = descendants || {};
49668 if (entity.type === 'relation') {
49669 children = lodash.map(entity.members, 'id');
49670 } else if (entity.type === 'way') {
49671 children = entity.nodes;
49676 for (i = 0; i < children.length; i++) {
49677 if (!descendants[children[i]]) {
49678 descendants[children[i]] = true;
49679 descendants = getDescendants(children[i], graph, descendants);
49683 return descendants;
49687 function doCopy() {
49688 event.preventDefault();
49689 if (context.inIntro()) return;
49691 var graph = context.graph(),
49692 selected = groupEntities(context.selectedIDs(), graph),
49697 for (i = 0; i < selected.relation.length; i++) {
49698 entity = selected.relation[i];
49699 if (!skip[entity.id] && entity.isComplete(graph)) {
49700 canCopy.push(entity.id);
49701 skip = getDescendants(entity.id, graph, skip);
49704 for (i = 0; i < selected.way.length; i++) {
49705 entity = selected.way[i];
49706 if (!skip[entity.id]) {
49707 canCopy.push(entity.id);
49708 skip = getDescendants(entity.id, graph, skip);
49711 for (i = 0; i < selected.node.length; i++) {
49712 entity = selected.node[i];
49713 if (!skip[entity.id]) {
49714 canCopy.push(entity.id);
49718 context.copyIDs(canCopy);
49723 keybinding.on(uiCmd('⌘C'), doCopy);
49724 select(document).call(keybinding);
49729 copy.off = function() {
49730 select(document).call(keybinding.off);
49738 `behaviorDrag` is like `d3.behavior.drag`, with the following differences:
49740 * The `origin` function is expected to return an [x, y] tuple rather than an
49742 * The events are `start`, `move`, and `end`.
49743 (https://github.com/mbostock/d3/issues/563)
49744 * The `start` event is not dispatched until the first cursor movement occurs.
49745 (https://github.com/mbostock/d3/pull/368)
49746 * The `move` event has a `point` and `delta` [x, y] tuple properties rather
49747 than `x`, `y`, `dx`, and `dy` properties.
49748 * The `end` event is not dispatched if no movement occurs.
49749 * An `off` function is available that unbinds the drag's internal event handlers.
49750 * Delegation is supported via the `delegate` function.
49753 function behaviorDrag() {
49754 var event$$1 = dispatch('start', 'move', 'end'),
49758 event_, target, surface;
49761 function d3_eventCancel() {
49762 event.stopPropagation();
49763 event.preventDefault();
49766 function eventOf(thiz, argumentz) {
49767 return function(e1) {
49768 e1.target = drag$$1;
49769 customEvent(e1, event$$1.apply, event$$1, [e1.type, thiz, argumentz]);
49773 var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect'),
49774 d3_event_userSelectSuppress = d3_event_userSelectProperty ?
49776 var selection$$1 = selection(),
49777 select$$1 = selection$$1.style(d3_event_userSelectProperty);
49778 selection$$1.style(d3_event_userSelectProperty, 'none');
49779 return function () {
49780 selection$$1.style(d3_event_userSelectProperty, select$$1);
49784 var w = select(window).on('selectstart.' + type, d3_eventCancel);
49785 return function () {
49786 w.on('selectstart.' + type, null);
49791 function dragstart() {
49793 event_ = eventOf(target, arguments);
49795 var eventTarget = event.target,
49796 touchId = event.touches ? event.changedTouches[0].identifier : null,
49800 selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
49802 var w = select(window)
49803 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
49804 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
49807 offset = origin.apply(target, arguments);
49808 offset = [offset[0] - origin_[0], offset[1] - origin_[1]];
49813 if (touchId === null) event.stopPropagation();
49817 var p = surface || target.parentNode;
49818 return touchId !== null ? touches(p).filter(function(p) {
49819 return p.identifier === touchId;
49824 function dragmove() {
49826 dx = p[0] - origin_[0],
49827 dy = p[1] - origin_[1];
49829 if (dx === 0 && dy === 0)
49844 point: [p[0] + offset[0], p[1] + offset[1]],
49850 function dragend() {
49857 if (event.target === eventTarget) w.on('click.drag', click, true);
49860 w.on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
49861 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
49868 w.on('click.drag', null);
49873 function drag$$1(selection$$1) {
49874 var matchesSelector = utilPrefixDOMProperty('matchesSelector'),
49875 delegate = dragstart;
49878 delegate = function() {
49880 target = event.target;
49881 for (; target && target !== root; target = target.parentNode) {
49882 if (target[matchesSelector](selector$$1) &&
49883 (!filter || filter(target.__data__))) {
49884 return dragstart.call(target, target.__data__);
49890 selection$$1.on('mousedown.drag' + selector$$1, delegate)
49891 .on('touchstart.drag' + selector$$1, delegate);
49895 drag$$1.off = function(selection$$1) {
49896 selection$$1.on('mousedown.drag' + selector$$1, null)
49897 .on('touchstart.drag' + selector$$1, null);
49901 drag$$1.delegate = function(_) {
49902 if (!arguments.length) return selector$$1;
49908 drag$$1.filter = function(_) {
49909 if (!arguments.length) return origin;
49915 drag$$1.origin = function (_) {
49916 if (!arguments.length) return origin;
49922 drag$$1.cancel = function() {
49924 .on('mousemove.drag', null)
49925 .on('mouseup.drag', null);
49930 drag$$1.target = function() {
49931 if (!arguments.length) return target;
49932 target = arguments[0];
49933 event_ = eventOf(target, Array.prototype.slice.call(arguments, 1));
49938 drag$$1.surface = function() {
49939 if (!arguments.length) return surface;
49940 surface = arguments[0];
49945 return utilRebind(drag$$1, event$$1, 'on');
49948 function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
49950 var way = context.entity(wayId),
49951 isArea = context.geometry(wayId) === 'area',
49953 annotation = t((way.isDegenerate() ?
49954 'operations.start.annotation.' :
49955 'operations.continue.annotation.') + context.geometry(wayId)),
49956 draw = behaviorDraw(context),
49957 startIndex, start, end, segment;
49961 startIndex = typeof index === 'undefined' ? way.nodes.length - 1 : 0;
49962 start = osmNode({ id: 'nStart', loc: context.entity(way.nodes[startIndex]).loc });
49963 end = osmNode({ id: 'nEnd', loc: context.map().mouseCoordinates() });
49964 segment = osmWay({ id: 'wTemp',
49965 nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
49966 tags: lodash.clone(way.tags)
49969 end = osmNode({ loc: context.map().mouseCoordinates() });
49973 var fn = context[way.isDegenerate() ? 'replace' : 'perform'];
49975 fn(actionAddEntity(end),
49976 actionAddVertex(wayId, end.id)
49979 fn(actionAddEntity(start),
49980 actionAddEntity(end),
49981 actionAddEntity(segment)
49986 function move(datum) {
49989 if (datum.type === 'node' && datum.id !== end.id) {
49992 } else if (datum.type === 'way') { // && (segment || datum.id !== segment.id)) {
49993 var dims = context.map().dimensions(),
49994 mouse = context.mouse(),
49996 trySnap = mouse[0] > pad && mouse[0] < dims[0] - pad &&
49997 mouse[1] > pad && mouse[1] < dims[1] - pad;
50000 loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
50005 loc = context.map().mouseCoordinates();
50008 context.replace(actionMoveNode(end.id, loc));
50012 function undone() {
50014 context.enter(modeBrowse(context));
50018 function setActiveElements() {
50019 var active = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
50020 context.surface().selectAll(utilEntitySelector(active))
50021 .classed('active', true);
50025 var drawWay = function(surface) {
50026 draw.on('move', move)
50027 .on('click', drawWay.add)
50028 .on('clickWay', drawWay.addWay)
50029 .on('clickNode', drawWay.addNode)
50030 .on('undo', context.undo)
50031 .on('cancel', drawWay.cancel)
50032 .on('finish', drawWay.finish);
50035 .dblclickEnable(false)
50036 .on('drawn.draw', setActiveElements);
50038 setActiveElements();
50040 surface.call(draw);
50043 .on('undone.draw', undone);
50047 drawWay.off = function(surface) {
50052 .on('drawn.draw', null);
50054 surface.call(draw.off)
50055 .selectAll('.active')
50056 .classed('active', false);
50059 .on('undone.draw', null);
50063 function ReplaceTemporaryNode(newNode) {
50064 return function(graph) {
50067 .replace(way.addNode(newNode.id))
50071 .replace(graph.entity(wayId).addNode(newNode.id, index))
50080 // Accept the current position of the temporary node and continue drawing.
50081 drawWay.add = function(loc) {
50082 // prevent duplicate nodes
50083 var last = context.hasEntity(way.nodes[way.nodes.length - (isArea ? 2 : 1)]);
50084 if (last && last.loc[0] === loc[0] && last.loc[1] === loc[1]) return;
50088 actionMoveNode(end.id, loc),
50092 var newNode = osmNode({loc: loc});
50094 actionAddEntity(newNode),
50095 ReplaceTemporaryNode(newNode),
50101 context.enter(mode);
50105 // Connect the way to an existing way.
50106 drawWay.addWay = function(loc, edge) {
50110 actionAddMidpoint({ loc: loc, edge: edge}, end),
50114 var previousEdge = startIndex ?
50115 [way.nodes[startIndex], way.nodes[startIndex - 1]] :
50116 [way.nodes[0], way.nodes[1]];
50118 // Avoid creating duplicate segments
50119 if (geoEdgeEqual(edge, previousEdge))
50122 var newNode = osmNode({ loc: loc });
50124 actionAddMidpoint({ loc: loc, edge: edge}, newNode),
50125 ReplaceTemporaryNode(newNode),
50131 context.enter(mode);
50135 // Connect the way to an existing node and continue drawing.
50136 drawWay.addNode = function(node) {
50137 // Avoid creating duplicate segments
50138 if (way.areAdjacent(node.id, way.nodes[way.nodes.length - 1])) return;
50141 ReplaceTemporaryNode(node),
50146 context.enter(mode);
50150 // Finish the draw operation, removing the temporary node. If the way has enough
50151 // nodes to be valid, it's selected. Otherwise, return to browse mode.
50152 drawWay.finish = function() {
50156 window.setTimeout(function() {
50157 context.map().dblclickEnable(true);
50160 if (context.hasEntity(wayId)) {
50162 modeSelect(context, [wayId]).suppressMenu(true).newFeature(true)
50165 context.enter(modeBrowse(context));
50170 // Cancel the draw operation and return to browse, deleting everything drawn.
50171 drawWay.cancel = function() {
50173 utilFunctor(baseGraph),
50174 t('operations.cancel_draw.annotation'));
50176 window.setTimeout(function() {
50177 context.map().dblclickEnable(true);
50181 context.enter(modeBrowse(context));
50185 drawWay.tail = function(text) {
50194 function behaviorHash(context) {
50195 var s0 = null, // cached window.location.hash
50196 lat = 90 - 1e-8; // allowable latitude range
50199 var parser = function(map$$1, s) {
50200 var q = utilStringQs(s);
50201 var args = (q.map || '').split('/').map(Number);
50202 if (args.length < 3 || args.some(isNaN)) {
50203 return true; // replace bogus hash
50204 } else if (s !== formatter(map$$1).slice(1)) {
50205 map$$1.centerZoom([args[2],
50206 Math.min(lat, Math.max(-lat, args[1]))], args[0]);
50211 var formatter = function(map$$1) {
50212 var mode = context.mode(),
50213 center = map$$1.center(),
50214 zoom$$1 = map$$1.zoom(),
50215 precision = Math.max(0, Math.ceil(Math.log(zoom$$1) / Math.LN2)),
50216 q = lodash.omit(utilStringQs(window.location.hash.substring(1)), 'comment'),
50219 if (mode && mode.id === 'browse') {
50222 var selected = context.selectedIDs().filter(function(id) {
50223 return !context.entity(id).isNew();
50225 if (selected.length) {
50226 newParams.id = selected.join(',');
50230 newParams.map = zoom$$1.toFixed(2) +
50231 '/' + center[1].toFixed(precision) +
50232 '/' + center[0].toFixed(precision);
50234 return '#' + utilQsString(lodash.assign(q, newParams), true);
50238 function update() {
50239 if (context.inIntro()) return;
50240 var s1 = formatter(context.map());
50242 window.location.replace(s0 = s1); // don't recenter the map!
50247 var throttledUpdate = lodash.throttle(update, 500);
50250 function hashchange() {
50251 if (window.location.hash === s0) return; // ignore spurious hashchange events
50252 if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
50253 update(); // replace bogus hash
50260 .on('move.hash', throttledUpdate);
50263 .on('enter.hash', throttledUpdate);
50266 .on('hashchange.hash', hashchange);
50268 if (window.location.hash) {
50269 var q = utilStringQs(window.location.hash.substring(1));
50270 if (q.id) context.zoomToEntity(q.id.split(',')[0], !q.map);
50271 if (q.comment) context.storage('comment', q.comment);
50273 if (q.map) hash.hadHash = true;
50278 hash.off = function() {
50279 throttledUpdate.cancel();
50282 .on('move.hash', null);
50285 .on('enter.hash', null);
50288 .on('hashchange.hash', null);
50290 window.location.hash = '';
50297 function behaviorLasso(context) {
50299 var behavior = function(selection$$1) {
50303 function mousedown() {
50304 var button = 0; // left
50305 if (event.button === button && event.shiftKey === true) {
50309 .on('mousemove.lasso', mousemove)
50310 .on('mouseup.lasso', mouseup);
50312 event.stopPropagation();
50317 function mousemove() {
50319 lasso = uiLasso(context);
50320 context.surface().call(lasso);
50323 lasso.p(context.mouse());
50327 function normalize(a, b) {
50329 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
50330 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
50334 function lassoed() {
50335 if (!lasso) return [];
50337 var graph = context.graph(),
50338 bounds = lasso.extent().map(context.projection.invert),
50339 extent$$1 = geoExtent$$1(normalize(bounds[0], bounds[1]));
50341 return lodash.map(context.intersects(extent$$1).filter(function(entity) {
50342 return entity.type === 'node' &&
50343 geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
50344 !context.features().isHidden(entity, graph, entity.geometry(graph));
50349 function mouseup() {
50351 .on('mousemove.lasso', null)
50352 .on('mouseup.lasso', null);
50354 if (!lasso) return;
50356 var ids = lassoed();
50360 context.enter(modeSelect(context, ids));
50365 .on('mousedown.lasso', mousedown);
50369 behavior.off = function(selection$$1) {
50370 selection$$1.on('mousedown.lasso', null);
50377 /* Creates a keybinding behavior for an operation */
50378 function behaviorOperation(context) {
50379 var which, keybinding;
50382 var behavior = function () {
50384 keybinding = d3keybinding('behavior.key.' + which.id);
50385 keybinding.on(which.keys, function() {
50386 event.preventDefault();
50387 if (which.available() && !which.disabled() && !context.inIntro()) {
50391 select(document).call(keybinding);
50397 behavior.off = function() {
50399 select(document).call(keybinding.off);
50404 behavior.which = function (_) {
50405 if (!arguments.length) return which;
50414 function behaviorPaste(context) {
50415 var keybinding = d3keybinding('paste');
50417 function omitTag(v, k) {
50425 k === 'description' ||
50426 k.indexOf('name') !== -1 ||
50427 k.indexOf('wiki') === 0 ||
50428 k.indexOf('addr:') === 0 ||
50429 k.indexOf('contact:') === 0
50434 function doPaste() {
50435 event.preventDefault();
50436 if (context.inIntro()) return;
50438 var baseGraph = context.graph(),
50439 mouse$$1 = context.mouse(),
50440 projection = context.projection,
50441 viewport = geoExtent$$1(projection.clipExtent()).polygon();
50443 if (!geoPointInPolygon(mouse$$1, viewport)) return;
50445 var extent$$1 = geoExtent$$1(),
50446 oldIDs = context.copyIDs(),
50447 oldGraph = context.copyGraph(),
50450 if (!oldIDs.length) return;
50452 var action = actionCopyEntities(oldIDs, oldGraph);
50453 context.perform(action);
50455 var copies = action.copies();
50456 var originals = lodash.invert(lodash.mapValues(copies, 'id'));
50457 for (var id in copies) {
50458 var oldEntity = oldGraph.entity(id),
50459 newEntity = copies[id];
50461 extent$$1._extend(oldEntity.extent(oldGraph));
50463 actionChangeTags(newEntity.id, lodash.omit(newEntity.tags, omitTag))
50466 // Exclude child nodes from newIDs if their parent way was also copied.
50467 var parents = context.graph().parentWays(newEntity),
50468 parentCopied = false;
50469 for (var i = 0; i < parents.length; i++) {
50470 if (originals[parents[i].id]) {
50471 parentCopied = true;
50476 if (!parentCopied) {
50477 newIDs.push(newEntity.id);
50481 // Put pasted objects where mouse pointer is..
50482 var center = projection(extent$$1.center()),
50483 delta = [ mouse$$1[0] - center[0], mouse$$1[1] - center[1] ];
50485 context.perform(actionMove(newIDs, delta, projection));
50486 context.enter(modeMove$$1(context, newIDs, baseGraph));
50491 keybinding.on(uiCmd('⌘V'), doPaste);
50492 select(document).call(keybinding);
50497 paste.off = function() {
50498 select(document).call(keybinding.off);
50505 function behaviorSelect(context) {
50507 function keydown() {
50508 if (event && event.shiftKey) {
50510 .classed('behavior-multiselect', true);
50516 if (!event || !event.shiftKey) {
50518 .classed('behavior-multiselect', false);
50524 var datum = event.target.__data__,
50525 lasso = select('#surface .lasso').node(),
50526 mode = context.mode();
50528 if (datum.type === 'midpoint') {
50530 } else if (!(datum instanceof osmEntity$$1)) {
50531 if (!event.shiftKey && !lasso && mode.id !== 'browse')
50532 context.enter(modeBrowse(context));
50534 } else if (!event.shiftKey && !lasso) {
50535 // Avoid re-entering Select mode with same entity.
50536 if (context.selectedIDs().length !== 1 || context.selectedIDs()[0] !== datum.id) {
50537 context.enter(modeSelect(context, [datum.id]));
50539 mode.suppressMenu(false).reselect();
50541 } else if (context.selectedIDs().indexOf(datum.id) >= 0) {
50542 var selectedIDs = lodash.without(context.selectedIDs(), datum.id);
50543 context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
50546 context.enter(modeSelect(context, context.selectedIDs().concat([datum.id])));
50551 var behavior = function(selection$$1) {
50553 .on('keydown.select', keydown)
50554 .on('keyup.select', keyup);
50556 selection$$1.on('click.select', click);
50562 behavior.off = function(selection$$1) {
50564 .on('keydown.select', null)
50565 .on('keyup.select', null);
50567 selection$$1.on('click.select', null);
50576 function modeAddArea$$1(context) {
50580 title: t('modes.add_area.title'),
50581 description: t('modes.add_area.description'),
50585 var behavior = behaviorAddWay(context)
50586 .tail(t('modes.add_area.tail'))
50587 .on('start', start)
50588 .on('startFromWay', startFromWay)
50589 .on('startFromNode', startFromNode),
50590 defaultTags = { area: 'yes' };
50593 function actionClose(wayId) {
50594 return function (graph) {
50595 return graph.replace(graph.entity(wayId).close());
50600 function start(loc) {
50601 var graph = context.graph(),
50602 node = osmNode({ loc: loc }),
50603 way = osmWay({ tags: defaultTags });
50606 actionAddEntity(node),
50607 actionAddEntity(way),
50608 actionAddVertex(way.id, node.id),
50609 actionClose(way.id)
50612 context.enter(modeDrawArea(context, way.id, graph));
50616 function startFromWay(loc, edge) {
50617 var graph = context.graph(),
50618 node = osmNode({ loc: loc }),
50619 way = osmWay({ tags: defaultTags });
50622 actionAddEntity(node),
50623 actionAddEntity(way),
50624 actionAddVertex(way.id, node.id),
50625 actionClose(way.id),
50626 actionAddMidpoint({ loc: loc, edge: edge }, node)
50629 context.enter(modeDrawArea(context, way.id, graph));
50633 function startFromNode(node) {
50634 var graph = context.graph(),
50635 way = osmWay({ tags: defaultTags });
50638 actionAddEntity(way),
50639 actionAddVertex(way.id, node.id),
50640 actionClose(way.id)
50643 context.enter(modeDrawArea(context, way.id, graph));
50647 mode.enter = function() {
50648 context.install(behavior);
50652 mode.exit = function() {
50653 context.uninstall(behavior);
50660 function modeAddLine$$1(context) {
50664 title: t('modes.add_line.title'),
50665 description: t('modes.add_line.description'),
50669 var behavior = behaviorAddWay(context)
50670 .tail(t('modes.add_line.tail'))
50671 .on('start', start)
50672 .on('startFromWay', startFromWay)
50673 .on('startFromNode', startFromNode);
50676 function start(loc) {
50677 var baseGraph = context.graph(),
50678 node = osmNode({ loc: loc }),
50682 actionAddEntity(node),
50683 actionAddEntity(way),
50684 actionAddVertex(way.id, node.id)
50687 context.enter(modeDrawLine(context, way.id, baseGraph));
50691 function startFromWay(loc, edge) {
50692 var baseGraph = context.graph(),
50693 node = osmNode({ loc: loc }),
50697 actionAddEntity(node),
50698 actionAddEntity(way),
50699 actionAddVertex(way.id, node.id),
50700 actionAddMidpoint({ loc: loc, edge: edge }, node)
50703 context.enter(modeDrawLine(context, way.id, baseGraph));
50707 function startFromNode(node) {
50708 var baseGraph = context.graph(),
50712 actionAddEntity(way),
50713 actionAddVertex(way.id, node.id)
50716 context.enter(modeDrawLine(context, way.id, baseGraph));
50720 mode.enter = function() {
50721 context.install(behavior);
50725 mode.exit = function() {
50726 context.uninstall(behavior);
50732 function modeAddPoint$$1(context) {
50736 title: t('modes.add_point.title'),
50737 description: t('modes.add_point.description'),
50741 var behavior = behaviorDraw(context)
50742 .tail(t('modes.add_point.tail'))
50744 .on('clickWay', addWay)
50745 .on('clickNode', addNode)
50746 .on('cancel', cancel)
50747 .on('finish', cancel);
50750 function add(loc) {
50751 var node = osmNode({ loc: loc });
50754 actionAddEntity(node),
50755 t('operations.add.annotation.point')
50759 modeSelect(context, [node.id]).suppressMenu(true).newFeature(true)
50764 function addWay(loc) {
50769 function addNode(node) {
50774 function cancel() {
50775 context.enter(modeBrowse(context));
50779 mode.enter = function() {
50780 context.install(behavior);
50784 mode.exit = function() {
50785 context.uninstall(behavior);
50792 function modeBrowse(context) {
50796 title: t('modes.browse.title'),
50797 description: t('modes.browse.description')
50801 behaviorPaste(context),
50802 behaviorHover(context).on('hover', context.ui().sidebar.hover),
50803 behaviorSelect(context),
50804 behaviorLasso(context)
50808 mode.enter = function() {
50809 behaviors.forEach(function(behavior) {
50810 context.install(behavior);
50813 // Get focus on the body.
50814 if (document.activeElement && document.activeElement.blur) {
50815 document.activeElement.blur();
50819 context.ui().sidebar.show(sidebar);
50821 context.ui().sidebar.select(null);
50826 mode.exit = function() {
50827 context.ui().sidebar.hover.cancel();
50828 behaviors.forEach(function(behavior) {
50829 context.uninstall(behavior);
50833 context.ui().sidebar.hide();
50838 mode.sidebar = function(_) {
50839 if (!arguments.length) return sidebar;
50848 function modeDragNode$$1(context) {
50860 hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover),
50861 edit = behaviorEdit(context);
50864 function vecSub(a, b) {
50865 return [a[0] - b[0], a[1] - b[1]];
50868 function edge(point, size) {
50869 var pad = [30, 100, 30, 100],
50873 if (point[0] > size[0] - pad[0])
50875 if (point[0] < pad[2])
50877 if (point[1] > size[1] - pad[1])
50879 if (point[1] < pad[3])
50890 function startNudge(entity, nudge) {
50891 if (nudgeInterval) window.clearInterval(nudgeInterval);
50892 nudgeInterval = window.setInterval(function() {
50893 context.pan(nudge);
50894 doMove(entity, nudge);
50899 function stopNudge() {
50900 if (nudgeInterval) window.clearInterval(nudgeInterval);
50901 nudgeInterval = null;
50905 function moveAnnotation(entity) {
50906 return t('operations.move.annotation.' + entity.geometry(context.graph()));
50910 function connectAnnotation(entity) {
50911 return t('operations.connect.annotation.' + entity.geometry(context.graph()));
50915 function origin(entity) {
50916 return context.projection(entity.loc);
50920 function start(entity) {
50921 wasMidpoint = entity.type === 'midpoint';
50923 // Things allowed to be dragged include:
50925 // - nodes that are selected
50926 // - vertices that are selected
50927 // - vertices classed 'sibling' which includes (see svg/vertices.js)
50928 // - children of selected ways or multipolygons
50929 // - vertices sharing a way with selected vertices
50930 var selector$$1 = 'g.node.point.selected.' + entity.id +
50931 ', g.vertex-persistent.selected.' + entity.id +
50932 ', g.vertex-persistent.sibling.' + entity.id;
50934 var isDraggable = wasMidpoint || !select(selector$$1).empty();
50936 isCancelled = event.sourceEvent.shiftKey || !isDraggable ||
50937 context.features().hasHiddenConnections(entity, context.graph());
50940 return behavior.cancel();
50944 var midpoint = entity;
50945 entity = osmNode();
50946 context.perform(actionAddMidpoint(midpoint, entity));
50948 var vertex = context.surface().selectAll('.' + entity.id);
50949 behavior.target(vertex.node(), entity);
50952 context.perform(actionNoop());
50955 // activeIDs generate no pointer events. This prevents the node or vertex
50956 // being dragged from trying to connect to itself or its parent element.
50957 activeIDs = lodash.map(context.graph().parentWays(entity), 'id');
50958 activeIDs.push(entity.id);
50959 setActiveElements();
50961 context.enter(mode);
50966 var event$$1 = event && event.sourceEvent;
50967 if (!event$$1 || event$$1.altKey) {
50970 return event$$1.target.__data__ || {};
50975 function doMove(entity, nudge) {
50976 nudge = nudge || [0, 0];
50978 var currPoint = (event && event.point) || context.projection(lastLoc),
50979 currMouse = vecSub(currPoint, nudge),
50980 loc = context.projection.invert(currMouse),
50983 if (d.type === 'node' && d.id !== entity.id) {
50985 } else if (d.type === 'way' && !select(event.sourceEvent.target).classed('fill')) {
50986 loc = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection).loc;
50990 actionMoveNode(entity.id, loc),
50991 moveAnnotation(entity)
50998 function move(entity) {
50999 if (isCancelled) return;
51000 event.sourceEvent.stopPropagation();
51001 lastLoc = context.projection.invert(event.point);
51004 var nudge = edge(event.point, context.map().dimensions());
51005 if (nudge) startNudge(entity, nudge);
51010 function end(entity) {
51011 if (isCancelled) return;
51015 if (d.type === 'way') {
51016 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
51018 actionAddMidpoint({ loc: choice.loc, edge: [d.nodes[choice.index - 1], d.nodes[choice.index]] }, entity),
51019 connectAnnotation(d)
51022 } else if (d.type === 'node' && d.id !== entity.id) {
51024 actionConnect([d.id, entity.id]),
51025 connectAnnotation(d)
51028 } else if (wasMidpoint) {
51031 t('operations.add.annotation.vertex')
51037 moveAnnotation(entity)
51041 var reselection = selectedIDs.filter(function(id) {
51042 return context.graph().hasEntity(id);
51045 if (reselection.length) {
51046 context.enter(modeSelect(context, reselection).suppressMenu(true));
51048 context.enter(modeBrowse(context));
51053 function cancel() {
51055 context.enter(modeBrowse(context));
51059 function setActiveElements() {
51060 context.surface().selectAll(utilEntitySelector(activeIDs))
51061 .classed('active', true);
51065 var behavior = behaviorDrag()
51066 .delegate('g.node, g.point, g.midpoint')
51067 .surface(select('#map').node())
51069 .on('start', start)
51074 mode.enter = function() {
51075 context.install(hover);
51076 context.install(edit);
51079 .on('undone.drag-node', cancel);
51082 .on('drawn.drag-node', setActiveElements);
51084 setActiveElements();
51088 mode.exit = function() {
51089 context.ui().sidebar.hover.cancel();
51090 context.uninstall(hover);
51091 context.uninstall(edit);
51094 .on('undone.drag-node', null);
51097 .on('drawn.drag-node', null);
51100 .selectAll('.active')
51101 .classed('active', false);
51107 mode.selectedIDs = function(_) {
51108 if (!arguments.length) return selectedIDs;
51114 mode.behavior = behavior;
51120 function modeDrawArea(context, wayId, baseGraph) {
51129 mode.enter = function() {
51130 var way = context.entity(wayId);
51132 behavior = behaviorDrawWay(context, wayId, undefined, mode, baseGraph)
51133 .tail(t('modes.draw_area.tail'));
51135 var addNode = behavior.addNode;
51137 behavior.addNode = function(node) {
51138 var length = way.nodes.length,
51139 penultimate = length > 2 ? way.nodes[length - 2] : null;
51141 if (node.id === way.first() || node.id === penultimate) {
51148 context.install(behavior);
51152 mode.exit = function() {
51153 context.uninstall(behavior);
51157 mode.selectedIDs = function() {
51165 function modeDrawLine(context, wayId, baseGraph, affix) {
51174 mode.enter = function() {
51175 var way = context.entity(wayId),
51176 index = (affix === 'prefix') ? 0 : undefined,
51177 headId = (affix === 'prefix') ? way.first() : way.last();
51179 behavior = behaviorDrawWay(context, wayId, index, mode, baseGraph)
51180 .tail(t('modes.draw_line.tail'));
51182 var addNode = behavior.addNode;
51184 behavior.addNode = function(node) {
51185 if (node.id === headId) {
51192 context.install(behavior);
51196 mode.exit = function() {
51197 context.uninstall(behavior);
51201 mode.selectedIDs = function() {
51209 function operationCircularize(selectedIDs, context) {
51210 var entityId = selectedIDs[0],
51211 entity = context.entity(entityId),
51212 extent = entity.extent(context.graph()),
51213 geometry = context.geometry(entityId),
51214 action = actionCircularize(entityId, context.projection);
51217 var operation = function() {
51218 context.perform(action, t('operations.circularize.annotation.' + geometry));
51222 operation.available = function() {
51223 return selectedIDs.length === 1 &&
51224 entity.type === 'way' &&
51225 lodash.uniq(entity.nodes).length > 1;
51229 operation.disabled = function() {
51231 if (extent.percentContainedIn(context.extent()) < 0.8) {
51232 reason = 'too_large';
51233 } else if (context.hasHiddenConnections(entityId)) {
51234 reason = 'connected_to_hidden';
51236 return action.disabled(context.graph()) || reason;
51240 operation.tooltip = function() {
51241 var disable = operation.disabled();
51243 t('operations.circularize.' + disable) :
51244 t('operations.circularize.description.' + geometry);
51248 operation.id = 'circularize';
51249 operation.keys = [t('operations.circularize.key')];
51250 operation.title = t('operations.circularize.title');
51251 operation.behavior = behaviorOperation(context).which(operation);
51256 function operationContinue(selectedIDs, context) {
51257 var graph = context.graph(),
51258 entities = selectedIDs.map(function(id) { return graph.entity(id); }),
51259 geometries = lodash.extend({ line: [], vertex: [] },
51260 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); })),
51261 vertex = geometries.vertex[0];
51264 function candidateWays() {
51265 return graph.parentWays(vertex).filter(function(parent) {
51266 return parent.geometry(graph) === 'line' &&
51267 !parent.isClosed() &&
51268 parent.affix(vertex.id) &&
51269 (geometries.line.length === 0 || geometries.line[0] === parent);
51274 var operation = function() {
51275 var candidate = candidateWays()[0];
51277 modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
51282 operation.available = function() {
51283 return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
51284 !context.features().hasHiddenConnections(vertex, context.graph());
51288 operation.disabled = function() {
51289 var candidates = candidateWays();
51290 if (candidates.length === 0)
51291 return 'not_eligible';
51292 if (candidates.length > 1)
51297 operation.tooltip = function() {
51298 var disable = operation.disabled();
51300 t('operations.continue.' + disable) :
51301 t('operations.continue.description');
51305 operation.id = 'continue';
51306 operation.keys = [t('operations.continue.key')];
51307 operation.title = t('operations.continue.title');
51308 operation.behavior = behaviorOperation(context).which(operation);
51313 function operationDelete(selectedIDs, context) {
51314 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51315 action = actionDeleteMultiple(selectedIDs);
51318 var operation = function() {
51322 if (selectedIDs.length > 1) {
51323 annotation = t('operations.delete.annotation.multiple', { n: selectedIDs.length });
51326 var id = selectedIDs[0],
51327 entity = context.entity(id),
51328 geometry = context.geometry(id),
51329 parents = context.graph().parentWays(entity),
51330 parent = parents[0];
51332 annotation = t('operations.delete.annotation.' + geometry);
51334 // Select the next closest node in the way.
51335 if (geometry === 'vertex' && parent.nodes.length > 2) {
51336 var nodes = parent.nodes,
51337 i = nodes.indexOf(id);
51341 } else if (i === nodes.length - 1) {
51344 var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
51345 b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
51346 i = a < b ? i - 1 : i + 1;
51349 nextSelectedID = nodes[i];
51353 context.perform(action, annotation);
51355 if (nextSelectedID && context.hasEntity(nextSelectedID)) {
51357 modeSelect(context, [nextSelectedID]).follow(true).suppressMenu(true)
51360 context.enter(modeBrowse(context));
51366 operation.available = function() {
51371 operation.disabled = function() {
51373 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51374 reason = 'connected_to_hidden';
51375 } else if (lodash.some(selectedIDs, protectedMember)) {
51376 reason = 'part_of_relation';
51377 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51378 reason = 'incomplete_relation';
51382 function incompleteRelation(id) {
51383 var entity = context.entity(id);
51384 return entity.type === 'relation' && !entity.isComplete(context.graph());
51387 function protectedMember(id) {
51388 var entity = context.entity(id);
51389 if (entity.type !== 'way') return false;
51391 var parents = context.graph().parentRelations(entity);
51392 for (var i = 0; i < parents.length; i++) {
51393 var parent = parents[i],
51394 type = parent.tags.type,
51395 role = parent.memberById(id).role || 'outer';
51396 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
51406 operation.tooltip = function() {
51407 var disable = operation.disabled();
51409 t('operations.delete.' + disable + '.' + multi) :
51410 t('operations.delete.description' + '.' + multi);
51414 operation.id = 'delete';
51415 operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
51416 operation.title = t('operations.delete.title');
51417 operation.behavior = behaviorOperation(context).which(operation);
51422 function operationDisconnect(selectedIDs, context) {
51423 var vertices = lodash.filter(selectedIDs, function(entityId) {
51424 return context.geometry(entityId) === 'vertex';
51427 var entityId = vertices[0],
51428 action = actionDisconnect(entityId);
51430 if (selectedIDs.length > 1) {
51431 action.limitWays(lodash.without(selectedIDs, entityId));
51435 var operation = function() {
51436 context.perform(action, t('operations.disconnect.annotation'));
51440 operation.available = function() {
51441 return vertices.length === 1;
51445 operation.disabled = function() {
51447 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51448 reason = 'connected_to_hidden';
51450 return action.disabled(context.graph()) || reason;
51454 operation.tooltip = function() {
51455 var disable = operation.disabled();
51457 t('operations.disconnect.' + disable) :
51458 t('operations.disconnect.description');
51462 operation.id = 'disconnect';
51463 operation.keys = [t('operations.disconnect.key')];
51464 operation.title = t('operations.disconnect.title');
51465 operation.behavior = behaviorOperation(context).which(operation);
51470 function operationMerge(selectedIDs, context) {
51471 var join = actionJoin(selectedIDs),
51472 merge = actionMerge(selectedIDs),
51473 mergePolygon = actionMergePolygon(selectedIDs);
51475 var operation = function() {
51476 var annotation = t('operations.merge.annotation', {n: selectedIDs.length}),
51479 if (!join.disabled(context.graph())) {
51481 } else if (!merge.disabled(context.graph())) {
51484 action = mergePolygon;
51487 context.perform(action, annotation);
51488 var ids = selectedIDs.filter(function(id) {
51489 var entity = context.hasEntity(id);
51490 return entity && entity.type !== 'node';
51492 context.enter(modeSelect(context, ids).suppressMenu(true));
51496 operation.available = function() {
51497 return selectedIDs.length >= 2;
51501 operation.disabled = function() {
51502 return join.disabled(context.graph()) &&
51503 merge.disabled(context.graph()) &&
51504 mergePolygon.disabled(context.graph());
51508 operation.tooltip = function() {
51509 var j = join.disabled(context.graph()),
51510 m = merge.disabled(context.graph()),
51511 p = mergePolygon.disabled(context.graph());
51513 if (j === 'restriction' && m && p) {
51514 return t('operations.merge.restriction',
51515 { relation: context.presets().item('type/restriction').name() });
51518 if (p === 'incomplete_relation' && j && m) {
51519 return t('operations.merge.incomplete_relation');
51523 return t('operations.merge.' + j);
51526 return t('operations.merge.description');
51530 operation.id = 'merge';
51531 operation.keys = [t('operations.merge.key')];
51532 operation.title = t('operations.merge.title');
51533 operation.behavior = behaviorOperation(context).which(operation);
51538 function operationMove(selectedIDs, context) {
51539 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51540 extent = selectedIDs.reduce(function(extent, id) {
51541 return extent.extend(context.entity(id).extent(context.graph()));
51542 }, geoExtent$$1());
51545 var operation = function() {
51546 context.enter(modeMove$$1(context, selectedIDs));
51550 operation.available = function() {
51551 return selectedIDs.length > 1 ||
51552 context.entity(selectedIDs[0]).type !== 'node';
51556 operation.disabled = function() {
51558 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51559 reason = 'too_large';
51560 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51561 reason = 'connected_to_hidden';
51562 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51563 reason = 'incomplete_relation';
51567 function incompleteRelation(id) {
51568 var entity = context.entity(id);
51569 return entity.type === 'relation' && !entity.isComplete(context.graph());
51574 operation.tooltip = function() {
51575 var disable = operation.disabled();
51577 t('operations.move.' + disable + '.' + multi) :
51578 t('operations.move.description.' + multi);
51582 operation.id = 'move';
51583 operation.keys = [t('operations.move.key')];
51584 operation.title = t('operations.move.title');
51585 operation.behavior = behaviorOperation(context).which(operation);
51590 function operationOrthogonalize(selectedIDs, context) {
51591 var entityId = selectedIDs[0],
51592 entity = context.entity(entityId),
51593 extent = entity.extent(context.graph()),
51594 geometry = context.geometry(entityId),
51595 action = actionOrthogonalize(entityId, context.projection);
51598 var operation = function() {
51599 context.perform(action, t('operations.orthogonalize.annotation.' + geometry));
51603 operation.available = function() {
51604 return selectedIDs.length === 1 &&
51605 entity.type === 'way' &&
51606 entity.isClosed() &&
51607 lodash.uniq(entity.nodes).length > 2;
51611 operation.disabled = function() {
51613 if (extent.percentContainedIn(context.extent()) < 0.8) {
51614 reason = 'too_large';
51615 } else if (context.hasHiddenConnections(entityId)) {
51616 reason = 'connected_to_hidden';
51618 return action.disabled(context.graph()) || reason;
51622 operation.tooltip = function() {
51623 var disable = operation.disabled();
51625 t('operations.orthogonalize.' + disable) :
51626 t('operations.orthogonalize.description.' + geometry);
51630 operation.id = 'orthogonalize';
51631 operation.keys = [t('operations.orthogonalize.key')];
51632 operation.title = t('operations.orthogonalize.title');
51633 operation.behavior = behaviorOperation(context).which(operation);
51638 function operationReflectShort(selectedIDs, context) {
51639 return operationReflect(selectedIDs, context, 'short');
51643 function operationReflectLong(selectedIDs, context) {
51644 return operationReflect(selectedIDs, context, 'long');
51648 function operationReflect(selectedIDs, context, axis) {
51649 axis = axis || 'long';
51650 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51651 extent = selectedIDs.reduce(function(extent, id) {
51652 return extent.extend(context.entity(id).extent(context.graph()));
51653 }, geoExtent$$1());
51656 var operation = function() {
51657 var action = actionReflect(selectedIDs, context.projection)
51658 .useLongAxis(Boolean(axis === 'long'));
51659 context.perform(action, t('operations.reflect.annotation.' + axis + '.' + multi));
51663 operation.available = function() {
51664 return lodash.some(selectedIDs, hasArea);
51666 function hasArea(id) {
51667 var entity = context.entity(id);
51668 return (entity.type === 'way' && entity.isClosed()) ||
51669 (entity.type ==='relation' && entity.isMultipolygon());
51674 operation.disabled = function() {
51676 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51677 reason = 'too_large';
51678 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51679 reason = 'connected_to_hidden';
51680 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51681 reason = 'incomplete_relation';
51685 function incompleteRelation(id) {
51686 var entity = context.entity(id);
51687 return entity.type === 'relation' && !entity.isComplete(context.graph());
51692 operation.tooltip = function() {
51693 var disable = operation.disabled();
51695 t('operations.reflect.' + disable + '.' + multi) :
51696 t('operations.reflect.description.' + axis + '.' + multi);
51700 operation.id = 'reflect-' + axis;
51701 operation.keys = [t('operations.reflect.key.' + axis)];
51702 operation.title = t('operations.reflect.title');
51703 operation.behavior = behaviorOperation(context).which(operation);
51708 function operationReverse(selectedIDs, context) {
51709 var entityId = selectedIDs[0];
51711 var operation = function() {
51712 context.perform(actionReverse(entityId), t('operations.reverse.annotation'));
51716 operation.available = function() {
51717 return selectedIDs.length === 1 && context.geometry(entityId) === 'line';
51721 operation.disabled = function() {
51726 operation.tooltip = function() {
51727 return t('operations.reverse.description');
51731 operation.id = 'reverse';
51732 operation.keys = [t('operations.reverse.key')];
51733 operation.title = t('operations.reverse.title');
51734 operation.behavior = behaviorOperation(context).which(operation);
51739 function operationRotate(selectedIDs, context) {
51740 var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
51741 extent = selectedIDs.reduce(function(extent, id) {
51742 return extent.extend(context.entity(id).extent(context.graph()));
51743 }, geoExtent$$1());
51746 var operation = function() {
51747 context.enter(modeRotate$$1(context, selectedIDs));
51751 operation.available = function() {
51752 return lodash.some(selectedIDs, hasArea);
51754 function hasArea(id) {
51755 var entity = context.entity(id);
51756 return (entity.type === 'way' && entity.isClosed()) ||
51757 (entity.type ==='relation' && entity.isMultipolygon());
51762 operation.disabled = function() {
51764 if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
51765 reason = 'too_large';
51766 } else if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51767 reason = 'connected_to_hidden';
51768 } else if (lodash.some(selectedIDs, incompleteRelation)) {
51769 reason = 'incomplete_relation';
51773 function incompleteRelation(id) {
51774 var entity = context.entity(id);
51775 return entity.type === 'relation' && !entity.isComplete(context.graph());
51780 operation.tooltip = function() {
51781 var disable = operation.disabled();
51783 t('operations.rotate.' + disable + '.' + multi) :
51784 t('operations.rotate.description.' + multi);
51788 operation.id = 'rotate';
51789 operation.keys = [t('operations.rotate.key')];
51790 operation.title = t('operations.rotate.title');
51791 operation.behavior = behaviorOperation(context).which(operation);
51796 function operationSplit(selectedIDs, context) {
51797 var vertices = lodash.filter(selectedIDs, function(entityId) {
51798 return context.geometry(entityId) === 'vertex';
51801 var entityId = vertices[0],
51802 action = actionSplit(entityId);
51804 if (selectedIDs.length > 1) {
51805 action.limitWays(lodash.without(selectedIDs, entityId));
51809 var operation = function() {
51812 var ways = action.ways(context.graph());
51813 if (ways.length === 1) {
51814 annotation = t('operations.split.annotation.' + context.geometry(ways[0].id));
51816 annotation = t('operations.split.annotation.multiple', {n: ways.length});
51819 var difference = context.perform(action, annotation);
51820 context.enter(modeSelect(context, difference.extantIDs()));
51824 operation.available = function() {
51825 return vertices.length === 1;
51829 operation.disabled = function() {
51831 if (lodash.some(selectedIDs, context.hasHiddenConnections)) {
51832 reason = 'connected_to_hidden';
51834 return action.disabled(context.graph()) || reason;
51838 operation.tooltip = function() {
51839 var disable = operation.disabled();
51841 return t('operations.split.' + disable);
51844 var ways = action.ways(context.graph());
51845 if (ways.length === 1) {
51846 return t('operations.split.description.' + context.geometry(ways[0].id));
51848 return t('operations.split.description.multiple');
51853 operation.id = 'split';
51854 operation.keys = [t('operations.split.key')];
51855 operation.title = t('operations.split.title');
51856 operation.behavior = behaviorOperation(context).which(operation);
51861 function operationStraighten(selectedIDs, context) {
51862 var entityId = selectedIDs[0],
51863 action = actionStraighten(entityId, context.projection);
51866 function operation() {
51867 context.perform(action, t('operations.straighten.annotation'));
51871 operation.available = function() {
51872 var entity = context.entity(entityId);
51873 return selectedIDs.length === 1 &&
51874 entity.type === 'way' &&
51875 !entity.isClosed() &&
51876 lodash.uniq(entity.nodes).length > 2;
51880 operation.disabled = function() {
51882 if (context.hasHiddenConnections(entityId)) {
51883 reason = 'connected_to_hidden';
51885 return action.disabled(context.graph()) || reason;
51889 operation.tooltip = function() {
51890 var disable = operation.disabled();
51892 t('operations.straighten.' + disable) :
51893 t('operations.straighten.description');
51897 operation.id = 'straighten';
51898 operation.keys = [t('operations.straighten.key')];
51899 operation.title = t('operations.straighten.title');
51900 operation.behavior = behaviorOperation(context).which(operation);
51907 var Operations = Object.freeze({
51908 operationCircularize: operationCircularize,
51909 operationContinue: operationContinue,
51910 operationDelete: operationDelete,
51911 operationDisconnect: operationDisconnect,
51912 operationMerge: operationMerge,
51913 operationMove: operationMove,
51914 operationOrthogonalize: operationOrthogonalize,
51915 operationReflectShort: operationReflectShort,
51916 operationReflectLong: operationReflectLong,
51917 operationReverse: operationReverse,
51918 operationRotate: operationRotate,
51919 operationSplit: operationSplit,
51920 operationStraighten: operationStraighten
51923 function modeMove$$1(context, entityIDs, baseGraph) {
51929 var keybinding = d3keybinding('move'),
51931 behaviorEdit(context),
51932 operationCircularize(entityIDs, context).behavior,
51933 operationDelete(entityIDs, context).behavior,
51934 operationOrthogonalize(entityIDs, context).behavior,
51935 operationReflectLong(entityIDs, context).behavior,
51936 operationReflectShort(entityIDs, context).behavior,
51937 operationRotate(entityIDs, context).behavior
51939 annotation = entityIDs.length === 1 ?
51940 t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
51941 t('operations.move.annotation.multiple'),
51948 function vecSub(a, b) {
51949 return [a[0] - b[0], a[1] - b[1]];
51953 function edge(point, size) {
51954 var pad = [30, 100, 30, 100],
51958 if (point[0] > size[0] - pad[0])
51960 if (point[0] < pad[2])
51962 if (point[1] > size[1] - pad[1])
51964 if (point[1] < pad[3])
51967 if (x || y) return [x, y];
51972 function doMove(nudge) {
51973 nudge = nudge || [0, 0];
51976 if (prevGraph !== context.graph()) {
51978 origin = context.map().mouseCoordinates();
51979 fn = context.perform;
51981 fn = context.overwrite;
51984 var currMouse = context.mouse(),
51985 origMouse = context.projection(origin),
51986 delta = vecSub(vecSub(currMouse, origMouse), nudge);
51988 fn(actionMove(entityIDs, delta, context.projection, cache), annotation);
51989 prevGraph = context.graph();
51993 function startNudge(nudge) {
51994 if (nudgeInterval) window.clearInterval(nudgeInterval);
51995 nudgeInterval = window.setInterval(function() {
51996 context.pan(nudge);
52002 function stopNudge() {
52003 if (nudgeInterval) window.clearInterval(nudgeInterval);
52004 nudgeInterval = null;
52010 var nudge = edge(context.mouse(), context.map().dimensions());
52011 if (nudge) startNudge(nudge);
52016 function finish() {
52017 event.stopPropagation();
52018 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
52023 function cancel() {
52025 while (context.graph() !== baseGraph) context.pop();
52026 context.enter(modeBrowse(context));
52029 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
52035 function undone() {
52036 context.enter(modeBrowse(context));
52040 mode.enter = function() {
52041 origin = context.map().mouseCoordinates();
52045 behaviors.forEach(function(behavior) {
52046 context.install(behavior);
52050 .on('mousemove.move', move)
52051 .on('click.move', finish);
52054 .on('undone.move', undone);
52065 mode.exit = function() {
52068 behaviors.forEach(function(behavior) {
52069 context.uninstall(behavior);
52073 .on('mousemove.move', null)
52074 .on('click.move', null);
52077 .on('undone.move', null);
52086 function modeRotate$$1(context, entityIDs) {
52092 var keybinding = d3keybinding('rotate'),
52094 behaviorEdit(context),
52095 operationCircularize(entityIDs, context).behavior,
52096 operationDelete(entityIDs, context).behavior,
52097 operationMove(entityIDs, context).behavior,
52098 operationOrthogonalize(entityIDs, context).behavior,
52099 operationReflectLong(entityIDs, context).behavior,
52100 operationReflectShort(entityIDs, context).behavior
52102 annotation = entityIDs.length === 1 ?
52103 t('operations.rotate.annotation.' + context.geometry(entityIDs[0])) :
52104 t('operations.rotate.annotation.multiple'),
52111 function doRotate() {
52113 if (context.graph() !== prevGraph) {
52114 fn = context.perform;
52116 fn = context.replace;
52119 // projection changed, recalculate pivot
52120 var projection = context.projection;
52121 var currTransform = projection.transform();
52122 if (!prevTransform ||
52123 currTransform.k !== prevTransform.k ||
52124 currTransform.x !== prevTransform.x ||
52125 currTransform.y !== prevTransform.y) {
52127 var nodes = utilGetAllNodes(entityIDs, context.graph()),
52128 points = nodes.map(function(n) { return projection(n.loc); });
52130 pivot = d3polygonCentroid(d3polygonHull(points));
52131 prevAngle = undefined;
52135 var currMouse = context.mouse(),
52136 currAngle = Math.atan2(currMouse[1] - pivot[1], currMouse[0] - pivot[0]);
52138 if (typeof prevAngle === 'undefined') prevAngle = currAngle;
52139 var delta = currAngle - prevAngle;
52141 fn(actionRotate(entityIDs, pivot, delta, projection), annotation);
52143 prevTransform = currTransform;
52144 prevAngle = currAngle;
52145 prevGraph = context.graph();
52149 function finish() {
52150 event.stopPropagation();
52151 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
52155 function cancel() {
52157 context.enter(modeSelect(context, entityIDs).suppressMenu(true));
52161 function undone() {
52162 context.enter(modeBrowse(context));
52166 mode.enter = function() {
52167 behaviors.forEach(function(behavior) {
52168 context.install(behavior);
52172 .on('mousemove.rotate', doRotate)
52173 .on('click.rotate', finish);
52176 .on('undone.rotate', undone);
52187 mode.exit = function() {
52188 behaviors.forEach(function(behavior) {
52189 context.uninstall(behavior);
52193 .on('mousemove.rotate', null)
52194 .on('click.rotate', null);
52197 .on('undone.rotate', null);
52206 function modeSave$$1(context) {
52211 var ui = uiCommit(context)
52212 .on('cancel', cancel)
52216 function cancel() {
52217 context.enter(modeBrowse(context));
52221 function save(e, tryAgain) {
52222 function withChildNodes(ids, graph) {
52223 return lodash.uniq(lodash.reduce(ids, function(result, id) {
52224 var e = graph.entity(id);
52225 if (e.type === 'way') {
52227 var cn = graph.childNodes(e);
52228 result.push.apply(result, lodash.map(lodash.filter(cn, 'version'), 'id'));
52230 /* eslint-disable no-console */
52231 if (typeof console !== 'undefined') console.error(err);
52232 /* eslint-enable no-console */
52236 }, lodash.clone(ids)));
52239 var loading = uiLoading(context).message(t('save.uploading')).blocking(true),
52240 history = context.history(),
52241 origChanges = history.changes(actionDiscardTags(history.difference())),
52242 localGraph = context.graph(),
52243 remoteGraph = coreGraph$$1(history.base(), true),
52244 modified = lodash.filter(history.difference().summary(), {changeType: 'modified'}),
52245 toCheck = lodash.map(lodash.map(modified, 'entity'), 'id'),
52246 toLoad = withChildNodes(toCheck, localGraph),
52250 if (!tryAgain) history.perform(actionNoop()); // checkpoint
52251 context.container().call(loading);
52253 if (toCheck.length) {
52254 context.connection().loadMultiple(toLoad, loaded);
52260 // Reload modified entities into an alternate graph and check for conflicts..
52261 function loaded(err, result) {
52262 if (errors.length) return;
52266 msg: err.responseText,
52267 details: [ t('save.status_code', { code: err.status }) ]
52273 lodash.each(result.data, function(entity) {
52274 remoteGraph.replace(entity);
52275 toLoad = lodash.without(toLoad, entity.id);
52277 // Because loadMultiple doesn't download /full like loadEntity,
52278 // need to also load children that aren't already being checked..
52279 if (!entity.visible) return;
52280 if (entity.type === 'way') {
52281 loadMore.push.apply(loadMore,
52282 lodash.difference(entity.nodes, toCheck, toLoad, loadMore));
52283 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
52284 loadMore.push.apply(loadMore,
52285 lodash.difference(lodash.map(entity.members, 'id'), toCheck, toLoad, loadMore));
52289 if (loadMore.length) {
52290 toLoad.push.apply(toLoad, loadMore);
52291 context.connection().loadMultiple(loadMore, loaded);
52294 if (!toLoad.length) {
52301 function checkConflicts() {
52302 function choice(id, text$$1, action) {
52303 return { id: id, text: text$$1, action: function() { history.replace(action); } };
52305 function formatUser(d) {
52306 return '<a href="' + context.connection().userURL(d) + '" target="_blank">' + d + '</a>';
52308 function entityName(entity) {
52309 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
52312 function compareVersions(local$$1, remote) {
52313 if (local$$1.version !== remote.version) return false;
52315 if (local$$1.type === 'way') {
52316 var children = lodash.union(local$$1.nodes, remote.nodes);
52318 for (var i = 0; i < children.length; i++) {
52319 var a = localGraph.hasEntity(children[i]),
52320 b = remoteGraph.hasEntity(children[i]);
52322 if (a && b && a.version !== b.version) return false;
52329 lodash.each(toCheck, function(id) {
52330 var local$$1 = localGraph.entity(id),
52331 remote = remoteGraph.entity(id);
52333 if (compareVersions(local$$1, remote)) return;
52335 var action = actionMergeRemoteChanges,
52336 merge$$1 = action(id, localGraph, remoteGraph, formatUser);
52338 history.replace(merge$$1);
52340 var mergeConflicts = merge$$1.conflicts();
52341 if (!mergeConflicts.length) return; // merged safely
52343 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
52344 forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote'),
52345 keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore')),
52346 keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
52350 name: entityName(local$$1),
52351 details: mergeConflicts,
52354 choice(id, keepMine, forceLocal),
52355 choice(id, keepTheirs, forceRemote)
52364 function finalize() {
52365 if (conflicts.length) {
52366 conflicts.sort(function(a,b) { return b.id.localeCompare(a.id); });
52368 } else if (errors.length) {
52371 var changes = history.changes(actionDiscardTags(history.difference()));
52372 if (changes.modified.length || changes.created.length || changes.deleted.length) {
52373 context.connection().putChangeset(
52377 history.imageryUsed(),
52378 function(err, changeset_id) {
52381 msg: err.responseText,
52382 details: [ t('save.status_code', { code: err.status }) ]
52386 history.clearSaved();
52387 success(e, changeset_id);
52388 // Add delay to allow for postgres replication #1646 #2678
52389 window.setTimeout(function() {
52395 } else { // changes were insignificant or reverted by user
52404 function showConflicts() {
52405 var selection$$1 = context.container()
52406 .select('#sidebar')
52408 .attr('class','sidebar-component');
52412 selection$$1.call(uiConflicts(context)
52414 .on('download', function() {
52415 var data = JXON.stringify(context.connection().osmChangeJXON('CHANGEME', origChanges)),
52416 win = window.open('data:text/xml,' + encodeURIComponent(data), '_blank');
52419 .on('cancel', function() {
52421 selection$$1.remove();
52423 .on('save', function() {
52424 for (var i = 0; i < conflicts.length; i++) {
52425 if (conflicts[i].chosen === 1) { // user chose "keep theirs"
52426 var entity = context.hasEntity(conflicts[i].id);
52427 if (entity && entity.type === 'way') {
52428 var children = lodash.uniq(entity.nodes);
52429 for (var j = 0; j < children.length; j++) {
52430 history.replace(actionRevert(children[j]));
52433 history.replace(actionRevert(conflicts[i].id));
52437 selection$$1.remove();
52444 function showErrors() {
52445 var selection$$1 = uiConfirm(context.container());
52451 .select('.modal-section.header')
52453 .text(t('save.error'));
52455 addErrors(selection$$1, errors);
52456 selection$$1.okButton();
52460 function addErrors(selection$$1, data) {
52461 var message = selection$$1
52462 .select('.modal-section.message-text');
52464 var items = message
52465 .selectAll('.error-container')
52468 var enter = items.enter()
52470 .attr('class', 'error-container');
52474 .attr('class', 'error-description')
52476 .classed('hide-toggle', true)
52477 .text(function(d) { return d.msg || t('save.unknown_error_details'); })
52478 .on('click', function() {
52479 var error = select(this),
52480 detail = select(this.nextElementSibling),
52481 exp = error.classed('expanded');
52483 detail.style('display', exp ? 'none' : 'block');
52484 error.classed('expanded', !exp);
52486 event.preventDefault();
52489 var details = enter
52491 .attr('class', 'error-detail-container')
52492 .style('display', 'none');
52496 .attr('class', 'error-detail-list')
52498 .data(function(d) { return d.details || []; })
52501 .attr('class', 'error-detail-item')
52502 .text(function(d) { return d; });
52511 function success(e, changeset_id) {
52512 context.enter(modeBrowse(context)
52513 .sidebar(uiSuccess(context)
52518 .on('cancel', function() {
52519 context.ui().sidebar.hide();
52526 mode.enter = function() {
52528 context.ui().sidebar.show(ui);
52531 context.container().selectAll('#content')
52532 .attr('class', 'inactive');
52534 if (context.connection().authenticated()) {
52537 context.connection().authenticate(function(err) {
52548 mode.exit = function() {
52549 context.container().selectAll('#content')
52550 .attr('class', 'active');
52552 context.ui().sidebar.hide();
52558 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
52559 // For example, ⌘Z -> Ctrl+Z
52560 function uiCmd(code) {
52561 var detected = utilDetect();
52563 if (detected.os === 'mac') {
52567 if (detected.os === 'win') {
52568 if (code === '⌘⇧Z') return 'Ctrl+Y';
52580 for (var i = 0; i < code.length; i++) {
52581 if (code[i] in replacements) {
52582 result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
52594 function modeSelect(context, selectedIDs) {
52600 var keybinding = d3keybinding('select'),
52603 behaviorCopy(context),
52604 behaviorPaste(context),
52605 behaviorBreathe(context),
52606 behaviorHover(context),
52607 behaviorSelect(context),
52608 behaviorLasso(context),
52609 modeDragNode$$1(context).selectedIDs(selectedIDs).behavior
52613 newFeature = false,
52614 suppressMenu = false,
52618 var wrap = context.container()
52619 .select('.inspector-wrap');
52622 function singular() {
52623 if (selectedIDs.length === 1) {
52624 return context.hasEntity(selectedIDs[0]);
52629 function checkSelectedIDs() {
52631 if (Array.isArray(selectedIDs)) {
52632 ids = selectedIDs.filter(function(id) {
52633 return context.hasEntity(id);
52640 context.enter(modeBrowse(context));
52642 return !!ids.length;
52646 // find the common parent ways for nextVertex, previousVertex
52647 function commonParents() {
52648 var graph = context.graph(),
52649 commonParents = [];
52651 for (var i = 0; i < selectedIDs.length; i++) {
52652 var entity = context.hasEntity(selectedIDs[i]);
52653 if (!entity || entity.geometry(graph) !== 'vertex') {
52654 return []; // selection includes some not vertexes
52657 var currParents = lodash.map(graph.parentWays(entity), 'id');
52658 if (!commonParents.length) {
52659 commonParents = currParents;
52663 commonParents = lodash.intersection(commonParents, currParents);
52664 if (!commonParents.length) {
52669 return commonParents;
52673 function singularParent() {
52674 var parents = commonParents();
52675 if (!parents || parents.length === 0) {
52676 relatedParent = null;
52680 // relatedParent is used when we visit a vertex with multiple
52681 // parents, and we want to remember which parent line we started on.
52683 if (parents.length === 1) {
52684 relatedParent = parents[0]; // remember this parent for later
52685 return relatedParent;
52688 if (parents.indexOf(relatedParent) !== -1) {
52689 return relatedParent; // prefer the previously seen parent
52696 function closeMenu() {
52698 context.surface().call(radialMenu.close);
52703 function positionMenu() {
52704 if (suppressMenu || !radialMenu) { return; }
52706 var entity = singular();
52707 if (entity && context.geometry(entity.id) === 'relation') {
52708 suppressMenu = true;
52709 } else if (entity && entity.type === 'node') {
52710 radialMenu.center(context.projection(entity.loc));
52712 var point = context.mouse(),
52713 viewport = geoExtent$$1(context.projection.clipExtent()).polygon();
52714 if (geoPointInPolygon(point, viewport)) {
52715 radialMenu.center(point);
52717 suppressMenu = true;
52723 function showMenu() {
52725 if (!suppressMenu && radialMenu) {
52726 context.surface().call(radialMenu);
52731 function toggleMenu() {
52732 if (select('.radial-menu').empty()) {
52740 mode.selectedIDs = function() {
52741 return selectedIDs;
52745 mode.reselect = function() {
52746 if (!checkSelectedIDs()) return;
52748 var surfaceNode = context.surface().node();
52749 if (surfaceNode.focus) { // FF doesn't support it
52750 surfaceNode.focus();
52758 mode.newFeature = function(_) {
52759 if (!arguments.length) return newFeature;
52765 mode.suppressMenu = function(_) {
52766 if (!arguments.length) return suppressMenu;
52772 mode.follow = function(_) {
52773 if (!arguments.length) return follow;
52779 mode.enter = function() {
52781 function update() {
52783 checkSelectedIDs();
52787 function dblclick() {
52788 var target = select(event.target),
52789 datum = target.datum();
52791 if (datum instanceof osmWay && !target.classed('fill')) {
52792 var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
52793 prev = datum.nodes[choice.index - 1],
52794 next = datum.nodes[choice.index];
52797 actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
52798 t('operations.add.annotation.vertex')
52801 event.preventDefault();
52802 event.stopPropagation();
52803 } else if (datum.type === 'midpoint') {
52805 actionAddMidpoint({loc: datum.loc, edge: datum.edge}, osmNode()),
52806 t('operations.add.annotation.vertex'));
52808 event.preventDefault();
52809 event.stopPropagation();
52814 function selectElements(drawn) {
52815 if (!checkSelectedIDs()) return;
52817 var surface = context.surface(),
52818 entity = singular();
52820 if (entity && context.geometry(entity.id) === 'relation') {
52821 suppressMenu = true;
52825 surface.selectAll('.related')
52826 .classed('related', false);
52829 if (relatedParent) {
52830 surface.selectAll(utilEntitySelector([relatedParent]))
52831 .classed('related', true);
52834 var selection$$1 = context.surface()
52835 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
52837 if (selection$$1.empty()) {
52838 // Return to browse mode if selected DOM elements have
52839 // disappeared because the user moved them out of view..
52840 var source = event && event.type === 'zoom' && event.sourceEvent;
52841 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
52842 context.enter(modeBrowse(context));
52846 .classed('selected', true);
52852 if (!context.inIntro()) {
52853 context.enter(modeBrowse(context));
52858 function firstVertex() {
52859 event.preventDefault();
52860 var parent = singularParent();
52862 var way = context.entity(parent);
52864 modeSelect(context, [way.first()]).follow(true).suppressMenu(true)
52870 function lastVertex() {
52871 event.preventDefault();
52872 var parent = singularParent();
52874 var way = context.entity(parent);
52876 modeSelect(context, [way.last()]).follow(true).suppressMenu(true)
52882 function previousVertex() {
52883 event.preventDefault();
52884 var parent = singularParent();
52885 if (!parent) return;
52887 var way = context.entity(parent),
52888 length = way.nodes.length,
52889 curr = way.nodes.indexOf(selectedIDs[0]),
52894 } else if (way.isClosed()) {
52895 index = length - 2;
52898 if (index !== -1) {
52900 modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
52906 function nextVertex() {
52907 event.preventDefault();
52908 var parent = singularParent();
52909 if (!parent) return;
52911 var way = context.entity(parent),
52912 length = way.nodes.length,
52913 curr = way.nodes.indexOf(selectedIDs[0]),
52916 if (curr < length - 1) {
52918 } else if (way.isClosed()) {
52922 if (index !== -1) {
52924 modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
52930 function nextParent() {
52931 event.preventDefault();
52932 var parents = lodash.uniq(commonParents());
52933 if (!parents || parents.length < 2) return;
52935 var index = parents.indexOf(relatedParent);
52936 if (index < 0 || index > parents.length - 2) {
52937 relatedParent = parents[0];
52939 relatedParent = parents[index + 1];
52942 var surface = context.surface();
52943 surface.selectAll('.related')
52944 .classed('related', false);
52946 if (relatedParent) {
52947 surface.selectAll(utilEntitySelector([relatedParent]))
52948 .classed('related', true);
52953 if (!checkSelectedIDs()) return;
52955 var operations = lodash.without(values(Operations), operationDelete)
52956 .map(function(o) { return o(selectedIDs, context); })
52957 .filter(function(o) { return o.available(); });
52959 operations.unshift(operationDelete(selectedIDs, context));
52961 operations.forEach(function(operation) {
52962 if (operation.behavior) {
52963 behaviors.push(operation.behavior);
52967 behaviors.forEach(function(behavior) {
52968 context.install(behavior);
52972 .on(['[','pgup'], previousVertex)
52973 .on([']', 'pgdown'], nextVertex)
52974 .on([uiCmd('⌘['), 'home'], firstVertex)
52975 .on([uiCmd('⌘]'), 'end'], lastVertex)
52976 .on(['\\', 'pause'], nextParent)
52977 .on('⎋', esc, true)
52978 .on('space', toggleMenu);
52983 radialMenu = uiRadialMenu(context, operations);
52985 context.ui().sidebar
52986 .select(singular() ? singular().id : null, newFeature);
52989 .on('undone.select', update)
52990 .on('redone.select', update);
52993 .on('move.select', closeMenu)
52994 .on('drawn.select', selectElements);
52998 var show = event && !suppressMenu;
53005 var extent$$1 = geoExtent$$1(),
53006 graph = context.graph();
53007 selectedIDs.forEach(function(id) {
53008 var entity = context.entity(id);
53009 extent$$1._extend(entity.extent(graph));
53012 var loc = extent$$1.center();
53013 context.map().centerEase(loc);
53016 timeout$$1 = window.setTimeout(function() {
53022 .on('dblclick.select', dblclick);
53025 if (selectedIDs.length > 1) {
53026 var entities = uiSelectionList(context, selectedIDs);
53027 context.ui().sidebar.show(entities);
53032 mode.exit = function() {
53033 if (timeout$$1) window.clearTimeout(timeout$$1);
53035 if (inspector) wrap.call(inspector.close);
53037 behaviors.forEach(function(behavior) {
53038 context.uninstall(behavior);
53043 radialMenu = undefined;
53046 .on('undone.select', null)
53047 .on('redone.select', null);
53049 var surface = context.surface();
53052 .on('dblclick.select', null);
53055 .selectAll('.selected')
53056 .classed('selected', false);
53059 .selectAll('.related')
53060 .classed('related', false);
53062 context.map().on('drawn.select', null);
53063 context.ui().sidebar.hide();
53070 function uiAccount(context) {
53071 var connection = context.connection();
53074 function update(selection$$1) {
53075 if (!connection.authenticated()) {
53076 selection$$1.selectAll('#userLink, #logoutLink')
53077 .classed('hide', true);
53081 connection.userDetails(function(err, details) {
53082 var userLink = selection$$1.select('#userLink'),
53083 logoutLink = selection$$1.select('#logoutLink');
53086 logoutLink.html('');
53090 selection$$1.selectAll('#userLink, #logoutLink')
53091 .classed('hide', false);
53094 userLink.append('a')
53095 .attr('href', connection.userURL(details.display_name))
53096 .attr('target', '_blank');
53098 // Add thumbnail or dont
53099 if (details.image_url) {
53100 userLink.append('img')
53101 .attr('class', 'icon pre-text user-icon')
53102 .attr('src', details.image_url);
53105 .call(svgIcon('#icon-avatar', 'pre-text light'));
53109 userLink.append('span')
53110 .attr('class', 'label')
53111 .text(details.display_name);
53113 logoutLink.append('a')
53114 .attr('class', 'logout')
53117 .on('click.logout', function() {
53118 event.preventDefault();
53119 connection.logout();
53125 return function(selection$$1) {
53126 selection$$1.append('li')
53127 .attr('id', 'logoutLink')
53128 .classed('hide', true);
53130 selection$$1.append('li')
53131 .attr('id', 'userLink')
53132 .classed('hide', true);
53135 .on('change.account', function() { update(selection$$1); });
53137 update(selection$$1);
53141 function uiAttribution(context) {
53145 function attribution(data, klass) {
53146 var div = selection$$1.selectAll('.' + klass)
53151 .attr('class', klass)
53155 var background = div.selectAll('.attribution')
53156 .data(data, function(d) { return d.name(); });
53161 background = background.enter()
53163 .attr('class', 'attribution')
53164 .each(function(d) {
53165 if (d.terms_html) {
53167 .html(d.terms_html);
53171 var source = d.terms_text || d.id || d.name();
53174 source = '<img class="source-image" src="' + context.imagePath(d.logo) + '">';
53180 .attr('href', d.terms_url)
53181 .attr('target', '_blank')
53188 .merge(background);
53191 var copyright = background.selectAll('.copyright-notice')
53192 .data(function(d) {
53193 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
53194 return notice ? [notice] : [];
53200 copyright = copyright.enter()
53202 .attr('class', 'copyright-notice')
53210 function update() {
53211 attribution([context.background().baseLayerSource()], 'base-layer-attribution');
53212 attribution(context.background().overlayLayerSources().filter(function (s) {
53213 return s.validZoom(context.map().zoom());
53214 }), 'overlay-layer-attribution');
53218 return function(select$$1) {
53219 selection$$1 = select$$1;
53221 context.background()
53222 .on('change.attribution', update);
53225 .on('move.attribution', lodash.throttle(update, 400, {leading: false}));
53231 function rendererBackgroundSource(data) {
53232 var source = lodash.clone(data),
53234 name = source.name,
53235 best = !!source.best;
53237 source.scaleExtent = data.scaleExtent || [0, 20];
53238 source.overzoom = data.overzoom !== false;
53241 source.offset = function(_) {
53242 if (!arguments.length) return offset;
53248 source.nudge = function(_, zoomlevel) {
53249 offset[0] += _[0] / Math.pow(2, zoomlevel);
53250 offset[1] += _[1] / Math.pow(2, zoomlevel);
53255 source.name = function() {
53260 source.best = function() {
53265 source.area = function() {
53266 if (!data.polygon) return Number.MAX_VALUE; // worldwide
53267 var area$$1 = area({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
53268 return isNaN(area$$1) ? 0 : area$$1;
53272 source.imageryUsed = function() {
53273 return name || source.id;
53277 source.url = function(coord) {
53278 return data.template
53279 .replace('{x}', coord[0])
53280 .replace('{y}', coord[1])
53281 // TMS-flipped y coordinate
53282 .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
53283 .replace(/\{z(oom)?\}/, coord[2])
53284 .replace(/\{switch:([^}]+)\}/, function(s, r) {
53285 var subdomains = r.split(',');
53286 return subdomains[(coord[0] + coord[1]) % subdomains.length];
53288 .replace('{u}', function() {
53290 for (var zoom$$1 = coord[2]; zoom$$1 > 0; zoom$$1--) {
53292 var mask = 1 << (zoom$$1 - 1);
53293 if ((coord[0] & mask) !== 0) b++;
53294 if ((coord[1] & mask) !== 0) b += 2;
53302 source.intersects = function(extent$$1) {
53303 extent$$1 = extent$$1.polygon();
53304 return !data.polygon || data.polygon.some(function(polygon) {
53305 return geoPolygonIntersectsPolygon(polygon, extent$$1, true);
53310 source.validZoom = function(z) {
53311 return source.scaleExtent[0] <= z &&
53312 (source.overzoom || source.scaleExtent[1] > z);
53316 source.isLocatorOverlay = function() {
53317 return source.id === 'mapbox_locator_overlay';
53321 source.copyrightNotices = function() {};
53328 rendererBackgroundSource.Bing = function(data, dispatch$$1) {
53329 // http://msdn.microsoft.com/en-us/library/ff701716.aspx
53330 // http://msdn.microsoft.com/en-us/library/ff701701.aspx
53332 data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
53334 var bing = rendererBackgroundSource(data),
53335 key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
53336 url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
53337 key + '&jsonp={callback}',
53340 jsonpRequest(url, function(json$$1) {
53341 providers = json$$1.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
53343 attribution: provider.attribution,
53344 areas: provider.coverageAreas.map(function(area$$1) {
53346 zoom: [area$$1.zoomMin, area$$1.zoomMax],
53347 extent: geoExtent$$1([area$$1.bbox[1], area$$1.bbox[0]], [area$$1.bbox[3], area$$1.bbox[2]])
53352 dispatch$$1.call('change');
53355 bing.copyrightNotices = function(zoom$$1, extent$$1) {
53356 zoom$$1 = Math.min(zoom$$1, 21);
53357 return providers.filter(function(provider) {
53358 return lodash.some(provider.areas, function(area$$1) {
53359 return extent$$1.intersects(area$$1.extent) &&
53360 area$$1.zoom[0] <= zoom$$1 &&
53361 area$$1.zoom[1] >= zoom$$1;
53363 }).map(function(provider) {
53364 return provider.attribution;
53368 bing.logo = 'bing_maps.png';
53369 bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
53375 rendererBackgroundSource.None = function() {
53376 var source = rendererBackgroundSource({ id: 'none', template: '' });
53378 source.name = function() {
53379 return t('background.none');
53382 source.imageryUsed = function() {
53386 source.area = function() {
53387 return -1; // sources in background pane are sorted by area
53394 rendererBackgroundSource.Custom = function(template) {
53395 var source = rendererBackgroundSource({ id: 'custom', template: template });
53397 source.name = function() {
53398 return t('background.custom');
53401 source.imageryUsed = function() {
53402 return 'Custom (' + template + ')';
53405 source.area = function() {
53406 return -2; // sources in background pane are sorted by area
53412 function rendererTileLayer(context) {
53413 var tileSize = 256,
53414 tile = d3geoTile(),
53419 transformProp = utilPrefixCSSProperty('Transform'),
53420 source = rendererBackgroundSource.None();
53423 // blacklist overlay tiles around Null Island..
53424 function nearNullIsland(x, y, z) {
53426 var center = Math.pow(2, z - 1),
53427 width = Math.pow(2, z - 6),
53428 min$$1 = center - (width / 2),
53429 max$$1 = center + (width / 2) - 1;
53430 return x >= min$$1 && x <= max$$1 && y >= min$$1 && y <= max$$1;
53436 function tileSizeAtZoom(d, z) {
53437 var epsilon = 0.002;
53438 return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + epsilon;
53442 function atZoom(t, distance) {
53443 var power = Math.pow(2, distance);
53445 Math.floor(t[0] * power),
53446 Math.floor(t[1] * power),
53451 function lookUp(d) {
53452 for (var up = -1; up > -d[2]; up--) {
53453 var tile = atZoom(d, up);
53454 if (cache[source.url(tile)] !== false) {
53461 function uniqueBy(a, n) {
53462 var o = [], seen = {};
53463 for (var i = 0; i < a.length; i++) {
53464 if (seen[a[i][n]] === undefined) {
53466 seen[a[i][n]] = true;
53473 function addSource(d) {
53474 d.push(source.url(d));
53479 // Update tiles based on current state of `projection`.
53480 function background(selection$$1) {
53481 tile.scale(projection.scale() * 2 * Math.PI)
53482 .translate(projection.translate());
53485 projection.scale() * Math.PI - projection.translate()[0],
53486 projection.scale() * Math.PI - projection.translate()[1]];
53488 z = Math.max(Math.log(projection.scale() * 2 * Math.PI) / Math.log(2) - 8, 0);
53490 render(selection$$1);
53494 // Derive the tiles onscreen, remove those offscreen and position them.
53495 // Important that this part not depend on `projection` because it's
53496 // rentered when tiles load/error (see #644).
53497 function render(selection$$1) {
53499 var showDebug = context.getDebug('tile') && !source.overlay;
53501 if (source.validZoom(z)) {
53502 tile().forEach(function(d) {
53504 if (d[3] === '') return;
53505 if (typeof d[3] !== 'string') return; // Workaround for chrome crash https://github.com/openstreetmap/iD/issues/2295
53507 if (cache[d[3]] === false && lookUp(d)) {
53508 requests.push(addSource(lookUp(d)));
53512 requests = uniqueBy(requests, 3).filter(function(r) {
53513 if (!!source.overlay && nearNullIsland(r[0], r[1], r[2])) {
53516 // don't re-request tiles which have failed in the past
53517 return cache[r[3]] !== false;
53521 var pixelOffset = [
53522 source.offset()[0] * Math.pow(2, z),
53523 source.offset()[1] * Math.pow(2, z)
53527 cache[d[3]] = true;
53531 .classed('tile-loaded', true);
53532 render(selection$$1);
53535 function error(d) {
53536 cache[d[3]] = false;
53541 render(selection$$1);
53544 function imageTransform(d) {
53545 var _ts = tileSize * Math.pow(2, z - d[2]);
53546 var scale = tileSizeAtZoom(d, z);
53547 return 'translate(' +
53548 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0]) + 'px,' +
53549 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1]) + 'px)' +
53550 'scale(' + scale + ',' + scale + ')';
53553 function debugTransform(d) {
53554 var _ts = tileSize * Math.pow(2, z - d[2]);
53555 var scale = tileSizeAtZoom(d, z);
53556 return 'translate(' +
53557 ((d[0] * _ts) - tileOrigin[0] + pixelOffset[0] + scale * (tileSize / 4)) + 'px,' +
53558 ((d[1] * _ts) - tileOrigin[1] + pixelOffset[1] + scale * (tileSize / 2)) + 'px)';
53562 var image = selection$$1.selectAll('img')
53563 .data(requests, function(d) { return d[3]; });
53566 .style(transformProp, imageTransform)
53567 .classed('tile-removing', true)
53569 var tile = select(this);
53570 window.setTimeout(function() {
53571 if (tile.classed('tile-removing')) {
53579 .attr('class', 'tile')
53580 .attr('src', function(d) { return d[3]; })
53581 .on('error', error)
53584 .style(transformProp, imageTransform)
53585 .classed('tile-debug', showDebug)
53586 .classed('tile-removing', false);
53589 var debug = selection$$1.selectAll('.tile-label-debug')
53590 .data(showDebug ? requests : [], function(d) { return d[3]; });
53597 .attr('class', 'tile-label-debug')
53599 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; })
53600 .style(transformProp, debugTransform);
53604 background.projection = function(_) {
53605 if (!arguments.length) return projection;
53611 background.dimensions = function(_) {
53612 if (!arguments.length) return tile.size();
53618 background.source = function(_) {
53619 if (!arguments.length) return source;
53622 tile.scaleExtent(source.scaleExtent);
53630 function rendererBackground(context) {
53631 var dispatch$$1 = dispatch('change'),
53632 baseLayer = rendererTileLayer(context).projection(context.projection),
53633 overlayLayers = [],
53637 function findSource(id) {
53638 return lodash.find(backgroundSources, function(d) {
53639 return d.id && d.id === id;
53644 function background(selection$$1) {
53645 var base = selection$$1.selectAll('.layer-background')
53649 .insert('div', '.layer-data')
53650 .attr('class', 'layer layer-background')
53654 var overlays = selection$$1.selectAll('.layer-overlay')
53655 .data(overlayLayers, function(d) { return d.source().name(); });
53661 .insert('div', '.layer-data')
53662 .attr('class', 'layer layer-overlay')
53664 .each(function(layer) { select(this).call(layer); });
53668 background.updateImagery = function() {
53669 var b = background.baseLayerSource(),
53671 .filter(function (d) { return !d.source().isLocatorOverlay(); })
53672 .map(function (d) { return d.source().id; })
53674 meters = geoOffsetToMeters(b.offset()),
53676 x = +meters[0].toFixed(2),
53677 y = +meters[1].toFixed(2),
53678 q = utilStringQs(window.location.hash.substring(1));
53681 if (id === 'custom') {
53682 id = 'custom:' + b.template;
53688 delete q.background;
53697 if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
53698 q.offset = x + ',' + y;
53703 window.location.replace('#' + utilQsString(q, true));
53705 var imageryUsed = [b.imageryUsed()];
53708 .filter(function (d) { return !d.source().isLocatorOverlay(); })
53709 .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
53711 var gpx = context.layers().layer('gpx');
53712 if (gpx && gpx.enabled() && gpx.hasGpx()) {
53713 imageryUsed.push('Local GPX');
53716 var mapillary_images = context.layers().layer('mapillary-images');
53717 if (mapillary_images && mapillary_images.enabled()) {
53718 imageryUsed.push('Mapillary Images');
53721 var mapillary_signs = context.layers().layer('mapillary-signs');
53722 if (mapillary_signs && mapillary_signs.enabled()) {
53723 imageryUsed.push('Mapillary Signs');
53726 context.history().imageryUsed(imageryUsed);
53730 background.sources = function(extent$$1) {
53731 return backgroundSources.filter(function(source) {
53732 return source.intersects(extent$$1);
53737 background.dimensions = function(_) {
53739 baseLayer.dimensions(_);
53741 overlayLayers.forEach(function(layer) {
53742 layer.dimensions(_);
53747 background.baseLayerSource = function(d) {
53748 if (!arguments.length) return baseLayer.source();
53750 // test source against OSM imagery blacklists..
53751 var blacklists = context.connection().imageryBlacklists();
53757 for (i = 0; i < blacklists.length; i++) {
53759 regex = new RegExp(blacklists[i]);
53760 fail = regex.test(d.template);
53768 // ensure at least one test was run.
53770 regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
53771 fail = regex.test(d.template);
53774 baseLayer.source(!fail ? d : rendererBackgroundSource.None());
53775 dispatch$$1.call('change');
53776 background.updateImagery();
53781 background.bing = function() {
53782 background.baseLayerSource(findSource('Bing'));
53786 background.showsLayer = function(d) {
53787 return d.id === baseLayer.source().id ||
53788 overlayLayers.some(function(layer) { return d.id === layer.source().id; });
53792 background.overlayLayerSources = function() {
53793 return overlayLayers.map(function (l) { return l.source(); });
53797 background.toggleOverlayLayer = function(d) {
53800 for (var i = 0; i < overlayLayers.length; i++) {
53801 layer = overlayLayers[i];
53802 if (layer.source() === d) {
53803 overlayLayers.splice(i, 1);
53804 dispatch$$1.call('change');
53805 background.updateImagery();
53810 layer = rendererTileLayer(context)
53812 .projection(context.projection)
53813 .dimensions(baseLayer.dimensions());
53815 overlayLayers.push(layer);
53816 dispatch$$1.call('change');
53817 background.updateImagery();
53821 background.nudge = function(d, zoom$$1) {
53822 baseLayer.source().nudge(d, zoom$$1);
53823 dispatch$$1.call('change');
53824 background.updateImagery();
53829 background.offset = function(d) {
53830 if (!arguments.length) return baseLayer.source().offset();
53831 baseLayer.source().offset(d);
53832 dispatch$$1.call('change');
53833 background.updateImagery();
53838 background.init = function() {
53839 function parseMap(qmap) {
53840 if (!qmap) return false;
53841 var args = qmap.split('/').map(Number);
53842 if (args.length < 3 || args.some(isNaN)) return false;
53843 return geoExtent$$1([args[2], args[1]]);
53846 var dataImagery = data.imagery || [],
53847 q = utilStringQs(window.location.hash.substring(1)),
53848 chosen = q.background || q.layer,
53849 extent$$1 = parseMap(q.map),
53852 backgroundSources = dataImagery.map(function(source) {
53853 if (source.type === 'bing') {
53854 return rendererBackgroundSource.Bing(source, dispatch$$1);
53856 return rendererBackgroundSource(source);
53860 backgroundSources.unshift(rendererBackgroundSource.None());
53862 if (!chosen && extent$$1) {
53863 best = lodash.find(this.sources(extent$$1), function(s) { return s.best(); });
53866 if (chosen && chosen.indexOf('custom:') === 0) {
53867 background.baseLayerSource(rendererBackgroundSource.Custom(chosen.replace(/^custom:/, '')));
53869 background.baseLayerSource(findSource(chosen) || best || findSource('Bing') || backgroundSources[1] || backgroundSources[0]);
53872 var locator = lodash.find(backgroundSources, function(d) {
53873 return d.overlay && d.default;
53877 background.toggleOverlayLayer(locator);
53880 var overlays = (q.overlays || '').split(',');
53881 overlays.forEach(function(overlay) {
53882 overlay = findSource(overlay);
53884 background.toggleOverlayLayer(overlay);
53889 var gpx = context.layers().layer('gpx');
53896 var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
53897 return !isNaN(n) && n;
53900 if (offset.length === 2) {
53901 background.offset(geoMetersToOffset(offset));
53907 return utilRebind(background, dispatch$$1, 'on');
53910 function rendererFeatures(context) {
53911 var traffic_roads = {
53913 'motorway_link': true,
53915 'trunk_link': true,
53917 'primary_link': true,
53919 'secondary_link': true,
53921 'tertiary_link': true,
53922 'residential': true,
53923 'unclassified': true,
53924 'living_street': true
53927 var service_roads = {
53939 'pedestrian': true,
53943 var past_futures = {
53945 'construction': true,
53947 'dismantled': true,
53950 'demolished': true,
53951 'obliterated': true
53954 var dispatch$$1 = dispatch('change', 'redraw'),
53963 function update() {
53964 _hidden = features.hidden();
53965 dispatch$$1.call('change');
53966 dispatch$$1.call('redraw');
53970 function defineFeature(k, filter, max$$1) {
53974 enabled: true, // whether the user wants it enabled..
53976 currentMax: (max$$1 || Infinity),
53977 defaultMax: (max$$1 || Infinity),
53978 enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
53979 disable: function() { this.enabled = false; this.currentMax = 0; },
53980 hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
53981 autoHidden: function() { return this.hidden() && this.currentMax > 0; }
53986 defineFeature('points', function isPoint(entity, resolver, geometry) {
53987 return geometry === 'point';
53990 defineFeature('traffic_roads', function isTrafficRoad(entity) {
53991 return traffic_roads[entity.tags.highway];
53994 defineFeature('service_roads', function isServiceRoad(entity) {
53995 return service_roads[entity.tags.highway];
53998 defineFeature('paths', function isPath(entity) {
53999 return paths[entity.tags.highway];
54002 defineFeature('buildings', function isBuilding(entity) {
54004 !!entity.tags['building:part'] ||
54005 (!!entity.tags.building && entity.tags.building !== 'no') ||
54006 entity.tags.amenity === 'shelter' ||
54007 entity.tags.parking === 'multi-storey' ||
54008 entity.tags.parking === 'sheds' ||
54009 entity.tags.parking === 'carports' ||
54010 entity.tags.parking === 'garage_boxes'
54014 defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
54015 return geometry === 'area' &&
54016 !_features.buildings.filter(entity) &&
54017 !_features.water.filter(entity);
54020 defineFeature('boundaries', function isBoundary(entity) {
54021 return !!entity.tags.boundary;
54024 defineFeature('water', function isWater(entity) {
54026 !!entity.tags.waterway ||
54027 entity.tags.natural === 'water' ||
54028 entity.tags.natural === 'coastline' ||
54029 entity.tags.natural === 'bay' ||
54030 entity.tags.landuse === 'pond' ||
54031 entity.tags.landuse === 'basin' ||
54032 entity.tags.landuse === 'reservoir' ||
54033 entity.tags.landuse === 'salt_pond'
54037 defineFeature('rail', function isRail(entity) {
54039 !!entity.tags.railway ||
54040 entity.tags.landuse === 'railway'
54042 traffic_roads[entity.tags.highway] ||
54043 service_roads[entity.tags.highway] ||
54044 paths[entity.tags.highway]
54048 defineFeature('power', function isPower(entity) {
54049 return !!entity.tags.power;
54052 // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
54053 defineFeature('past_future', function isPastFuture(entity) {
54055 traffic_roads[entity.tags.highway] ||
54056 service_roads[entity.tags.highway] ||
54057 paths[entity.tags.highway]
54058 ) { return false; }
54060 var strings = Object.keys(entity.tags);
54062 for (var i = 0; i < strings.length; i++) {
54063 var s = strings[i];
54064 if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
54069 // Lines or areas that don't match another feature filter.
54070 // IMPORTANT: The 'others' feature must be the last one defined,
54071 // so that code in getMatches can skip this test if `hasMatch = true`
54072 defineFeature('others', function isOther(entity, resolver, geometry) {
54073 return (geometry === 'line' || geometry === 'area');
54077 function features() {}
54080 features.features = function() {
54085 features.keys = function() {
54090 features.enabled = function(k) {
54091 if (!arguments.length) {
54092 return _keys.filter(function(k) { return _features[k].enabled; });
54094 return _features[k] && _features[k].enabled;
54098 features.disabled = function(k) {
54099 if (!arguments.length) {
54100 return _keys.filter(function(k) { return !_features[k].enabled; });
54102 return _features[k] && !_features[k].enabled;
54106 features.hidden = function(k) {
54107 if (!arguments.length) {
54108 return _keys.filter(function(k) { return _features[k].hidden(); });
54110 return _features[k] && _features[k].hidden();
54114 features.autoHidden = function(k) {
54115 if (!arguments.length) {
54116 return _keys.filter(function(k) { return _features[k].autoHidden(); });
54118 return _features[k] && _features[k].autoHidden();
54122 features.enable = function(k) {
54123 if (_features[k] && !_features[k].enabled) {
54124 _features[k].enable();
54130 features.disable = function(k) {
54131 if (_features[k] && _features[k].enabled) {
54132 _features[k].disable();
54138 features.toggle = function(k) {
54139 if (_features[k]) {
54140 (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
54146 features.resetStats = function() {
54147 for (var i = 0; i < _keys.length; i++) {
54148 _features[_keys[i]].count = 0;
54150 dispatch$$1.call('change');
54154 features.gatherStats = function(d, resolver, dimensions) {
54155 var needsRedraw = false,
54156 type = lodash.groupBy(d, function(ent) { return ent.type; }),
54157 entities = [].concat(type.relation || [], type.way || [], type.node || []),
54158 currHidden, geometry, matches, i, j;
54160 for (i = 0; i < _keys.length; i++) {
54161 _features[_keys[i]].count = 0;
54164 // adjust the threshold for point/building culling based on viewport size..
54165 // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
54166 _cullFactor = dimensions[0] * dimensions[1] / 1000000;
54168 for (i = 0; i < entities.length; i++) {
54169 geometry = entities[i].geometry(resolver);
54170 if (!(geometry === 'vertex' || geometry === 'relation')) {
54171 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
54172 for (j = 0; j < matches.length; j++) {
54173 _features[matches[j]].count++;
54178 currHidden = features.hidden();
54179 if (currHidden !== _hidden) {
54180 _hidden = currHidden;
54181 needsRedraw = true;
54182 dispatch$$1.call('change');
54185 return needsRedraw;
54189 features.stats = function() {
54190 for (var i = 0; i < _keys.length; i++) {
54191 _stats[_keys[i]] = _features[_keys[i]].count;
54198 features.clear = function(d) {
54199 for (var i = 0; i < d.length; i++) {
54200 features.clearEntity(d[i]);
54205 features.clearEntity = function(entity) {
54206 delete _cache[osmEntity$$1.key(entity)];
54210 features.reset = function() {
54215 features.getMatches = function(entity, resolver, geometry) {
54216 if (geometry === 'vertex' || geometry === 'relation') return {};
54218 var ent = osmEntity$$1.key(entity);
54219 if (!_cache[ent]) {
54223 if (!_cache[ent].matches) {
54227 for (var i = 0; i < _keys.length; i++) {
54228 if (_keys[i] === 'others') {
54229 if (hasMatch) continue;
54231 // Multipolygon members:
54233 // 1. is a way that hasn't matched other 'interesting' feature rules,
54234 // 2. and it belongs to a single parent multipolygon relation
54235 // ...then match whatever feature rules the parent multipolygon has matched.
54236 // see #2548, #2887
54239 // For this to work, getMatches must be called on relations before ways.
54241 if (entity.type === 'way') {
54242 var parents = features.getParents(entity, resolver, geometry);
54243 if (parents.length === 1 && parents[0].isMultipolygon()) {
54244 var pkey = osmEntity$$1.key(parents[0]);
54245 if (_cache[pkey] && _cache[pkey].matches) {
54246 matches = lodash.clone(_cache[pkey].matches);
54253 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
54254 matches[_keys[i]] = hasMatch = true;
54257 _cache[ent].matches = matches;
54260 return _cache[ent].matches;
54264 features.getParents = function(entity, resolver, geometry) {
54265 if (geometry === 'point') return [];
54267 var ent = osmEntity$$1.key(entity);
54268 if (!_cache[ent]) {
54272 if (!_cache[ent].parents) {
54274 if (geometry === 'vertex') {
54275 parents = resolver.parentWays(entity);
54276 } else { // 'line', 'area', 'relation'
54277 parents = resolver.parentRelations(entity);
54279 _cache[ent].parents = parents;
54281 return _cache[ent].parents;
54285 features.isHiddenFeature = function(entity, resolver, geometry) {
54286 if (!_hidden.length) return false;
54287 if (!entity.version) return false;
54289 var matches = features.getMatches(entity, resolver, geometry);
54291 for (var i = 0; i < _hidden.length; i++) {
54292 if (matches[_hidden[i]]) return true;
54298 features.isHiddenChild = function(entity, resolver, geometry) {
54299 if (!_hidden.length) return false;
54300 if (!entity.version || geometry === 'point') return false;
54302 var parents = features.getParents(entity, resolver, geometry);
54303 if (!parents.length) return false;
54305 for (var i = 0; i < parents.length; i++) {
54306 if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
54314 features.hasHiddenConnections = function(entity, resolver) {
54315 if (!_hidden.length) return false;
54316 var childNodes, connections;
54318 if (entity.type === 'midpoint') {
54319 childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
54322 childNodes = entity.nodes ? resolver.childNodes(entity) : [];
54323 connections = features.getParents(entity, resolver, entity.geometry(resolver));
54326 // gather ways connected to child nodes..
54327 connections = lodash.reduce(childNodes, function(result, e) {
54328 return resolver.isShared(e) ? lodash.union(result, resolver.parentWays(e)) : result;
54331 return connections.length ? lodash.some(connections, function(e) {
54332 return features.isHidden(e, resolver, e.geometry(resolver));
54337 features.isHidden = function(entity, resolver, geometry) {
54338 if (!_hidden.length) return false;
54339 if (!entity.version) return false;
54341 var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
54342 return fn(entity, resolver, geometry);
54346 features.filter = function(d, resolver) {
54347 if (!_hidden.length) return d;
54350 for (var i = 0; i < d.length; i++) {
54352 if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
54353 result.push(entity);
54360 return utilRebind(features, dispatch$$1, 'on');
54363 function utilBindOnce(target, type, listener, capture) {
54364 var typeOnce = type + '.once';
54366 target.on(typeOnce, null);
54367 listener.apply(this, arguments);
54369 target.on(typeOnce, one, capture);
54373 function rendererMap(context) {
54375 var dimensions = [1, 1],
54376 dispatch$$1 = dispatch('move', 'drawn'),
54377 projection = context.projection,
54378 dblclickEnabled = true,
54379 redrawEnabled = true,
54380 transformStart = projection.transform(),
54381 transformed = false,
54383 drawLayers = svgLayers(projection, context),
54384 drawPoints = svgPoints$$1(projection, context),
54385 drawVertices = svgVertices$$1(projection, context),
54386 drawLines = svgLines$$1(projection),
54387 drawAreas = svgAreas$$1(projection, context),
54388 drawMidpoints = svgMidpoints$$1(projection, context),
54389 drawLabels = svgLabels(projection, context),
54390 supersurface = select(null),
54391 wrapper = select(null),
54392 surface = select(null),
54396 var zoom$$1 = zoom$1()
54397 .scaleExtent([ztok(2), ztok(24)])
54398 .interpolate(value$1)
54399 .filter(zoomEventFilter)
54400 .on('zoom', zoomPan);
54402 var _selection = select(null);
54405 function map$$1(selection$$1) {
54407 _selection = selection$$1;
54410 .on('change.map', immediateRedraw);
54412 context.connection()
54413 .on('change.map', immediateRedraw);
54416 .on('change.map', immediateRedraw)
54417 .on('undone.context redone.context', function(stack$$1) {
54418 var followSelected = false;
54419 if (Array.isArray(stack$$1.selectedIDs)) {
54420 followSelected = (stack$$1.selectedIDs.length === 1 && stack$$1.selectedIDs[0][0] === 'n');
54422 modeSelect(context, stack$$1.selectedIDs).suppressMenu(true).follow(followSelected)
54425 if (!followSelected && stack$$1.transform) {
54426 map$$1.transformEase(stack$$1.transform);
54430 context.background()
54431 .on('change.map', immediateRedraw);
54434 .on('redraw.map', immediateRedraw);
54437 .on('change.map', function() {
54438 context.background().updateImagery();
54443 .on('dblclick.map', dblClick)
54445 .call(zoom$$1.transform, projection.transform());
54447 supersurface = selection$$1.append('div')
54448 .attr('id', 'supersurface')
54449 .call(utilSetTransform, 0, 0);
54451 // Need a wrapper div because Opera can't cope with an absolutely positioned
54452 // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
54453 wrapper = supersurface
54455 .attr('class', 'layer layer-data');
54457 map$$1.surface = surface = wrapper
54459 .selectAll('.surface')
54460 .attr('id', 'surface');
54463 .call(drawLabels.observe)
54464 .on('mousedown.zoom', function() {
54465 if (event.button === 2) {
54466 event.stopPropagation();
54469 .on('mouseup.zoom', function() {
54470 if (resetTransform()) immediateRedraw();
54472 .on('mousemove.map', function() {
54475 .on('mouseover.vertices', function() {
54476 if (map$$1.editable() && !transformed) {
54477 var hover = event.target.__data__;
54478 surface.selectAll('.data-layer-osm')
54479 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
54480 dispatch$$1.call('drawn', this, {full: false});
54483 .on('mouseout.vertices', function() {
54484 if (map$$1.editable() && !transformed) {
54485 var hover = event.relatedTarget && event.relatedTarget.__data__;
54486 surface.selectAll('.data-layer-osm')
54487 .call(drawVertices.drawHover, context.graph(), hover, map$$1.extent(), map$$1.zoom());
54488 dispatch$$1.call('drawn', this, {full: false});
54493 .call(context.background());
54495 context.on('enter.map', function() {
54496 if (map$$1.editable() && !transformed) {
54497 var all = context.intersects(map$$1.extent()),
54498 filter = utilFunctor(true),
54499 graph = context.graph();
54501 all = context.features().filter(all, graph);
54502 surface.selectAll('.data-layer-osm')
54503 .call(drawVertices, graph, all, filter, map$$1.extent(), map$$1.zoom())
54504 .call(drawMidpoints, graph, all, filter, map$$1.trimmedExtent());
54505 dispatch$$1.call('drawn', this, {full: false});
54509 map$$1.dimensions(utilGetDimensions(selection$$1));
54513 function zoomEventFilter() {
54514 // Fix for #2151, (see also d3/d3-zoom#60, d3/d3-brush#18)
54515 // Intercept `mousedown` and check if there is an orphaned zoom gesture.
54516 // This can happen if a previous `mousedown` occurred without a `mouseup`.
54517 // If we detect this, dispatch `mouseup` to complete the orphaned gesture,
54518 // so that d3-zoom won't stop propagation of new `mousedown` events.
54519 if (event.type === 'mousedown') {
54520 var hasOrphan = false;
54521 var listeners = window.__on;
54522 for (var i = 0; i < listeners.length; i++) {
54523 var listener = listeners[i];
54524 if (listener.name === 'zoom' && listener.type === 'mouseup') {
54530 var event$$1 = window.CustomEvent;
54532 event$$1 = new event$$1('mouseup');
54534 event$$1 = window.document.createEvent('Event');
54535 event$$1.initEvent('mouseup', false, false);
54537 // Event needs to be dispatched with an event.view property.
54538 event$$1.view = window;
54539 window.dispatchEvent(event$$1);
54543 return event.button !== 2; // ignore right clicks
54548 return 256 * Math.pow(2, z);
54552 return Math.max(Math.log(k) / Math.LN2 - 8, 0);
54555 function pxCenter() {
54556 return [dimensions[0] / 2, dimensions[1] / 2];
54560 function drawVector(difference, extent$$1) {
54561 var graph = context.graph(),
54562 features = context.features(),
54563 all = context.intersects(map$$1.extent()),
54567 var complete = difference.complete(map$$1.extent());
54568 data = lodash.compact(lodash.values(complete));
54569 filter = function(d) { return d.id in complete; };
54570 features.clear(data);
54573 // force a full redraw if gatherStats detects that a feature
54574 // should be auto-hidden (e.g. points or buildings)..
54575 if (features.gatherStats(all, graph, dimensions)) {
54576 extent$$1 = undefined;
54580 data = context.intersects(map$$1.extent().intersection(extent$$1));
54581 var set$$1 = set$2(lodash.map(data, 'id'));
54582 filter = function(d) { return set$$1.has(d.id); };
54586 filter = utilFunctor(true);
54590 data = features.filter(data, graph);
54592 surface.selectAll('.data-layer-osm')
54593 .call(drawVertices, graph, data, filter, map$$1.extent(), map$$1.zoom())
54594 .call(drawLines, graph, data, filter)
54595 .call(drawAreas, graph, data, filter)
54596 .call(drawMidpoints, graph, data, filter, map$$1.trimmedExtent())
54597 .call(drawLabels, graph, data, filter, dimensions, !difference && !extent$$1)
54598 .call(drawPoints, graph, data, filter);
54600 dispatch$$1.call('drawn', this, {full: true});
54604 function editOff() {
54605 context.features().resetStats();
54606 surface.selectAll('.layer-osm *').remove();
54607 dispatch$$1.call('drawn', this, {full: true});
54611 function dblClick() {
54612 if (!dblclickEnabled) {
54613 event.preventDefault();
54614 event.stopImmediatePropagation();
54619 function zoomPan(manualEvent) {
54620 var eventTransform = (manualEvent || event).transform;
54622 if (transformStart.x === eventTransform.x &&
54623 transformStart.y === eventTransform.y &&
54624 transformStart.k === eventTransform.k) {
54625 return; // no change
54628 if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
54629 surface.interrupt();
54630 uiFlash(context.container())
54631 .select('.content')
54632 .text(t('cannot_zoom'));
54633 setZoom(context.minEditableZoom(), true);
54635 dispatch$$1.call('move', this, map$$1);
54639 projection.transform(eventTransform);
54641 var scale = eventTransform.k / transformStart.k,
54642 tX = (eventTransform.x / scale - transformStart.x) * scale,
54643 tY = (eventTransform.y / scale - transformStart.y) * scale;
54645 transformed = true;
54646 utilSetTransform(supersurface, tX, tY, scale);
54649 dispatch$$1.call('move', this, map$$1);
54653 function resetTransform() {
54654 if (!transformed) return false;
54656 surface.selectAll('.radial-menu').interrupt().remove();
54657 utilSetTransform(supersurface, 0, 0);
54658 transformed = false;
54663 function redraw(difference, extent$$1) {
54664 if (surface.empty() || !redrawEnabled) return;
54666 // If we are in the middle of a zoom/pan, we can't do differenced redraws.
54667 // It would result in artifacts where differenced entities are redrawn with
54668 // one transform and unchanged entities with another.
54669 if (resetTransform()) {
54670 difference = extent$$1 = undefined;
54673 var z = String(~~map$$1.zoom());
54674 if (surface.attr('data-zoom') !== z) {
54675 surface.attr('data-zoom', z)
54676 .classed('low-zoom', z <= 16);
54680 supersurface.call(context.background());
54687 if (map$$1.editable()) {
54688 context.loadTiles(projection, dimensions);
54689 drawVector(difference, extent$$1);
54694 transformStart = projection.transform();
54700 var queueRedraw = lodash.throttle(redraw, 750);
54703 var immediateRedraw = function(difference, extent$$1) {
54704 if (!difference && !extent$$1) queueRedraw.cancel();
54705 redraw(difference, extent$$1);
54709 function pointLocation(p) {
54710 var translate = projection.translate(),
54711 scale = projection.scale() * 2 * Math.PI;
54712 return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
54716 function locationPoint(l) {
54717 var translate = projection.translate(),
54718 scale = projection.scale() * 2 * Math.PI;
54719 return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
54723 map$$1.mouse = function() {
54724 var event$$1 = mousemove || event;
54727 while ((s = event$$1.sourceEvent)) { event$$1 = s; }
54728 return mouse$$1(event$$1);
54734 map$$1.mouseCoordinates = function() {
54735 return projection.invert(map$$1.mouse());
54739 map$$1.dblclickEnable = function(_) {
54740 if (!arguments.length) return dblclickEnabled;
54741 dblclickEnabled = _;
54746 map$$1.redrawEnable = function(_) {
54747 if (!arguments.length) return redrawEnabled;
54753 function setTransform(t2, duration, force) {
54754 var t$$1 = projection.transform();
54755 if (!force && t2.k === t$$1.k && t2.x === t$$1.x && t2.y === t$$1.y) {
54762 .duration(duration)
54763 .on('start', function() { map$$1.startEase(); })
54764 .call(zoom$$1.transform, identity$9.translate(t2.x, t2.y).scale(t2.k));
54766 projection.transform(t2);
54767 transformStart = t2;
54768 _selection.call(zoom$$1.transform, transformStart);
54773 function setZoom(z2, force, duration) {
54774 if (z2 === map$$1.zoom() && !force) {
54778 var k = projection.scale(),
54779 k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
54780 center = pxCenter(),
54781 l = pointLocation(center);
54783 projection.scale(k2);
54785 var t$$1 = projection.translate();
54786 l = locationPoint(l);
54788 t$$1[0] += center[0] - l[0];
54789 t$$1[1] += center[1] - l[1];
54792 projection.scale(k); // reset scale
54795 .duration(duration)
54796 .on('start', function() { map$$1.startEase(); })
54797 .call(zoom$$1.transform, identity$9.translate(t$$1[0], t$$1[1]).scale(k2));
54799 projection.translate(t$$1);
54800 transformStart = projection.transform();
54801 _selection.call(zoom$$1.transform, transformStart);
54808 function setCenter(loc2, duration) {
54809 var c = map$$1.center();
54810 if (loc2[0] === c[0] && loc2[1] === c[1]) {
54814 var t$$1 = projection.translate(),
54815 k = projection.scale(),
54817 ll = projection(loc2);
54819 t$$1[0] = t$$1[0] - ll[0] + pxC[0];
54820 t$$1[1] = t$$1[1] - ll[1] + pxC[1];
54825 .duration(duration)
54826 .on('start', function() { map$$1.startEase(); })
54827 .call(zoom$$1.transform, identity$9.translate(t$$1[0], t$$1[1]).scale(k));
54829 projection.translate(t$$1);
54830 transformStart = projection.transform();
54831 _selection.call(zoom$$1.transform, transformStart);
54838 map$$1.pan = function(delta, duration) {
54839 var t$$1 = projection.translate(),
54840 k = projection.scale();
54842 t$$1[0] += delta[0];
54843 t$$1[1] += delta[1];
54848 .duration(duration)
54849 .on('start', function() { map$$1.startEase(); })
54850 .call(zoom$$1.transform, identity$9.translate(t$$1[0], t$$1[1]).scale(k));
54852 projection.translate(t$$1);
54853 transformStart = projection.transform();
54854 _selection.call(zoom$$1.transform, transformStart);
54855 dispatch$$1.call('move', this, map$$1);
54863 map$$1.dimensions = function(_) {
54864 if (!arguments.length) return dimensions;
54865 var center = map$$1.center();
54867 drawLayers.dimensions(dimensions);
54868 context.background().dimensions(dimensions);
54869 projection.clipExtent([[0, 0], dimensions]);
54870 mouse$$1 = utilFastMouse(supersurface.node());
54878 function zoomIn(delta) {
54879 setZoom(~~map$$1.zoom() + delta, true, 250);
54882 function zoomOut(delta) {
54883 setZoom(~~map$$1.zoom() - delta, true, 250);
54886 map$$1.zoomIn = function() { zoomIn(1); };
54887 map$$1.zoomInFurther = function() { zoomIn(4); };
54889 map$$1.zoomOut = function() { zoomOut(1); };
54890 map$$1.zoomOutFurther = function() { zoomOut(4); };
54893 map$$1.center = function(loc2) {
54894 if (!arguments.length) {
54895 return projection.invert(pxCenter());
54898 if (setCenter(loc2)) {
54899 dispatch$$1.call('move', this, map$$1);
54907 map$$1.zoom = function(z2) {
54908 if (!arguments.length) {
54909 return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
54912 if (z2 < minzoom) {
54913 surface.interrupt();
54914 uiFlash(context.container())
54915 .select('.content')
54916 .text(t('cannot_zoom'));
54917 z2 = context.minEditableZoom();
54921 dispatch$$1.call('move', this, map$$1);
54929 map$$1.zoomTo = function(entity, zoomLimits) {
54930 var extent$$1 = entity.extent(context.graph());
54931 if (!isFinite(extent$$1.area())) return;
54933 var z2 = map$$1.trimmedExtentZoom(extent$$1);
54934 zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
54935 map$$1.centerZoom(extent$$1.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
54939 map$$1.centerZoom = function(loc2, z2) {
54940 var centered = setCenter(loc2),
54941 zoomed = setZoom(z2);
54943 if (centered || zoomed) {
54944 dispatch$$1.call('move', this, map$$1);
54952 map$$1.centerEase = function(loc2, duration) {
54953 duration = duration || 250;
54954 setCenter(loc2, duration);
54959 map$$1.zoomEase = function(z2, duration) {
54960 duration = duration || 250;
54961 setZoom(z2, false, duration);
54966 map$$1.transformEase = function(t2, duration) {
54967 duration = duration || 250;
54968 setTransform(t2, duration, false);
54973 map$$1.startEase = function() {
54974 utilBindOnce(surface, 'mousedown.ease', function() {
54975 map$$1.cancelEase();
54981 map$$1.cancelEase = function() {
54982 _selection.interrupt();
54987 map$$1.extent = function(_) {
54988 if (!arguments.length) {
54989 return new geoExtent$$1(projection.invert([0, dimensions[1]]),
54990 projection.invert([dimensions[0], 0]));
54992 var extent$$1 = geoExtent$$1(_);
54993 map$$1.centerZoom(extent$$1.center(), map$$1.extentZoom(extent$$1));
54998 map$$1.trimmedExtent = function(_) {
54999 if (!arguments.length) {
55000 var headerY = 60, footerY = 30, pad = 10;
55001 return new geoExtent$$1(projection.invert([pad, dimensions[1] - footerY - pad]),
55002 projection.invert([dimensions[0] - pad, headerY + pad]));
55004 var extent$$1 = geoExtent$$1(_);
55005 map$$1.centerZoom(extent$$1.center(), map$$1.trimmedExtentZoom(extent$$1));
55010 function calcZoom(extent$$1, dim) {
55011 var tl = projection([extent$$1[0][0], extent$$1[1][1]]),
55012 br = projection([extent$$1[1][0], extent$$1[0][1]]);
55014 // Calculate maximum zoom that fits extent
55015 var hFactor = (br[0] - tl[0]) / dim[0],
55016 vFactor = (br[1] - tl[1]) / dim[1],
55017 hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
55018 vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
55019 newZoom = map$$1.zoom() - Math.max(hZoomDiff, vZoomDiff);
55025 map$$1.extentZoom = function(_) {
55026 return calcZoom(geoExtent$$1(_), dimensions);
55030 map$$1.trimmedExtentZoom = function(_) {
55031 var trimY = 120, trimX = 40,
55032 trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
55033 return calcZoom(geoExtent$$1(_), trimmed);
55037 map$$1.editable = function() {
55038 return map$$1.zoom() >= context.minEditableZoom();
55042 map$$1.minzoom = function(_) {
55043 if (!arguments.length) return minzoom;
55049 map$$1.layers = drawLayers;
55052 return utilRebind(map$$1, dispatch$$1, 'on');
55055 var TAU = 2 * Math.PI;
55056 function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
55057 function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
55058 function vecSub(a, b) { return [ a[0] - b[0], a[1] - b[1] ]; }
55059 function vecScale(a, b) { return [ a[0] * b, a[1] * b ]; }
55062 function uiMapInMap(context) {
55066 function map_in_map(selection$$1) {
55067 var backgroundLayer = rendererTileLayer(context),
55068 overlayLayers = {},
55069 projection = geoRawMercator(),
55070 gpxLayer = svgGpx(projection, context).showLabels(false),
55071 debugLayer = svgDebug(projection, context),
55073 .scaleExtent([ztok(0.5), ztok(24)])
55074 .on('start', zoomStarted)
55075 .on('zoom', zoomed)
55076 .on('end', zoomEnded),
55077 isTransformed = false,
55079 skipEvents = false,
55081 zDiff = 6, // by default, minimap renders at (main zoom - 6)
55082 wrap = select(null),
55083 tiles = select(null),
55084 viewport = select(null),
55085 tStart, // transform at start of gesture
55086 tCurr, // transform at most recent event
55090 function zoomStarted() {
55091 if (skipEvents) return;
55092 tStart = tCurr = projection.transform();
55097 function zoomed() {
55098 if (skipEvents) return;
55100 var x = event.transform.x,
55101 y = event.transform.y,
55102 k = event.transform.k,
55103 isZooming = (k !== tStart.k),
55104 isPanning = (x !== tStart.x || y !== tStart.y);
55106 if (!isZooming && !isPanning) {
55107 return; // no change
55110 // lock in either zooming or panning, don't allow both in minimap.
55112 gesture = isZooming ? 'zoom' : 'pan';
55115 var tMini = projection.transform(),
55118 if (gesture === 'zoom') {
55119 var dMini = utilGetDimensions(wrap),
55120 cMini = vecScale(dMini, 0.5);
55121 scale = k / tMini.k;
55122 tX = (cMini[0] / scale - cMini[0]) * scale;
55123 tY = (cMini[1] / scale - cMini[1]) * scale;
55131 utilSetTransform(tiles, tX, tY, scale);
55132 utilSetTransform(viewport, 0, 0, scale);
55133 isTransformed = true;
55134 tCurr = identity$9.translate(x, y).scale(k);
55136 var zMain = ktoz(context.projection.scale()),
55139 zDiff = zMain - zMini;
55145 function zoomEnded() {
55146 if (skipEvents) return;
55147 if (gesture !== 'pan') return;
55149 updateProjection();
55151 var dMini = utilGetDimensions(wrap),
55152 cMini = vecScale(dMini, 0.5);
55153 context.map().center(projection.invert(cMini)); // recenter main map..
55157 function updateProjection() {
55158 var loc = context.map().center(),
55159 dMini = utilGetDimensions(wrap),
55160 cMini = vecScale(dMini, 0.5),
55161 tMain = context.projection.transform(),
55162 zMain = ktoz(tMain.k),
55163 zMini = Math.max(zMain - zDiff, 0.5),
55164 kMini = ztok(zMini);
55167 .translate([tMain.x, tMain.y])
55170 var point = projection(loc),
55171 mouse$$1 = (gesture === 'pan') ? vecSub([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0],
55172 xMini = cMini[0] - point[0] + tMain.x + mouse$$1[0],
55173 yMini = cMini[1] - point[1] + tMain.y + mouse$$1[1];
55176 .translate([xMini, yMini])
55177 .clipExtent([[0, 0], dMini]);
55179 tCurr = projection.transform();
55181 if (isTransformed) {
55182 utilSetTransform(tiles, 0, 0);
55183 utilSetTransform(viewport, 0, 0);
55184 isTransformed = false;
55188 .scaleExtent([ztok(0.5), ztok(zMain - 3)]);
55191 wrap.call(zoom$$1.transform, tCurr);
55192 skipEvents = false;
55196 function redraw() {
55197 clearTimeout(timeoutId);
55198 if (isHidden) return;
55200 updateProjection();
55202 var dMini = utilGetDimensions(wrap),
55203 zMini = ktoz(projection.scale());
55205 // setup tile container
55207 .selectAll('.map-in-map-tiles')
55210 tiles = tiles.enter()
55212 .attr('class', 'map-in-map-tiles')
55215 // redraw background
55217 .source(context.background().baseLayerSource())
55218 .projection(projection)
55219 .dimensions(dMini);
55221 var background = tiles
55222 .selectAll('.map-in-map-background')
55227 .attr('class', 'map-in-map-background')
55229 .call(backgroundLayer);
55233 var overlaySources = context.background().overlayLayerSources();
55234 var activeOverlayLayers = [];
55235 for (var i = 0; i < overlaySources.length; i++) {
55236 if (overlaySources[i].validZoom(zMini)) {
55237 if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
55238 activeOverlayLayers.push(overlayLayers[i]
55239 .source(overlaySources[i])
55240 .projection(projection)
55241 .dimensions(dMini));
55245 var overlay = tiles
55246 .selectAll('.map-in-map-overlay')
55249 overlay = overlay.enter()
55251 .attr('class', 'map-in-map-overlay')
55255 var overlays = overlay
55257 .data(activeOverlayLayers, function(d) { return d.source().name(); });
55262 overlays = overlays.enter()
55265 .each(function(layer) { select(this).call(layer); });
55268 var dataLayers = tiles
55269 .selectAll('.map-in-map-data')
55275 dataLayers = dataLayers.enter()
55277 .attr('class', 'map-in-map-data')
55283 // redraw viewport bounding box
55284 if (gesture !== 'pan') {
55285 var getPath = index$4(projection),
55286 bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
55288 viewport = wrap.selectAll('.map-in-map-viewport')
55291 viewport = viewport.enter()
55293 .attr('class', 'map-in-map-viewport')
55297 var path$$1 = viewport.selectAll('.map-in-map-bbox')
55302 .attr('class', 'map-in-map-bbox')
55304 .attr('d', getPath)
55305 .classed('thick', function(d) { return getPath.area(d) < 30; });
55310 function queueRedraw() {
55311 clearTimeout(timeoutId);
55312 timeoutId = setTimeout(function() { redraw(); }, 750);
55316 function toggle() {
55317 if (event) event.preventDefault();
55319 isHidden = !isHidden;
55321 var label = select('.minimap-toggle');
55322 label.classed('active', !isHidden)
55323 .select('input').property('checked', !isHidden);
55327 .style('display', 'block')
55328 .style('opacity', '1')
55331 .style('opacity', '0')
55332 .on('end', function() {
55333 selection$$1.selectAll('.map-in-map')
55334 .style('display', 'none');
55338 .style('display', 'block')
55339 .style('opacity', '0')
55342 .style('opacity', '1')
55343 .on('end', function() {
55350 uiMapInMap.toggle = toggle;
55352 wrap = selection$$1.selectAll('.map-in-map')
55355 wrap = wrap.enter()
55357 .attr('class', 'map-in-map')
55358 .style('display', (isHidden ? 'none' : 'block'))
55360 .on('dblclick.zoom', null)
55364 .on('drawn.map-in-map', function(drawn) {
55365 if (drawn.full === true) {
55372 var keybinding = d3keybinding('map-in-map')
55382 function uiTooltipHtml(text, key) {
55383 var s = '<span>' + text + '</span>';
55385 s += '<div class="keyhint-wrap">' +
55386 '<span> ' + (t('tooltip_keyhint')) + ' </span>' +
55387 '<span class="keyhint"> ' + key + '</span></div>';
55392 function uiBackground(context) {
55394 detected = utilDetect(),
55395 opacities = [1, 0.75, 0.5, 0.25],
55397 ['right', [0.5, 0]],
55398 ['top', [0, -0.5]],
55399 ['left', [-0.5, 0]],
55400 ['bottom', [0, 0.5]]],
55401 opacityDefault = (context.storage('background-opacity') !== null) ?
55402 (+context.storage('background-opacity')) : 1.0,
55403 customTemplate = context.storage('background-custom-template') || '',
55406 // Can be 0 from <1.3.0 use or due to issue #1923.
55407 if (opacityDefault === 0) opacityDefault = 1.0;
55410 function background(selection$$1) {
55412 function sortSources(a, b) {
55413 return a.best() && !b.best() ? -1
55414 : b.best() && !a.best() ? 1
55415 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0;
55419 function setOpacity(d) {
55420 var bg = context.container().selectAll('.layer-background')
55422 .style('opacity', d)
55423 .attr('data-opacity', d);
55425 if (!detected.opera) {
55426 utilSetTransform(bg, 0, 0);
55429 opacityList.selectAll('li')
55430 .classed('active', function(_) { return _ === d; });
55432 context.storage('background-opacity', d);
55436 function setTooltips(selection$$1) {
55437 selection$$1.each(function(d, i, nodes) {
55438 var item = select(this).select('label'),
55439 placement = (i < nodes.length / 2) ? 'bottom' : 'top';
55441 if (d === previous) {
55442 item.call(tooltip()
55443 .placement(placement)
55445 .title(function() {
55446 var tip = '<div>' + t('background.switch') + '</div>';
55447 return uiTooltipHtml(tip, uiCmd('⌘B'));
55450 } else if (d.description) {
55451 item.call(tooltip()
55452 .placement(placement)
55453 .title(d.description)
55456 item.call(tooltip().destroy);
55462 function selectLayer() {
55463 function active$$1(d) {
55464 return context.background().showsLayer(d);
55467 content.selectAll('.layer, .custom_layer')
55468 .classed('active', active$$1)
55469 .classed('switch', function(d) { return d === previous; })
55471 .selectAll('input')
55472 .property('checked', active$$1);
55476 function clickSetSource(d) {
55477 event.preventDefault();
55478 previous = context.background().baseLayerSource();
55479 context.background().baseLayerSource(d);
55481 document.activeElement.blur();
55485 function editCustom() {
55486 event.preventDefault();
55487 var template = window.prompt(t('background.custom_prompt'), customTemplate);
55489 setCustom(template);
55496 function setCustom(template) {
55497 context.storage('background-custom-template', template);
55498 var d = rendererBackgroundSource.Custom(template);
55499 content.selectAll('.custom_layer').datum(d);
55504 function clickSetOverlay(d) {
55505 event.preventDefault();
55506 context.background().toggleOverlayLayer(d);
55508 document.activeElement.blur();
55512 function drawList(layerList, type, change, filter) {
55513 var sources = context.background()
55514 .sources(context.map().extent())
55517 var layerLinks = layerList.selectAll('li.layer')
55518 .data(sources, function(d) { return d.name(); });
55523 var enter = layerLinks.enter()
55524 .insert('li', '.custom_layer')
55525 .attr('class', 'layer')
55526 .classed('best', function(d) { return d.best(); });
55528 enter.filter(function(d) { return d.best(); })
55530 .attr('class', 'best')
55532 .title(t('background.best_imagery'))
55533 .placement((textDirection === 'rtl') ? 'right' : 'left'))
55542 .attr('type', type)
55543 .attr('name', 'layers')
55544 .on('change', change);
55548 .text(function(d) { return d.name(); });
55551 layerList.selectAll('li.layer')
55553 .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
55557 function update() {
55558 backgroundList.call(drawList, 'radio', clickSetSource, function(d) { return !d.overlay; });
55559 overlayList.call(drawList, 'checkbox', clickSetOverlay, function(d) { return d.overlay; });
55563 var source = context.background().baseLayerSource();
55564 if (source.id === 'custom') {
55565 customTemplate = source.template;
55572 function updateOffsetVal() {
55573 var meters = geoOffsetToMeters(context.background().offset()),
55574 x = +meters[0].toFixed(2),
55575 y = +meters[1].toFixed(2);
55577 selectAll('.nudge-inner-rect')
55579 .classed('error', false)
55580 .property('value', x + ', ' + y);
55582 selectAll('.nudge-reset')
55583 .classed('disabled', function() {
55584 return (x === 0 && y === 0);
55589 function resetOffset() {
55590 if (event.button !== 0) return;
55591 context.background().offset([0, 0]);
55596 function nudge(d) {
55597 context.background().nudge(d, context.map().zoom());
55602 function buttonOffset(d) {
55603 if (event.button !== 0) return;
55604 var timeout$$1 = window.setTimeout(function() {
55605 interval$$1 = window.setInterval(nudge.bind(null, d), 100);
55609 function doneNudge() {
55610 window.clearTimeout(timeout$$1);
55611 window.clearInterval(interval$$1);
55613 .on('mouseup.buttonoffset', null, true)
55614 .on('mousedown.buttonoffset', null, true);
55618 .on('mouseup.buttonoffset', doneNudge, true)
55619 .on('mousedown.buttonoffset', doneNudge, true);
55625 function inputOffset() {
55626 if (event.button !== 0) return;
55627 var input = select(this);
55628 var d = input.node().value;
55630 if (d === '') return resetOffset();
55632 d = d.replace(/;/g, ',').split(',').map(function(n) {
55633 // if n is NaN, it will always get mapped to false.
55634 return !isNaN(n) && n;
55637 if (d.length !== 2 || !d[0] || !d[1]) {
55638 input.classed('error', true);
55642 context.background().offset(geoMetersToOffset(d));
55647 function dragOffset() {
55648 if (event.button !== 0) return;
55649 var origin = [event.clientX, event.clientY];
55651 context.container()
55653 .attr('class', 'nudge-surface');
55656 .on('mousemove.offset', function() {
55657 var latest = [event.clientX, event.clientY];
55659 -(origin[0] - latest[0]) / 4,
55660 -(origin[1] - latest[1]) / 4
55666 .on('mouseup.offset', function() {
55667 if (event.button !== 0) return;
55668 selectAll('.nudge-surface')
55672 .on('mousemove.offset', null)
55673 .on('mouseup.offset', null);
55676 event.preventDefault();
55685 function toggle() {
55686 if (event) event.preventDefault();
55687 tooltipBehavior.hide(button);
55688 setVisible(!button.classed('active'));
55692 function quickSwitch() {
55694 clickSetSource(previous);
55699 function setVisible(show) {
55700 if (show !== shown) {
55701 button.classed('active', show);
55705 selection$$1.on('mousedown.background-inside', function() {
55706 event.stopPropagation();
55709 .style('display', 'block')
55710 .style('right', '-300px')
55713 .style('right', '0px');
55716 .style('display', 'block')
55717 .style('right', '0px')
55720 .style('right', '-300px')
55721 .on('end', function() {
55722 select(this).style('display', 'none');
55724 selection$$1.on('mousedown.background-inside', null);
55730 var content = selection$$1
55732 .attr('class', 'fillL map-overlay col3 content hide'),
55733 tooltipBehavior = tooltip()
55734 .placement((textDirection === 'rtl') ? 'right' : 'left')
55736 .title(uiTooltipHtml(t('background.description'), key)),
55737 button = selection$$1
55739 .attr('tabindex', -1)
55740 .on('click', toggle)
55741 .call(svgIcon('#icon-layers', 'light'))
55742 .call(tooltipBehavior),
55746 /* opacity switcher */
55748 var opawrap = content
55750 .attr('class', 'opacity-options-wrapper');
55754 .text(t('background.title'));
55756 var opacityList = opawrap
55758 .attr('class', 'opacity-options');
55760 opacityList.selectAll('div.opacity')
55764 .attr('data-original-title', function(d) {
55765 return t('background.percent_brightness', { opacity: (d * 100) });
55767 .on('click.set-opacity', setOpacity)
55768 .html('<div class="select-box"></div>')
55770 .placement((textDirection === 'rtl') ? 'right' : 'left'))
55772 .attr('class', 'opacity')
55773 .style('opacity', function(d) { return 1.25 - d; });
55776 /* background switcher */
55778 var backgroundList = content
55780 .attr('class', 'layer-list')
55781 .attr('dir', 'auto');
55783 var custom = backgroundList
55785 .attr('class', 'custom_layer')
55786 .datum(rendererBackgroundSource.Custom());
55790 .attr('class', 'layer-browse')
55792 .title(t('background.custom_button'))
55793 .placement((textDirection === 'rtl') ? 'right' : 'left'))
55794 .on('click', editCustom)
55795 .call(svgIcon('#icon-search'));
55802 .attr('type', 'radio')
55803 .attr('name', 'layers')
55804 .on('change', function () {
55805 if (customTemplate) {
55806 setCustom(customTemplate);
55814 .text(t('background.custom'));
55818 .attr('class', 'imagery-faq')
55820 .attr('target', '_blank')
55821 .attr('tabindex', -1)
55822 .call(svgIcon('#icon-out-link', 'inline'))
55823 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
55825 .text(t('background.imagery_source_faq'));
55827 var overlayList = content
55829 .attr('class', 'layer-list');
55831 var controls = content
55833 .attr('class', 'controls-list');
55836 /* minimap toggle */
55838 var minimapLabel = controls
55842 .title(uiTooltipHtml(t('background.minimap.tooltip'), '/'))
55847 .classed('minimap-toggle', true)
55849 .attr('type', 'checkbox')
55850 .on('change', function() {
55851 uiMapInMap.toggle();
55852 event.preventDefault();
55857 .text(t('background.minimap.description'));
55860 /* imagery offset controls */
55862 var adjustments = content
55864 .attr('class', 'adjustments');
55868 .text(t('background.fix_misalignment'))
55870 .classed('hide-toggle', true)
55871 .classed('expanded', false)
55872 .on('click', function() {
55873 if (event.button !== 0) return;
55874 var exp = select(this).classed('expanded');
55875 nudgeContainer.style('display', exp ? 'none' : 'block');
55876 select(this).classed('expanded', !exp);
55877 event.preventDefault();
55880 var nudgeContainer = adjustments
55882 .attr('class', 'nudge-container cf')
55883 .style('display', 'none');
55887 .attr('class', 'nudge-instructions')
55888 .text(t('background.offset'));
55890 var nudgeRect = nudgeContainer
55892 .attr('class', 'nudge-outer-rect')
55893 .on('mousedown', dragOffset);
55897 .attr('class', 'nudge-inner-rect')
55899 .on('change', inputOffset)
55900 .on('mousedown', function() {
55901 if (event.button !== 0) return;
55902 event.stopPropagation();
55907 .selectAll('button')
55908 .data(directions).enter()
55910 .attr('class', function(d) { return d[0] + ' nudge'; })
55911 .on('mousedown', function(d) {
55912 if (event.button !== 0) return;
55913 buttonOffset(d[1]);
55918 .attr('title', t('background.reset'))
55919 .attr('class', 'nudge-reset disabled')
55920 .on('click', resetOffset)
55922 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
55926 .on('move.background-update', lodash.debounce(update, 1000));
55928 context.background()
55929 .on('change.background-update', update);
55933 setOpacity(opacityDefault);
55935 var keybinding = d3keybinding('background')
55937 .on(uiCmd('⌘B'), quickSwitch)
55944 context.surface().on('mousedown.background-outside', hide);
55945 context.container().on('mousedown.background-outside', hide);
55951 function uiContributors(context) {
55952 var debouncedUpdate = lodash.debounce(function() { update(); }, 1000),
55955 wrap = select(null);
55958 function update() {
55960 entities = context.intersects(context.map().extent());
55962 entities.forEach(function(entity) {
55963 if (entity && entity.user) users[entity.user] = true;
55966 var u = Object.keys(users),
55967 subset = u.slice(0, u.length > limit ? limit - 1 : limit);
55970 .call(svgIcon('#icon-nearby', 'pre-text light'));
55972 var userList = select(document.createElement('span'));
55974 userList.selectAll()
55978 .attr('class', 'user-link')
55979 .attr('href', function(d) { return context.connection().userURL(d); })
55980 .attr('target', '_blank')
55981 .attr('tabindex', -1)
55984 if (u.length > limit) {
55985 var count = select(document.createElement('span'));
55988 .attr('target', '_blank')
55989 .attr('tabindex', -1)
55990 .attr('href', function() {
55991 return context.connection().changesetsURL(context.map().center(), context.map().zoom());
55993 .text(u.length - limit + 1);
55995 wrap.append('span')
55996 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
55999 wrap.append('span')
56000 .html(t('contributors.list', { users: userList.html() }));
56007 .style('opacity', 0);
56009 } else if (hidden) {
56012 .style('opacity', 1);
56017 return function(selection$$1) {
56018 wrap = selection$$1;
56021 context.connection().on('loaded.contributors', debouncedUpdate);
56022 context.map().on('move.contributors', debouncedUpdate);
56026 function uiFeatureInfo(context) {
56027 function update(selection$$1) {
56028 var features = context.features(),
56029 stats = features.stats(),
56031 hiddenList = lodash.compact(lodash.map(features.hidden(), function(k) {
56034 return String(stats[k]) + ' ' + t('feature.' + k + '.description');
56038 selection$$1.html('');
56040 if (hiddenList.length) {
56041 var tooltipBehavior = tooltip()
56044 .title(function() {
56045 return uiTooltipHtml(hiddenList.join('<br/>'));
56048 var warning = selection$$1.append('a')
56050 .attr('tabindex', -1)
56051 .html(t('feature_info.hidden_warning', { count: count }))
56052 .call(tooltipBehavior)
56053 .on('click', function() {
56054 tooltipBehavior.hide(warning);
56055 // open map data panel?
56056 event.preventDefault();
56061 .classed('hide', !hiddenList.length);
56065 return function(selection$$1) {
56066 update(selection$$1);
56068 context.features().on('change.feature_info', function() {
56069 update(selection$$1);
56074 function uiFullScreen(context) {
56075 var element = context.container().node(),
56076 keybinding = d3keybinding('full-screen');
56080 function getFullScreenFn() {
56081 if (element.requestFullscreen) {
56082 return element.requestFullscreen;
56083 } else if (element.msRequestFullscreen) {
56084 return element.msRequestFullscreen;
56085 } else if (element.mozRequestFullScreen) {
56086 return element.mozRequestFullScreen;
56087 } else if (element.webkitRequestFullscreen) {
56088 return element.webkitRequestFullscreen;
56093 function getExitFullScreenFn() {
56094 if (document.exitFullscreen) {
56095 return document.exitFullscreen;
56096 } else if (document.msExitFullscreen) {
56097 return document.msExitFullscreen;
56098 } else if (document.mozCancelFullScreen) {
56099 return document.mozCancelFullScreen;
56100 } else if (document.webkitExitFullscreen) {
56101 return document.webkitExitFullscreen;
56106 function isFullScreen() {
56107 return document.fullscreenElement ||
56108 document.mozFullScreenElement ||
56109 document.webkitFullscreenElement ||
56110 document.msFullscreenElement;
56114 function isSupported() {
56115 return !!getFullScreenFn();
56119 function fullScreen() {
56120 event.preventDefault();
56121 if (!isFullScreen()) {
56122 // button.classed('active', true);
56123 getFullScreenFn().apply(element);
56125 // button.classed('active', false);
56126 getExitFullScreenFn().apply(document);
56131 return function() { // selection) {
56132 if (!isSupported())
56135 // button = selection.append('button')
56136 // .attr('title', t('full_screen'))
56137 // .attr('tabindex', -1)
56138 // .on('click', fullScreen)
56141 // button.append('span')
56142 // .attr('class', 'icon full-screen');
56145 .on('f11', fullScreen)
56146 .on(uiCmd('⌘⇧F'), fullScreen);
56153 function uiModal(selection$$1, blocking) {
56154 var keybinding = d3keybinding('modal');
56155 var previous = selection$$1.select('div.modal');
56156 var animate = previous.empty();
56158 previous.transition()
56160 .style('opacity', 0)
56163 var shaded = selection$$1
56165 .attr('class', 'shaded')
56166 .style('opacity', 0);
56168 shaded.close = function() {
56172 .style('opacity',0)
56178 .style('top','0px');
56186 .attr('class', 'modal fillL col6');
56189 shaded.on('click.remove-modal', function() {
56190 if (event.target === this) {
56195 modal.append('button')
56196 .attr('class', 'close')
56197 .on('click', shaded.close)
56198 .call(svgIcon('#icon-close'));
56201 .on('⌫', shaded.close)
56202 .on('⎋', shaded.close);
56210 .attr('class', 'content');
56213 shaded.transition().style('opacity', 1);
56215 shaded.style('opacity', 1);
56222 function uiLoading(context) {
56228 var loading = function(selection) {
56229 modalSelection = uiModal(selection, blocking);
56231 var loadertext = modalSelection.select('.content')
56232 .classed('loading-modal', true)
56234 .attr('class', 'modal-section fillL');
56238 .attr('class', 'loader')
56239 .attr('src', context.imagePath('loader-white.gif'));
56245 modalSelection.select('button.close')
56246 .attr('class', 'hide');
56252 loading.message = function(_) {
56253 if (!arguments.length) return message;
56259 loading.blocking = function(_) {
56260 if (!arguments.length) return blocking;
56266 loading.close = function() {
56267 modalSelection.remove();
56274 function uiGeolocate(context) {
56275 var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
56276 locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
56281 context.enter(modeBrowse(context));
56282 context.container().call(locating);
56283 navigator.geolocation.getCurrentPosition(success, error, geoOptions);
56285 // This timeout ensures that we still call finish() even if
56286 // the user declines to share their location in Firefox
56287 timeoutId = setTimeout(finish, 10000 /* 10sec */ );
56291 function success(position) {
56292 var map = context.map(),
56293 extent = geoExtent$$1([position.coords.longitude, position.coords.latitude])
56294 .padByMeters(position.coords.accuracy);
56296 map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
56306 function finish() {
56307 locating.close(); // unblock ui
56308 if (timeoutId) { clearTimeout(timeoutId); }
56309 timeoutId = undefined;
56313 return function(selection) {
56314 if (!navigator.geolocation) return;
56318 .attr('tabindex', -1)
56319 .attr('title', t('geolocate.title'))
56320 .on('click', click)
56321 .call(svgIcon('#icon-geolocate', 'light'))
56323 .placement((textDirection === 'rtl') ? 'right' : 'left'));
56327 var marked = createCommonjsModule(function (module, exports) {
56329 * marked - a markdown parser
56330 * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
56331 * https://github.com/chjj/marked
56337 * Block-Level Grammar
56342 code: /^( {4}[^\n]+\n*)+/,
56344 hr: /^( *[-*_]){3,} *(?:\n+|$)/,
56345 heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
56347 lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
56348 blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
56349 list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
56350 html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
56351 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
56353 paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
56357 block.bullet = /(?:[*+-]|\d+\.)/;
56358 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
56359 block.item = replace(block.item, 'gm')
56360 (/bull/g, block.bullet)
56363 block.list = replace(block.list)
56364 (/bull/g, block.bullet)
56365 ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
56366 ('def', '\\n+(?=' + block.def.source + ')')
56369 block.blockquote = replace(block.blockquote)
56373 block._tag = '(?!(?:'
56374 + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
56375 + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
56376 + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
56378 block.html = replace(block.html)
56379 ('comment', /<!--[\s\S]*?-->/)
56380 ('closed', /<(tag)[\s\S]+?<\/\1>/)
56381 ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
56382 (/tag/g, block._tag)
56385 block.paragraph = replace(block.paragraph)
56387 ('heading', block.heading)
56388 ('lheading', block.lheading)
56389 ('blockquote', block.blockquote)
56390 ('tag', '<' + block._tag)
56395 * Normal Block Grammar
56398 block.normal = merge({}, block);
56401 * GFM Block Grammar
56404 block.gfm = merge({}, block.normal, {
56405 fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
56407 heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
56410 block.gfm.paragraph = replace(block.paragraph)
56412 + block.gfm.fences.source.replace('\\1', '\\2') + '|'
56413 + block.list.source.replace('\\1', '\\3') + '|')
56417 * GFM + Tables Block Grammar
56420 block.tables = merge({}, block.gfm, {
56421 nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
56422 table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
56429 function Lexer(options) {
56431 this.tokens.links = {};
56432 this.options = options || marked.defaults;
56433 this.rules = block.normal;
56435 if (this.options.gfm) {
56436 if (this.options.tables) {
56437 this.rules = block.tables;
56439 this.rules = block.gfm;
56445 * Expose Block Rules
56448 Lexer.rules = block;
56451 * Static Lex Method
56454 Lexer.lex = function(src, options) {
56455 var lexer = new Lexer(options);
56456 return lexer.lex(src);
56463 Lexer.prototype.lex = function(src) {
56465 .replace(/\r\n|\r/g, '\n')
56466 .replace(/\t/g, ' ')
56467 .replace(/\u00a0/g, ' ')
56468 .replace(/\u2424/g, '\n');
56470 return this.token(src, true);
56477 Lexer.prototype.token = function(src, top, bq) {
56478 var src = src.replace(/^ +$/gm, '')
56491 if (cap = this.rules.newline.exec(src)) {
56492 src = src.substring(cap[0].length);
56493 if (cap[0].length > 1) {
56501 if (cap = this.rules.code.exec(src)) {
56502 src = src.substring(cap[0].length);
56503 cap = cap[0].replace(/^ {4}/gm, '');
56506 text: !this.options.pedantic
56507 ? cap.replace(/\n+$/, '')
56514 if (cap = this.rules.fences.exec(src)) {
56515 src = src.substring(cap[0].length);
56525 if (cap = this.rules.heading.exec(src)) {
56526 src = src.substring(cap[0].length);
56529 depth: cap[1].length,
56535 // table no leading pipe (gfm)
56536 if (top && (cap = this.rules.nptable.exec(src))) {
56537 src = src.substring(cap[0].length);
56541 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
56542 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
56543 cells: cap[3].replace(/\n$/, '').split('\n')
56546 for (i = 0; i < item.align.length; i++) {
56547 if (/^ *-+: *$/.test(item.align[i])) {
56548 item.align[i] = 'right';
56549 } else if (/^ *:-+: *$/.test(item.align[i])) {
56550 item.align[i] = 'center';
56551 } else if (/^ *:-+ *$/.test(item.align[i])) {
56552 item.align[i] = 'left';
56554 item.align[i] = null;
56558 for (i = 0; i < item.cells.length; i++) {
56559 item.cells[i] = item.cells[i].split(/ *\| */);
56562 this.tokens.push(item);
56568 if (cap = this.rules.lheading.exec(src)) {
56569 src = src.substring(cap[0].length);
56572 depth: cap[2] === '=' ? 1 : 2,
56579 if (cap = this.rules.hr.exec(src)) {
56580 src = src.substring(cap[0].length);
56588 if (cap = this.rules.blockquote.exec(src)) {
56589 src = src.substring(cap[0].length);
56592 type: 'blockquote_start'
56595 cap = cap[0].replace(/^ *> ?/gm, '');
56597 // Pass `top` to keep the current
56598 // "toplevel" state. This is exactly
56599 // how markdown.pl works.
56600 this.token(cap, top, true);
56603 type: 'blockquote_end'
56610 if (cap = this.rules.list.exec(src)) {
56611 src = src.substring(cap[0].length);
56615 type: 'list_start',
56616 ordered: bull.length > 1
56619 // Get each top-level item.
56620 cap = cap[0].match(this.rules.item);
56626 for (; i < l; i++) {
56629 // Remove the list item's bullet
56630 // so it is seen as the next token.
56631 space = item.length;
56632 item = item.replace(/^ *([*+-]|\d+\.) +/, '');
56634 // Outdent whatever the
56635 // list item contains. Hacky.
56636 if (~item.indexOf('\n ')) {
56637 space -= item.length;
56638 item = !this.options.pedantic
56639 ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
56640 : item.replace(/^ {1,4}/gm, '');
56643 // Determine whether the next list item belongs here.
56644 // Backpedal if it does not belong in this list.
56645 if (this.options.smartLists && i !== l - 1) {
56646 b = block.bullet.exec(cap[i + 1])[0];
56647 if (bull !== b && !(bull.length > 1 && b.length > 1)) {
56648 src = cap.slice(i + 1).join('\n') + src;
56653 // Determine whether item is loose or not.
56654 // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
56655 // for discount behavior.
56656 loose = next || /\n\n(?!\s*$)/.test(item);
56658 next = item.charAt(item.length - 1) === '\n';
56659 if (!loose) loose = next;
56664 ? 'loose_item_start'
56665 : 'list_item_start'
56669 this.token(item, false, bq);
56672 type: 'list_item_end'
56684 if (cap = this.rules.html.exec(src)) {
56685 src = src.substring(cap[0].length);
56687 type: this.options.sanitize
56690 pre: !this.options.sanitizer
56691 && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
56698 if ((!bq && top) && (cap = this.rules.def.exec(src))) {
56699 src = src.substring(cap[0].length);
56700 this.tokens.links[cap[1].toLowerCase()] = {
56708 if (top && (cap = this.rules.table.exec(src))) {
56709 src = src.substring(cap[0].length);
56713 header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
56714 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
56715 cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
56718 for (i = 0; i < item.align.length; i++) {
56719 if (/^ *-+: *$/.test(item.align[i])) {
56720 item.align[i] = 'right';
56721 } else if (/^ *:-+: *$/.test(item.align[i])) {
56722 item.align[i] = 'center';
56723 } else if (/^ *:-+ *$/.test(item.align[i])) {
56724 item.align[i] = 'left';
56726 item.align[i] = null;
56730 for (i = 0; i < item.cells.length; i++) {
56731 item.cells[i] = item.cells[i]
56732 .replace(/^ *\| *| *\| *$/g, '')
56736 this.tokens.push(item);
56741 // top-level paragraph
56742 if (top && (cap = this.rules.paragraph.exec(src))) {
56743 src = src.substring(cap[0].length);
56746 text: cap[1].charAt(cap[1].length - 1) === '\n'
56747 ? cap[1].slice(0, -1)
56754 if (cap = this.rules.text.exec(src)) {
56755 // Top-level should never reach here.
56756 src = src.substring(cap[0].length);
56766 Error('Infinite loop on byte: ' + src.charCodeAt(0));
56770 return this.tokens;
56774 * Inline-Level Grammar
56778 escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
56779 autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
56781 tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
56782 link: /^!?\[(inside)\]\(href\)/,
56783 reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
56784 nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
56785 strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
56786 em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
56787 code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
56788 br: /^ {2,}\n(?!\s*$)/,
56790 text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
56793 inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
56794 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
56796 inline.link = replace(inline.link)
56797 ('inside', inline._inside)
56798 ('href', inline._href)
56801 inline.reflink = replace(inline.reflink)
56802 ('inside', inline._inside)
56806 * Normal Inline Grammar
56809 inline.normal = merge({}, inline);
56812 * Pedantic Inline Grammar
56815 inline.pedantic = merge({}, inline.normal, {
56816 strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
56817 em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
56821 * GFM Inline Grammar
56824 inline.gfm = merge({}, inline.normal, {
56825 escape: replace(inline.escape)('])', '~|])')(),
56826 url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
56827 del: /^~~(?=\S)([\s\S]*?\S)~~/,
56828 text: replace(inline.text)
56830 ('|', '|https?://|')
56835 * GFM + Line Breaks Inline Grammar
56838 inline.breaks = merge({}, inline.gfm, {
56839 br: replace(inline.br)('{2,}', '*')(),
56840 text: replace(inline.gfm.text)('{2,}', '*')()
56844 * Inline Lexer & Compiler
56847 function InlineLexer(links, options) {
56848 this.options = options || marked.defaults;
56849 this.links = links;
56850 this.rules = inline.normal;
56851 this.renderer = this.options.renderer || new Renderer;
56852 this.renderer.options = this.options;
56856 Error('Tokens array requires a `links` property.');
56859 if (this.options.gfm) {
56860 if (this.options.breaks) {
56861 this.rules = inline.breaks;
56863 this.rules = inline.gfm;
56865 } else if (this.options.pedantic) {
56866 this.rules = inline.pedantic;
56871 * Expose Inline Rules
56874 InlineLexer.rules = inline;
56877 * Static Lexing/Compiling Method
56880 InlineLexer.output = function(src, links, options) {
56881 var inline = new InlineLexer(links, options);
56882 return inline.output(src);
56889 InlineLexer.prototype.output = function(src) {
56898 if (cap = this.rules.escape.exec(src)) {
56899 src = src.substring(cap[0].length);
56905 if (cap = this.rules.autolink.exec(src)) {
56906 src = src.substring(cap[0].length);
56907 if (cap[2] === '@') {
56908 text = cap[1].charAt(6) === ':'
56909 ? this.mangle(cap[1].substring(7))
56910 : this.mangle(cap[1]);
56911 href = this.mangle('mailto:') + text;
56913 text = escape(cap[1]);
56916 out += this.renderer.link(href, null, text);
56921 if (!this.inLink && (cap = this.rules.url.exec(src))) {
56922 src = src.substring(cap[0].length);
56923 text = escape(cap[1]);
56925 out += this.renderer.link(href, null, text);
56930 if (cap = this.rules.tag.exec(src)) {
56931 if (!this.inLink && /^<a /i.test(cap[0])) {
56932 this.inLink = true;
56933 } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
56934 this.inLink = false;
56936 src = src.substring(cap[0].length);
56937 out += this.options.sanitize
56938 ? this.options.sanitizer
56939 ? this.options.sanitizer(cap[0])
56946 if (cap = this.rules.link.exec(src)) {
56947 src = src.substring(cap[0].length);
56948 this.inLink = true;
56949 out += this.outputLink(cap, {
56953 this.inLink = false;
56958 if ((cap = this.rules.reflink.exec(src))
56959 || (cap = this.rules.nolink.exec(src))) {
56960 src = src.substring(cap[0].length);
56961 link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
56962 link = this.links[link.toLowerCase()];
56963 if (!link || !link.href) {
56964 out += cap[0].charAt(0);
56965 src = cap[0].substring(1) + src;
56968 this.inLink = true;
56969 out += this.outputLink(cap, link);
56970 this.inLink = false;
56975 if (cap = this.rules.strong.exec(src)) {
56976 src = src.substring(cap[0].length);
56977 out += this.renderer.strong(this.output(cap[2] || cap[1]));
56982 if (cap = this.rules.em.exec(src)) {
56983 src = src.substring(cap[0].length);
56984 out += this.renderer.em(this.output(cap[2] || cap[1]));
56989 if (cap = this.rules.code.exec(src)) {
56990 src = src.substring(cap[0].length);
56991 out += this.renderer.codespan(escape(cap[2], true));
56996 if (cap = this.rules.br.exec(src)) {
56997 src = src.substring(cap[0].length);
56998 out += this.renderer.br();
57003 if (cap = this.rules.del.exec(src)) {
57004 src = src.substring(cap[0].length);
57005 out += this.renderer.del(this.output(cap[1]));
57010 if (cap = this.rules.text.exec(src)) {
57011 src = src.substring(cap[0].length);
57012 out += this.renderer.text(escape(this.smartypants(cap[0])));
57018 Error('Infinite loop on byte: ' + src.charCodeAt(0));
57029 InlineLexer.prototype.outputLink = function(cap, link) {
57030 var href = escape(link.href)
57031 , title = link.title ? escape(link.title) : null;
57033 return cap[0].charAt(0) !== '!'
57034 ? this.renderer.link(href, title, this.output(cap[1]))
57035 : this.renderer.image(href, title, escape(cap[1]));
57039 * Smartypants Transformations
57042 InlineLexer.prototype.smartypants = function(text) {
57043 if (!this.options.smartypants) return text;
57046 .replace(/---/g, '\u2014')
57048 .replace(/--/g, '\u2013')
57050 .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
57051 // closing singles & apostrophes
57052 .replace(/'/g, '\u2019')
57054 .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
57056 .replace(/"/g, '\u201d')
57058 .replace(/\.{3}/g, '\u2026');
57065 InlineLexer.prototype.mangle = function(text) {
57066 if (!this.options.mangle) return text;
57072 for (; i < l; i++) {
57073 ch = text.charCodeAt(i);
57074 if (Math.random() > 0.5) {
57075 ch = 'x' + ch.toString(16);
57077 out += '&#' + ch + ';';
57087 function Renderer(options) {
57088 this.options = options || {};
57091 Renderer.prototype.code = function(code, lang, escaped) {
57092 if (this.options.highlight) {
57093 var out = this.options.highlight(code, lang);
57094 if (out != null && out !== code) {
57101 return '<pre><code>'
57102 + (escaped ? code : escape(code, true))
57103 + '\n</code></pre>';
57106 return '<pre><code class="'
57107 + this.options.langPrefix
57108 + escape(lang, true)
57110 + (escaped ? code : escape(code, true))
57111 + '\n</code></pre>\n';
57114 Renderer.prototype.blockquote = function(quote) {
57115 return '<blockquote>\n' + quote + '</blockquote>\n';
57118 Renderer.prototype.html = function(html) {
57122 Renderer.prototype.heading = function(text, level, raw) {
57126 + this.options.headerPrefix
57127 + raw.toLowerCase().replace(/[^\w]+/g, '-')
57135 Renderer.prototype.hr = function() {
57136 return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
57139 Renderer.prototype.list = function(body, ordered) {
57140 var type = ordered ? 'ol' : 'ul';
57141 return '<' + type + '>\n' + body + '</' + type + '>\n';
57144 Renderer.prototype.listitem = function(text) {
57145 return '<li>' + text + '</li>\n';
57148 Renderer.prototype.paragraph = function(text) {
57149 return '<p>' + text + '</p>\n';
57152 Renderer.prototype.table = function(header, body) {
57163 Renderer.prototype.tablerow = function(content) {
57164 return '<tr>\n' + content + '</tr>\n';
57167 Renderer.prototype.tablecell = function(content, flags) {
57168 var type = flags.header ? 'th' : 'td';
57169 var tag = flags.align
57170 ? '<' + type + ' style="text-align:' + flags.align + '">'
57171 : '<' + type + '>';
57172 return tag + content + '</' + type + '>\n';
57175 // span level renderer
57176 Renderer.prototype.strong = function(text) {
57177 return '<strong>' + text + '</strong>';
57180 Renderer.prototype.em = function(text) {
57181 return '<em>' + text + '</em>';
57184 Renderer.prototype.codespan = function(text) {
57185 return '<code>' + text + '</code>';
57188 Renderer.prototype.br = function() {
57189 return this.options.xhtml ? '<br/>' : '<br>';
57192 Renderer.prototype.del = function(text) {
57193 return '<del>' + text + '</del>';
57196 Renderer.prototype.link = function(href, title, text) {
57197 if (this.options.sanitize) {
57199 var prot = decodeURIComponent(unescape(href))
57200 .replace(/[^\w:]/g, '')
57205 if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
57209 var out = '<a href="' + href + '"';
57211 out += ' title="' + title + '"';
57213 out += '>' + text + '</a>';
57217 Renderer.prototype.image = function(href, title, text) {
57218 var out = '<img src="' + href + '" alt="' + text + '"';
57220 out += ' title="' + title + '"';
57222 out += this.options.xhtml ? '/>' : '>';
57226 Renderer.prototype.text = function(text) {
57231 * Parsing & Compiling
57234 function Parser(options) {
57237 this.options = options || marked.defaults;
57238 this.options.renderer = this.options.renderer || new Renderer;
57239 this.renderer = this.options.renderer;
57240 this.renderer.options = this.options;
57244 * Static Parse Method
57247 Parser.parse = function(src, options, renderer) {
57248 var parser = new Parser(options, renderer);
57249 return parser.parse(src);
57256 Parser.prototype.parse = function(src) {
57257 this.inline = new InlineLexer(src.links, this.options, this.renderer);
57258 this.tokens = src.reverse();
57261 while (this.next()) {
57272 Parser.prototype.next = function() {
57273 return this.token = this.tokens.pop();
57277 * Preview Next Token
57280 Parser.prototype.peek = function() {
57281 return this.tokens[this.tokens.length - 1] || 0;
57285 * Parse Text Tokens
57288 Parser.prototype.parseText = function() {
57289 var body = this.token.text;
57291 while (this.peek().type === 'text') {
57292 body += '\n' + this.next().text;
57295 return this.inline.output(body);
57299 * Parse Current Token
57302 Parser.prototype.tok = function() {
57303 switch (this.token.type) {
57308 return this.renderer.hr();
57311 return this.renderer.heading(
57312 this.inline.output(this.token.text),
57317 return this.renderer.code(this.token.text,
57319 this.token.escaped);
57332 for (i = 0; i < this.token.header.length; i++) {
57333 flags = { header: true, align: this.token.align[i] };
57334 cell += this.renderer.tablecell(
57335 this.inline.output(this.token.header[i]),
57336 { header: true, align: this.token.align[i] }
57339 header += this.renderer.tablerow(cell);
57341 for (i = 0; i < this.token.cells.length; i++) {
57342 row = this.token.cells[i];
57345 for (j = 0; j < row.length; j++) {
57346 cell += this.renderer.tablecell(
57347 this.inline.output(row[j]),
57348 { header: false, align: this.token.align[j] }
57352 body += this.renderer.tablerow(cell);
57354 return this.renderer.table(header, body);
57356 case 'blockquote_start': {
57359 while (this.next().type !== 'blockquote_end') {
57360 body += this.tok();
57363 return this.renderer.blockquote(body);
57365 case 'list_start': {
57367 , ordered = this.token.ordered;
57369 while (this.next().type !== 'list_end') {
57370 body += this.tok();
57373 return this.renderer.list(body, ordered);
57375 case 'list_item_start': {
57378 while (this.next().type !== 'list_item_end') {
57379 body += this.token.type === 'text'
57384 return this.renderer.listitem(body);
57386 case 'loose_item_start': {
57389 while (this.next().type !== 'list_item_end') {
57390 body += this.tok();
57393 return this.renderer.listitem(body);
57396 var html = !this.token.pre && !this.options.pedantic
57397 ? this.inline.output(this.token.text)
57399 return this.renderer.html(html);
57401 case 'paragraph': {
57402 return this.renderer.paragraph(this.inline.output(this.token.text));
57405 return this.renderer.paragraph(this.parseText());
57414 function escape(html, encode) {
57416 .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
57417 .replace(/</g, '<')
57418 .replace(/>/g, '>')
57419 .replace(/"/g, '"')
57420 .replace(/'/g, ''');
57423 function unescape(html) {
57424 // explicitly match decimal, hex, and named HTML entities
57425 return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
57426 n = n.toLowerCase();
57427 if (n === 'colon') return ':';
57428 if (n.charAt(0) === '#') {
57429 return n.charAt(1) === 'x'
57430 ? String.fromCharCode(parseInt(n.substring(2), 16))
57431 : String.fromCharCode(+n.substring(1));
57437 function replace(regex, opt) {
57438 regex = regex.source;
57440 return function self(name, val) {
57441 if (!name) return new RegExp(regex, opt);
57442 val = val.source || val;
57443 val = val.replace(/(^|[^\[])\^/g, '$1');
57444 regex = regex.replace(name, val);
57452 function merge(obj) {
57457 for (; i < arguments.length; i++) {
57458 target = arguments[i];
57459 for (key in target) {
57460 if (Object.prototype.hasOwnProperty.call(target, key)) {
57461 obj[key] = target[key];
57474 function marked(src, opt, callback) {
57475 if (callback || typeof opt === 'function') {
57481 opt = merge({}, marked.defaults, opt || {});
57483 var highlight = opt.highlight
57489 tokens = Lexer.lex(src, opt);
57491 return callback(e);
57494 pending = tokens.length;
57496 var done = function(err) {
57498 opt.highlight = highlight;
57499 return callback(err);
57505 out = Parser.parse(tokens, opt);
57510 opt.highlight = highlight;
57514 : callback(null, out);
57517 if (!highlight || highlight.length < 3) {
57521 delete opt.highlight;
57523 if (!pending) return done();
57525 for (; i < tokens.length; i++) {
57527 if (token.type !== 'code') {
57528 return --pending || done();
57530 return highlight(token.text, token.lang, function(err, code) {
57531 if (err) return done(err);
57532 if (code == null || code === token.text) {
57533 return --pending || done();
57536 token.escaped = true;
57537 --pending || done();
57545 if (opt) opt = merge({}, marked.defaults, opt);
57546 return Parser.parse(Lexer.lex(src, opt), opt);
57548 e.message += '\nPlease report this to https://github.com/chjj/marked.';
57549 if ((opt || marked.defaults).silent) {
57550 return '<p>An error occured:</p><pre>'
57551 + escape(e.message + '', true)
57563 marked.setOptions = function(opt) {
57564 merge(marked.defaults, opt);
57568 marked.defaults = {
57579 langPrefix: 'lang-',
57580 smartypants: false,
57582 renderer: new Renderer,
57590 marked.Parser = Parser;
57591 marked.parser = Parser.parse;
57593 marked.Renderer = Renderer;
57595 marked.Lexer = Lexer;
57596 marked.lexer = Lexer.lex;
57598 marked.InlineLexer = InlineLexer;
57599 marked.inlineLexer = InlineLexer.output;
57601 marked.parse = marked;
57604 module.exports = marked;
57607 }).call(function() {
57608 return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
57612 // toggles the visibility of ui elements, using a combination of the
57613 // hide class, which sets display=none, and a d3 transition for opacity.
57614 // this will cause blinking when called repeatedly, so check that the
57615 // value actually changes between calls.
57616 function uiToggle(show, callback) {
57617 return function(selection$$1) {
57619 .style('opacity', show ? 0 : 1)
57620 .classed('hide', false)
57622 .style('opacity', show ? 1 : 0)
57623 .on('end', function() {
57625 .classed('hide', !show)
57626 .style('opacity', null);
57627 if (callback) callback.apply(this);
57632 // Tooltips and svg mask used to highlight certain features
57633 function d3curtain() {
57635 var dispatch$$1 = dispatch(),
57636 surface = select(null),
57637 tooltip = select(null),
57638 darkness = select(null);
57640 function curtain(selection$$1) {
57641 surface = selection$$1
57643 .attr('id', 'curtain')
57644 .style('z-index', 1000)
57645 .style('pointer-events', 'none')
57646 .style('position', 'absolute')
57650 darkness = surface.append('path')
57653 .attr('class', 'curtain-darkness');
57655 select(window).on('resize.curtain', resize);
57657 tooltip = selection$$1.append('div')
57658 .attr('class', 'tooltip')
57659 .style('z-index', 1002);
57663 .attr('class', 'tooltip-arrow');
57667 .attr('class', 'tooltip-inner');
57672 function resize() {
57674 .attr('width', window.innerWidth)
57675 .attr('height', window.innerHeight);
57676 curtain.cut(darkness.datum());
57681 curtain.reveal = function(box, text$$1, tooltipclass, duration) {
57682 if (typeof box === 'string') box = select(box).node();
57683 if (box.getBoundingClientRect) box = box.getBoundingClientRect();
57685 curtain.cut(box, duration);
57688 // pseudo markdown bold text hack
57689 var parts = text$$1.split('**');
57690 var html$$1 = parts[0] ? '<span>' + parts[0] + '</span>' : '';
57691 if (parts[1]) html$$1 += '<span class="bold">' + parts[1] + '</span>';
57693 var selection$$1 = tooltip
57694 .classed('in', true)
57695 .selectAll('.tooltip-inner')
57698 var dimensions = utilGetDimensions(selection$$1, true),
57699 w = window.innerWidth,
57700 h = window.innerHeight,
57703 // trim box dimensions to just the portion that fits in the window..
57704 if (box.top + box.height > h) {
57705 box.height -= (box.top + box.height - h);
57707 if (box.left + box.width > w) {
57708 box.width -= (box.left + box.width - w);
57711 // determine tooltip placement..
57712 if (box.top + box.height < Math.min(100, box.width + box.left)) {
57714 pos = [box.left + box.width / 2 - dimensions[0] / 2, box.top + box.height];
57716 } else if (box.left + box.width + 300 < w) {
57718 pos = [box.left + box.width, box.top + box.height / 2 - dimensions[1] / 2];
57720 } else if (box.left > 300) {
57722 pos = [box.left - 200, box.top + box.height / 2 - dimensions[1] / 2];
57726 pos = [box.left, box.top + box.height];
57730 Math.min(Math.max(10, pos[0]), w - dimensions[0] - 10),
57731 Math.min(Math.max(10, pos[1]), h - dimensions[1] - 10)
57734 if (duration !== 0 || !tooltip.classed(side)) {
57735 tooltip.call(uiToggle(true));
57739 .style('top', pos[1] + 'px')
57740 .style('left', pos[0] + 'px')
57741 .attr('class', 'curtain-tooltip tooltip in ' + side + ' ' + tooltipclass);
57744 tooltip.call(uiToggle(false));
57749 curtain.cut = function(datum, duration) {
57750 darkness.datum(datum)
57753 (duration === 0 ? darkness : darkness.transition().duration(duration || 600))
57754 .attr('d', function(d) {
57755 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
57756 window.innerWidth + ',' + window.innerHeight + 'L' +
57757 window.innerWidth + ',0 Z';
57759 if (!d) return string;
57760 return string + 'M' +
57761 d.left + ',' + d.top + 'L' +
57762 d.left + ',' + (d.top + d.height) + 'L' +
57763 (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
57764 (d.left + d.width) + ',' + (d.top) + 'Z';
57770 curtain.remove = function() {
57776 return utilRebind(curtain, dispatch$$1, 'on');
57779 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"]}};
57781 function pointBox(point, context) {
57782 var rect = context.surfaceRect();
57783 point = context.projection(point);
57785 left: point[0] + rect.left - 30,
57786 top: point[1] + rect.top - 50,
57793 function pad$1(box, padding, context) {
57794 if (box instanceof Array) {
57795 var rect = context.surfaceRect();
57796 box = context.projection(box);
57798 left: box[0] + rect.left,
57799 top: box[1] + rect.top
57803 left: box.left - padding,
57804 top: box.top - padding,
57805 width: (box.width || 0) + 2 * padding,
57806 height: (box.width || 0) + 2 * padding
57811 function icon(name, svgklass) {
57812 return '<svg class="icon ' + (svgklass || '') + '">' +
57813 '<use xlink:href="' + name + '"></use></svg>';
57816 function uiIntroNavigation(context, reveal) {
57817 var dispatch$$1 = dispatch('done'),
57821 title: 'intro.navigation.title'
57825 function set$$1(f, t$$1) {
57826 timeouts.push(window.setTimeout(f, t$$1));
57830 function eventCancel() {
57831 event.stopPropagation();
57832 event.preventDefault();
57836 step.enter = function() {
57837 var rect = context.surfaceRect(),
57839 left: rect.left + 10,
57840 top: rect.top + 70,
57841 width: rect.width - 70,
57842 height: rect.height - 170
57845 context.map().centerZoom([-85.63591, 41.94285], 19);
57847 reveal(map$$1, t('intro.navigation.drag'));
57849 context.map().on('move.intro', lodash.debounce(function() {
57850 context.map().on('move.intro', null);
57852 context.on('enter.intro', inspectTownHall);
57856 function townhall() {
57857 var hall = [-85.63645945147184, 41.942986488012565];
57858 var point = context.projection(hall);
57860 if (point[0] < 0 || point[0] > rect.width ||
57861 point[1] < 0 || point[1] > rect.height) {
57862 context.map().center(hall);
57865 var box = pointBox(hall, context);
57866 reveal(box, t('intro.navigation.select'));
57868 context.map().on('move.intro', function() {
57869 var box = pointBox(hall, context);
57870 reveal(box, t('intro.navigation.select'), {duration: 0});
57875 function inspectTownHall(mode) {
57876 if (mode.id !== 'select') return;
57877 context.on('enter.intro', null);
57878 context.map().on('move.intro', null);
57879 set$$1(function() {
57880 reveal('.entity-editor-pane',
57881 t('intro.navigation.pane', { button: icon('#icon-close', 'pre-text') }));
57882 context.on('exit.intro', streetSearch);
57887 function streetSearch() {
57888 context.on('exit.intro', null);
57889 reveal('.search-header input',
57890 t('intro.navigation.search', { name: t('intro.graph.spring_st') }));
57891 select('.search-header input')
57892 .on('keyup.intro', searchResult);
57896 function searchResult() {
57897 var first = select('.feature-list-item:nth-child(0n+2)'), // skip No Results item
57898 firstName = first.select('.entity-name'),
57899 name = t('intro.graph.spring_st');
57901 if (!firstName.empty() && firstName.text() === name) {
57902 reveal(first.node(), t('intro.navigation.choose', { name: name }));
57903 context.on('exit.intro', selectedStreet);
57904 select('.search-header input')
57905 .on('keydown.intro', eventCancel, true)
57906 .on('keyup.intro', null);
57911 function selectedStreet() {
57912 var springSt = [-85.63585099140167, 41.942506848938926];
57913 context.map().center(springSt);
57914 context.on('exit.intro', function() {
57915 dispatch$$1.call('done');
57918 set$$1(function() {
57919 reveal('.entity-editor-pane',
57920 t('intro.navigation.chosen', {
57921 name: t('intro.graph.spring_st'),
57922 button: icon('#icon-close', 'pre-text')
57929 step.exit = function() {
57930 timeouts.forEach(window.clearTimeout);
57931 context.map().on('move.intro', null);
57932 context.on('enter.intro', null);
57933 context.on('exit.intro', null);
57934 select('.search-header input')
57935 .on('keydown.intro', null)
57936 .on('keyup.intro', null);
57940 return utilRebind(step, dispatch$$1, 'on');
57943 function uiIntroPoint(context, reveal) {
57944 var dispatch$$1 = dispatch('done'),
57948 title: 'intro.points.title'
57952 function setTimeout(f, t$$1) {
57953 timeouts.push(window.setTimeout(f, t$$1));
57957 function eventCancel() {
57958 event.stopPropagation();
57959 event.preventDefault();
57963 step.enter = function() {
57964 context.map().centerZoom([-85.63279, 41.94394], 19);
57965 reveal('button.add-point',
57966 t('intro.points.add', { button: icon('#icon-point', 'pre-text') }),
57967 { tooltipClass: 'intro-points-add' });
57969 var corner = [-85.632481,41.944094];
57971 context.on('enter.intro', addPoint);
57974 function addPoint(mode) {
57975 if (mode.id !== 'add-point') return;
57976 context.on('enter.intro', enterSelect);
57978 var pointBox$$1 = pad$1(corner, 150, context);
57979 reveal(pointBox$$1, t('intro.points.place'));
57981 context.map().on('move.intro', function() {
57982 pointBox$$1 = pad$1(corner, 150, context);
57983 reveal(pointBox$$1, t('intro.points.place'), {duration: 0});
57988 function enterSelect(mode) {
57989 if (mode.id !== 'select') return;
57990 context.map().on('move.intro', null);
57991 context.on('enter.intro', null);
57993 setTimeout(function() {
57994 reveal('.preset-search-input',
57995 t('intro.points.search', {name: context.presets().item('amenity/cafe').name()}));
57996 select('.preset-search-input').on('keyup.intro', keySearch);
58001 function keySearch() {
58002 var first = select('.preset-list-item:first-child');
58003 if (first.classed('preset-amenity-cafe')) {
58004 reveal(first.select('.preset-list-button').node(), t('intro.points.choose'));
58005 utilBindOnce(context.history(), 'change.intro', selectedPreset);
58006 select('.preset-search-input')
58007 .on('keydown.intro', eventCancel, true)
58008 .on('keyup.intro', null);
58013 function selectedPreset() {
58014 setTimeout(function() {
58015 reveal('.entity-editor-pane', t('intro.points.describe'), {tooltipClass: 'intro-points-describe'});
58016 context.history().on('change.intro', closeEditor);
58017 context.on('exit.intro', selectPoint);
58022 function closeEditor() {
58023 select('.preset-search-input').on('keydown.intro', null);
58024 context.history().on('change.intro', null);
58025 reveal('.entity-editor-pane',
58026 t('intro.points.close', { button: icon('#icon-apply', 'pre-text') }));
58030 function selectPoint() {
58031 context.on('exit.intro', null);
58032 context.history().on('change.intro', null);
58033 context.on('enter.intro', enterReselect);
58035 var pointBox$$1 = pad$1(corner, 150, context);
58036 reveal(pointBox$$1, t('intro.points.reselect'));
58038 context.map().on('move.intro', function() {
58039 pointBox$$1 = pad$1(corner, 150, context);
58040 reveal(pointBox$$1, t('intro.points.reselect'), {duration: 0});
58045 function enterReselect(mode) {
58046 if (mode.id !== 'select') return;
58047 context.map().on('move.intro', null);
58048 context.on('enter.intro', null);
58050 setTimeout(function() {
58051 reveal('.entity-editor-pane',
58052 t('intro.points.fixname', { button: icon('#icon-apply', 'pre-text') }));
58053 context.on('exit.intro', deletePoint);
58058 function deletePoint() {
58059 context.on('exit.intro', null);
58060 context.on('enter.intro', enterDelete);
58062 var pointBox$$1 = pad$1(corner, 150, context);
58063 reveal(pointBox$$1, t('intro.points.reselect_delete'));
58065 context.map().on('move.intro', function() {
58066 pointBox$$1 = pad$1(corner, 150, context);
58067 reveal(pointBox$$1, t('intro.points.reselect_delete'), {duration: 0});
58072 function enterDelete(mode) {
58073 if (mode.id !== 'select') return;
58074 context.map().on('move.intro', null);
58075 context.on('enter.intro', null);
58076 context.on('exit.intro', deletePoint);
58077 context.map().on('move.intro', deletePoint);
58078 context.history().on('change.intro', deleted);
58080 setTimeout(function() {
58081 var node = select('.radial-menu-item-delete').node();
58082 var pointBox$$1 = pad$1(node.getBoundingClientRect(), 50, context);
58083 reveal(pointBox$$1,
58084 t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }));
58089 function deleted(changed) {
58090 if (changed.deleted().length) {
58091 dispatch$$1.call('done');
58098 step.exit = function() {
58099 timeouts.forEach(window.clearTimeout);
58100 context.on('exit.intro', null);
58101 context.on('enter.intro', null);
58102 context.map().on('move.intro', null);
58103 context.history().on('change.intro', null);
58104 select('.preset-search-input')
58105 .on('keyup.intro', null)
58106 .on('keydown.intro', null);
58109 return utilRebind(step, dispatch$$1, 'on');
58112 function uiIntroArea(context, reveal) {
58113 var dispatch$$1 = dispatch('done'),
58117 title: 'intro.areas.title'
58121 step.enter = function() {
58122 var playground = [-85.63552, 41.94159],
58123 corner = [-85.63565411045074, 41.9417715536927];
58124 context.map().centerZoom(playground, 19);
58125 reveal('button.add-area',
58126 t('intro.areas.add', { button: icon('#icon-area', 'pre-text') }),
58127 { tooltipClass: 'intro-areas-add' });
58129 context.on('enter.intro', addArea);
58132 function addArea(mode) {
58133 if (mode.id !== 'add-area') return;
58134 context.on('enter.intro', drawArea);
58136 var padding = 120 * Math.pow(2, context.map().zoom() - 19);
58137 var pointBox$$1 = pad$1(corner, padding, context);
58138 reveal(pointBox$$1, t('intro.areas.corner'));
58140 context.map().on('move.intro', function() {
58141 padding = 120 * Math.pow(2, context.map().zoom() - 19);
58142 pointBox$$1 = pad$1(corner, padding, context);
58143 reveal(pointBox$$1, t('intro.areas.corner'), {duration: 0});
58148 function drawArea(mode) {
58149 if (mode.id !== 'draw-area') return;
58150 context.on('enter.intro', enterSelect);
58152 var padding = 150 * Math.pow(2, context.map().zoom() - 19);
58153 var pointBox$$1 = pad$1(playground, padding, context);
58154 reveal(pointBox$$1, t('intro.areas.place'));
58156 context.map().on('move.intro', function() {
58157 padding = 150 * Math.pow(2, context.map().zoom() - 19);
58158 pointBox$$1 = pad$1(playground, padding, context);
58159 reveal(pointBox$$1, t('intro.areas.place'), {duration: 0});
58164 function enterSelect(mode) {
58165 if (mode.id !== 'select') return;
58166 context.map().on('move.intro', null);
58167 context.on('enter.intro', null);
58169 timeout$$1 = setTimeout(function() {
58170 reveal('.preset-search-input',
58171 t('intro.areas.search',
58172 { name: context.presets().item('leisure/playground').name() }));
58173 select('.preset-search-input').on('keyup.intro', keySearch);
58178 function keySearch() {
58179 var first = select('.preset-list-item:first-child');
58180 if (first.classed('preset-leisure-playground')) {
58181 reveal(first.select('.preset-list-button').node(), t('intro.areas.choose'));
58182 utilBindOnce(context.history(), 'change.intro', selectedPreset);
58183 select('.preset-search-input').on('keyup.intro', null);
58188 function selectedPreset() {
58190 t('intro.areas.describe', { button: icon('#icon-apply', 'pre-text') }));
58191 context.on('exit.intro', function() {
58192 dispatch$$1.call('done');
58198 step.exit = function() {
58199 window.clearTimeout(timeout$$1);
58200 context.on('enter.intro', null);
58201 context.on('exit.intro', null);
58202 context.history().on('change.intro', null);
58203 context.map().on('move.intro', null);
58204 select('.preset-search-input').on('keyup.intro', null);
58208 return utilRebind(step, dispatch$$1, 'on');
58211 function uiIntroLine(context, reveal) {
58212 var dispatch$$1 = dispatch('done'),
58214 centroid = [-85.62830, 41.95699],
58215 midpoint = [-85.62975395449628, 41.95787501510204],
58216 start = [-85.6297754121684, 41.95805253325314],
58217 intersection = [-85.62974496187628, 41.95742515554585],
58218 targetId = 'w17965351',
58223 title: 'intro.lines.title'
58227 function timeout$$1(f, t$$1) {
58228 timeouts.push(window.setTimeout(f, t$$1));
58232 function eventCancel() {
58233 event.stopPropagation();
58234 event.preventDefault();
58238 step.enter = function() {
58239 context.map().centerZoom(start, 18);
58240 reveal('button.add-line',
58241 t('intro.lines.add', { button: icon('#icon-line', 'pre-text') }),
58242 { tooltipClass: 'intro-lines-add' });
58244 context.on('enter.intro', addLine);
58247 function addLine(mode) {
58248 if (mode.id !== 'add-line') return;
58250 context.on('enter.intro', drawLine);
58252 var padding = 150 * Math.pow(2, context.map().zoom() - 18);
58253 var pointBox$$1 = pad$1(start, padding, context);
58254 reveal(pointBox$$1, t('intro.lines.start'));
58256 context.map().on('move.intro', function() {
58257 padding = 150 * Math.pow(2, context.map().zoom() - 18);
58258 pointBox$$1 = pad$1(start, padding, context);
58259 reveal(pointBox$$1, t('intro.lines.start'), {duration: 0});
58264 function drawLine(mode) {
58265 if (mode.id !== 'draw-line') return;
58266 drawId = mode.selectedIDs()[0];
58267 context.history().on('change.intro', checkIntersection);
58268 context.on('enter.intro', retry);
58270 var padding = 300 * Math.pow(2, context.map().zoom() - 19);
58271 var pointBox$$1 = pad$1(midpoint, padding, context);
58272 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}));
58274 context.map().on('move.intro', function() {
58275 padding = 300 * Math.pow(2, context.map().zoom() - 19);
58276 pointBox$$1 = pad$1(midpoint, padding, context);
58277 reveal(pointBox$$1, t('intro.lines.intersect', {name: t('intro.graph.flower_st')}), {duration: 0});
58282 // ended line before creating intersection
58283 function retry(mode) {
58284 if (mode.id !== 'select') return;
58285 context.history().on('change.intro', null);
58286 var pointBox$$1 = pad$1(intersection, 30, context);
58287 reveal(pointBox$$1, t('intro.lines.restart', {name: t('intro.graph.flower_st')}));
58288 select(window).on('mousedown.intro', eventCancel, true);
58290 timeout$$1(step.restart, 3000);
58294 function checkIntersection() {
58296 function joinedTargetWay() {
58297 var drawEntity = drawId && context.hasEntity(drawId);
58303 var drawNodes = context.graph().childNodes(drawEntity);
58304 return lodash.some(drawNodes, function(node) {
58305 return lodash.some(context.graph().parentWays(node), function(parent) {
58306 return parent.id === targetId;
58311 if (joinedTargetWay()) {
58312 context.history().on('change.intro', null);
58313 context.on('enter.intro', enterSelect);
58315 var padding = 900 * Math.pow(2, context.map().zoom() - 19);
58316 var pointBox$$1 = pad$1(centroid, padding, context);
58317 reveal(pointBox$$1, t('intro.lines.finish'));
58319 context.map().on('move.intro', function() {
58320 padding = 900 * Math.pow(2, context.map().zoom() - 19);
58321 pointBox$$1 = pad$1(centroid, padding, context);
58322 reveal(pointBox$$1, t('intro.lines.finish'), {duration: 0});
58328 function enterSelect(mode) {
58329 if (mode.id !== 'select') return;
58330 context.map().on('move.intro', null);
58331 context.on('enter.intro', null);
58332 select('#curtain').style('pointer-events', 'all');
58337 function presetCategory() {
58338 timeout$$1(function() {
58339 select('#curtain').style('pointer-events', 'none');
58340 var road = select('.preset-category-road .preset-list-button');
58341 reveal(road.node(), t('intro.lines.road'));
58342 utilBindOnce(road, 'click.intro', roadCategory);
58347 function roadCategory() {
58348 timeout$$1(function() {
58349 var grid = select('.subgrid');
58350 reveal(grid.node(), t('intro.lines.residential'));
58351 utilBindOnce(grid.selectAll(':not(.preset-highway-residential) .preset-list-button'),
58352 'click.intro', retryPreset);
58353 utilBindOnce(grid.selectAll('.preset-highway-residential .preset-list-button'),
58354 'click.intro', roadDetails);
58359 // selected wrong road type
58360 function retryPreset() {
58361 timeout$$1(function() {
58362 var preset = select('.entity-editor-pane .preset-list-button');
58363 reveal(preset.node(), t('intro.lines.wrong_preset'));
58364 utilBindOnce(preset, 'click.intro', presetCategory);
58369 function roadDetails() {
58371 t('intro.lines.describe', { button: icon('#icon-apply', 'pre-text') }));
58372 context.on('exit.intro', function() {
58373 dispatch$$1.call('done');
58379 step.restart = function() {
58385 step.exit = function() {
58386 select(window).on('mousedown.intro', null, true);
58387 select('#curtain').style('pointer-events', 'none');
58388 timeouts.forEach(window.clearTimeout);
58389 context.on('enter.intro', null);
58390 context.on('exit.intro', null);
58391 context.map().on('move.intro', null);
58392 context.history().on('change.intro', null);
58394 context.replace(actionDeleteMultiple([drawId]));
58399 return utilRebind(step, dispatch$$1, 'on');
58402 function uiIntroStartEditing(context, reveal) {
58403 var dispatch$$1 = dispatch('done', 'startEditing'),
58408 title: 'intro.startediting.title'
58412 function timeout$$1(f, t$$1) {
58413 timeouts.push(window.setTimeout(f, t$$1));
58417 step.enter = function() {
58418 reveal('.map-control.help-control',
58419 t('intro.startediting.help', { button: icon('#icon-help', 'pre-text') }));
58421 timeout$$1(function() {
58422 reveal('#bar button.save', t('intro.startediting.save'));
58425 timeout$$1(function() {
58426 reveal('#surface');
58429 timeout$$1(function() {
58430 modalSelection = uiModal(context.container());
58432 modalSelection.select('.modal')
58433 .attr('class', 'modal-splash modal col6');
58435 modalSelection.selectAll('.close').remove();
58437 var startbutton = modalSelection.select('.content')
58438 .attr('class', 'fillL')
58440 .attr('class', 'modal-section huge-modal-button')
58441 .on('click', function() {
58442 modalSelection.remove();
58447 .attr('class','illustration');
58451 .text(t('intro.startediting.start'));
58453 dispatch$$1.call('startEditing');
58458 step.exit = function() {
58459 if (modalSelection) { modalSelection.remove(); }
58460 timeouts.forEach(window.clearTimeout);
58464 return utilRebind(step, dispatch$$1, 'on');
58467 var sampleIntros = {
58468 navigation: uiIntroNavigation,
58469 point: uiIntroPoint,
58472 startEditing: uiIntroStartEditing
58476 function uiIntro(context) {
58479 function localizedName(id) {
58481 n2140018997: 'city_hall',
58482 n367813436: 'fire_department',
58483 w203988286: 'memory_isle_park',
58484 w203972937: 'riverwalk_trail',
58485 w203972938: 'riverwalk_trail',
58486 w203972940: 'riverwalk_trail',
58487 w41785752: 'w_michigan_ave',
58488 w134150789: 'w_michigan_ave',
58489 w134150795: 'w_michigan_ave',
58490 w134150800: 'w_michigan_ave',
58491 w134150811: 'w_michigan_ave',
58492 w134150802: 'e_michigan_ave',
58493 w134150836: 'e_michigan_ave',
58494 w41074896: 'e_michigan_ave',
58495 w17965834: 'spring_st',
58496 w203986457: 'scidmore_park',
58497 w203049587: 'petting_zoo',
58498 w17967397: 'n_andrews_st',
58499 w17967315: 's_andrews_st',
58500 w17967326: 'n_constantine_st',
58501 w17966400: 's_constantine_st',
58502 w170848823: 'rocky_river',
58503 w170848824: 'rocky_river',
58504 w170848331: 'rocky_river',
58505 w17967752: 'railroad_dr',
58506 w17965998: 'conrail_rr',
58507 w134150845: 'conrail_rr',
58508 w170989131: 'st_joseph_river',
58509 w143497377: 'n_main_st',
58510 w134150801: 's_main_st',
58511 w134150830: 's_main_st',
58512 w17966462: 's_main_st',
58513 w17967734: 'water_st',
58514 w17964996: 'foster_st',
58515 w170848330: 'portage_river',
58516 w17965351: 'flower_st',
58517 w17965502: 'elm_st',
58518 w17965402: 'walnut_st',
58519 w17964793: 'morris_ave',
58520 w17967444: 'east_st',
58521 w17966984: 'portage_ave'
58524 return features[id] && t('intro.graph.' + features[id]);
58528 var introGraph = {};
58530 for (var key in dataIntroGraph) {
58531 introGraph[key] = osmEntity$$1(dataIntroGraph[key]);
58532 var name = localizedName(key);
58534 introGraph[key].tags.name = name;
58539 function intro(selection$$1) {
58540 context.enter(modeBrowse(context));
58542 // Save current map state
58543 var history = context.history().toJSON(),
58544 hash = window.location.hash,
58545 center = context.map().center(),
58546 zoom$$1 = context.map().zoom(),
58547 background = context.background().baseLayerSource(),
58548 opacity = selectAll('#map .layer-background').style('opacity'),
58549 loadedTiles = context.connection().loadedTiles(),
58550 baseEntities = context.history().graph().base().entities;
58553 context.inIntro(true);
58555 // Load semi-real data used in intro
58556 context.connection().toggle(false).reset();
58557 context.history().reset();
58559 context.history().merge(values(coreGraph$$1().load(introGraph).entities));
58560 context.background().bing();
58562 selectAll('#map .layer-background').style('opacity', 1);
58564 var curtain = d3curtain();
58565 selection$$1.call(curtain);
58568 function reveal(box, text$$1, options) {
58569 options = options || {};
58570 curtain.reveal(box,
58572 options.tooltipClass || '',
58577 var steps = ['navigation', 'point', 'area', 'line', 'startEditing'].map(function(step, i) {
58578 var s = sampleIntros[step](context, reveal)
58579 .on('done', function() {
58580 entered.filter(function(d) {
58581 return d.title === s.title;
58582 }).classed('finished', true);
58583 enter(steps[i + 1]);
58588 steps[steps.length - 1].on('startEditing', function() {
58591 selectAll('#map .layer-background').style('opacity', opacity);
58592 context.connection().toggle(true).reset().loadedTiles(loadedTiles);
58593 context.history().reset().merge(values(baseEntities));
58594 context.background().baseLayerSource(background);
58595 if (history) context.history().fromJSON(history, false);
58596 context.map().centerZoom(center, zoom$$1);
58597 window.location.replace(hash);
58598 context.inIntro(false);
58601 var navwrap = selection$$1
58603 .attr('class', 'intro-nav-wrap fillD');
58605 var buttonwrap = navwrap
58607 .attr('class', 'joined')
58608 .selectAll('button.step');
58610 var entered = buttonwrap
58614 .attr('class', 'step')
58615 .on('click', enter);
58619 .text(function(d) { return t(d.title); });
58623 .attr('class', 'status')
58624 .text(' - ' + t('intro.done'));
58629 function enter(newStep) {
58630 if (step) { step.exit(); }
58632 context.enter(modeBrowse(context));
58637 entered.classed('active', function(d) {
58638 return d.title === step.title;
58648 function uiHelp(context) {
58653 'help.editing_saving',
58662 var docs = docKeys.map(function(key) {
58663 var text$$1 = t(key);
58665 title: text$$1.split('\n')[0].replace('#', '').trim(),
58666 html: marked(text$$1.split('\n').slice(1).join('\n'))
58671 function help(selection$$1) {
58678 function toggle() {
58679 if (event) event.preventDefault();
58680 tooltipBehavior.hide(button);
58681 setVisible(!button.classed('active'));
58685 function setVisible(show) {
58686 if (show !== shown) {
58687 button.classed('active', show);
58691 selection$$1.on('mousedown.help-inside', function() {
58692 return event.stopPropagation();
58694 pane.style('display', 'block')
58695 .style('right', '-500px')
58698 .style('right', '0px');
58700 pane.style('right', '0px')
58703 .style('right', '-500px')
58704 .on('end', function() {
58705 select(this).style('display', 'none');
58707 selection$$1.on('mousedown.help-inside', null);
58713 function clickHelp(d, i) {
58714 var rtl = (textDirection === 'rtl');
58715 pane.property('scrollTop', 0);
58716 doctitle.html(d.title);
58719 body.selectAll('a')
58720 .attr('target', '_blank');
58721 menuItems.classed('selected', function(m) {
58722 return m.title === d.title;
58727 nav.call(drawNext).call(drawPrevious);
58729 nav.call(drawPrevious).call(drawNext);
58733 function drawNext(selection$$1) {
58734 if (i < docs.length - 1) {
58735 var nextLink = selection$$1
58737 .attr('class', 'next')
58738 .on('click', function() {
58739 clickHelp(docs[i + 1], i + 1);
58744 .text(docs[i + 1].title)
58745 .call(svgIcon((rtl ? '#icon-backward' : '#icon-forward'), 'inline'));
58750 function drawPrevious(selection$$1) {
58752 var prevLink = selection$$1
58754 .attr('class', 'previous')
58755 .on('click', function() {
58756 clickHelp(docs[i - 1], i - 1);
58760 .call(svgIcon((rtl ? '#icon-forward' : '#icon-backward'), 'inline'))
58762 .text(docs[i - 1].title);
58768 function clickWalkthrough() {
58769 select(document.body).call(uiIntro(context));
58774 var pane = selection$$1.append('div')
58775 .attr('class', 'help-wrap map-overlay fillL col5 content hide'),
58776 tooltipBehavior = tooltip()
58777 .placement((textDirection === 'rtl') ? 'right' : 'left')
58779 .title(uiTooltipHtml(t('help.title'), key)),
58780 button = selection$$1.append('button')
58781 .attr('tabindex', -1)
58782 .on('click', toggle)
58783 .call(svgIcon('#icon-help', 'light'))
58784 .call(tooltipBehavior),
58788 var toc = pane.append('ul')
58789 .attr('class', 'toc');
58791 var menuItems = toc.selectAll('li')
58796 .html(function(d) { return d.title; })
58797 .on('click', clickHelp);
58800 .attr('class','walkthrough')
58802 .text(t('splash.walkthrough'))
58803 .on('click', clickWalkthrough);
58805 var content = pane.append('div')
58806 .attr('class', 'left-content');
58808 var doctitle = content.append('h2')
58809 .text(t('help.title'));
58811 var body = content.append('div')
58812 .attr('class', 'body');
58814 var nav = content.append('div')
58815 .attr('class', 'nav');
58817 clickHelp(docs[0], 0);
58819 var keybinding = d3keybinding('help')
58827 context.surface().on('mousedown.help-outside', hide);
58828 context.container().on('mousedown.help-outside', hide);
58834 function uiInfo(context) {
58835 var key = uiCmd('⌘I'),
58836 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
58840 function info(selection$$1) {
58842 function radiansToMeters(r) {
58843 // using WGS84 authalic radius (6371007.1809 m)
58844 return r * 6371007.1809;
58847 function steradiansToSqmeters(r) {
58848 // http://gis.stackexchange.com/a/124857/40446
58849 return r / (4 * Math.PI) * 510065621724000;
58853 function toLineString(feature) {
58854 if (feature.type === 'LineString') return feature;
58856 var result = { type: 'LineString', coordinates: [] };
58857 if (feature.type === 'Polygon') {
58858 result.coordinates = feature.coordinates[0];
58859 } else if (feature.type === 'MultiPolygon') {
58860 result.coordinates = feature.coordinates[0][0];
58867 function displayLength(m) {
58868 var d = m * (isImperial ? 3.28084 : 1),
58887 // drop unnecessary precision
58888 p = d > 1000 ? 0 : d > 100 ? 1 : 2;
58890 return String(d.toFixed(p)) + ' ' + unit;
58894 function displayArea(m2) {
58895 var d = m2 * (isImperial ? 10.7639111056 : 1),
58896 d1, d2, p1, p2, unit1, unit2;
58899 if (d >= 6969600) { // > 0.25mi² show mi²
58907 if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres
58913 if (d >= 250000) { // > 0.25km² show km²
58921 if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares
58927 // drop unnecessary precision
58928 p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
58929 p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
58931 return String(d1.toFixed(p1)) + ' ' + unit1 +
58932 (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
58936 function redraw() {
58937 if (isHidden) return;
58939 var resolver = context.graph(),
58940 selected = lodash.filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
58941 singular = selected.length === 1 ? selected[0] : null,
58942 extent$$1 = geoExtent$$1(),
58947 .attr('class', 'infobox-heading fillD')
58948 .text(singular || t('infobox.selected', { n: selected.length }));
58950 if (!selected.length) return;
58953 for (var i = 0; i < selected.length; i++) {
58954 entity = context.entity(selected[i]);
58955 extent$$1._extend(entity.extent(resolver));
58957 center = extent$$1.center();
58960 var list = wrap.append('ul');
58962 // multiple features, just display extent center..
58965 .text(t('infobox.center') + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
58969 // single feature, display details..
58970 if (!entity) return;
58971 var geometry = entity.geometry(resolver);
58973 if (geometry === 'line' || geometry === 'area') {
58974 var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
58975 feature = entity.asGeoJSON(resolver),
58976 length = radiansToMeters(d3GeoLength(toLineString(feature))),
58977 lengthLabel = t('infobox.' + (closed ? 'perimeter' : 'length')),
58978 centroid = d3GeoCentroid(feature);
58981 .text(t('infobox.geometry') + ': ' +
58982 (closed ? t('infobox.closed') + ' ' : '') + t('geometry.' + geometry) );
58985 var area$$1 = steradiansToSqmeters(entity.area(resolver));
58987 .text(t('infobox.area') + ': ' + displayArea(area$$1));
58991 .text(lengthLabel + ': ' + displayLength(length));
58994 .text(t('infobox.centroid') + ': ' + centroid[0].toFixed(5) + ', ' + centroid[1].toFixed(5));
58997 var toggle = isImperial ? 'imperial' : 'metric';
58999 .text(t('infobox.' + toggle))
59001 .attr('class', 'button')
59002 .on('click', function() {
59003 event.preventDefault();
59004 isImperial = !isImperial;
59009 var centerLabel = t('infobox.' + (entity.type === 'node' ? 'location' : 'center'));
59012 .text(t('infobox.geometry') + ': ' + t('geometry.' + geometry));
59015 .text(centerLabel + ': ' + center[0].toFixed(5) + ', ' + center[1].toFixed(5));
59020 function toggle() {
59022 event.preventDefault();
59025 isHidden = !isHidden;
59029 .style('display', 'block')
59030 .style('opacity', 1)
59033 .style('opacity', 0)
59034 .on('end', function() {
59035 select(this).style('display', 'none');
59039 .style('display', 'block')
59040 .style('opacity', 0)
59043 .style('opacity', 1)
59044 .on('end', function() {
59051 var wrap = selection$$1.selectAll('.infobox')
59054 wrap = wrap.enter()
59056 .attr('class', 'infobox fillD2')
59057 .style('display', (isHidden ? 'none' : 'block'))
59061 .on('drawn.info', redraw);
59065 var keybinding = d3keybinding('info')
59075 function uiMapData(context) {
59077 features = context.features().keys(),
59078 layers = context.layers(),
59079 fills = ['wireframe', 'partial', 'full'],
59080 fillDefault = context.storage('area-fill') || 'partial',
59081 fillSelected = fillDefault;
59084 function map_data(selection$$1) {
59086 function showsFeature(d) {
59087 return context.features().enabled(d);
59091 function autoHiddenFeature(d) {
59092 return context.features().autoHidden(d);
59096 function clickFeature(d) {
59097 context.features().toggle(d);
59102 function showsFill(d) {
59103 return fillSelected === d;
59107 function setFill(d) {
59108 lodash.each(fills, function(opt) {
59109 context.surface().classed('fill-' + opt, Boolean(opt === d));
59113 if (d !== 'wireframe') {
59115 context.storage('area-fill', d);
59121 function showsLayer(which) {
59122 var layer = layers.layer(which);
59124 return layer.enabled();
59130 function setLayer(which, enabled) {
59131 var layer = layers.layer(which);
59133 layer.enabled(enabled);
59139 function toggleLayer(which) {
59140 setLayer(which, !showsLayer(which));
59144 function clickGpx() {
59145 toggleLayer('gpx');
59149 function clickMapillaryImages() {
59150 toggleLayer('mapillary-images');
59151 if (!showsLayer('mapillary-images')) {
59152 setLayer('mapillary-signs', false);
59157 function clickMapillarySigns() {
59158 toggleLayer('mapillary-signs');
59162 function drawMapillaryItems(selection$$1) {
59163 var mapillaryImages = layers.layer('mapillary-images'),
59164 mapillarySigns = layers.layer('mapillary-signs'),
59165 supportsMapillaryImages = mapillaryImages && mapillaryImages.supported(),
59166 supportsMapillarySigns = mapillarySigns && mapillarySigns.supported(),
59167 showsMapillaryImages = supportsMapillaryImages && mapillaryImages.enabled(),
59168 showsMapillarySigns = supportsMapillarySigns && mapillarySigns.enabled();
59170 var mapillaryList = selection$$1
59171 .selectAll('.layer-list-mapillary')
59174 mapillaryList = mapillaryList.enter()
59176 .attr('class', 'layer-list layer-list-mapillary')
59177 .merge(mapillaryList);
59180 var mapillaryImageLayerItem = mapillaryList
59181 .selectAll('.list-item-mapillary-images')
59182 .data(supportsMapillaryImages ? [0] : []);
59184 mapillaryImageLayerItem.exit()
59187 var enterImages = mapillaryImageLayerItem.enter()
59189 .attr('class', 'list-item-mapillary-images');
59191 var labelImages = enterImages
59194 .title(t('mapillary_images.tooltip'))
59195 .placement('top'));
59199 .attr('type', 'checkbox')
59200 .on('change', clickMapillaryImages);
59204 .text(t('mapillary_images.title'));
59207 var mapillarySignLayerItem = mapillaryList
59208 .selectAll('.list-item-mapillary-signs')
59209 .data(supportsMapillarySigns ? [0] : []);
59211 mapillarySignLayerItem.exit()
59214 var enterSigns = mapillarySignLayerItem.enter()
59216 .attr('class', 'list-item-mapillary-signs');
59218 var labelSigns = enterSigns
59221 .title(t('mapillary_signs.tooltip'))
59222 .placement('top'));
59226 .attr('type', 'checkbox')
59227 .on('change', clickMapillarySigns);
59231 .text(t('mapillary_signs.title'));
59235 mapillaryImageLayerItem = mapillaryImageLayerItem
59236 .merge(enterImages);
59238 mapillaryImageLayerItem
59239 .classed('active', showsMapillaryImages)
59240 .selectAll('input')
59241 .property('checked', showsMapillaryImages);
59244 mapillarySignLayerItem = mapillarySignLayerItem
59245 .merge(enterSigns);
59247 mapillarySignLayerItem
59248 .classed('active', showsMapillarySigns)
59249 .selectAll('input')
59250 .property('disabled', !showsMapillaryImages)
59251 .property('checked', showsMapillarySigns);
59253 mapillarySignLayerItem
59254 .selectAll('label')
59255 .classed('deemphasize', !showsMapillaryImages);
59259 function drawGpxItem(selection$$1) {
59260 var gpx = layers.layer('gpx'),
59261 hasGpx = gpx && gpx.hasGpx(),
59262 showsGpx = hasGpx && gpx.enabled();
59264 var gpxLayerItem = selection$$1
59265 .selectAll('.layer-list-gpx')
59266 .data(gpx ? [0] : []);
59269 gpxLayerItem.exit()
59273 var enter = gpxLayerItem.enter()
59275 .attr('class', 'layer-list layer-list-gpx')
59277 .classed('list-item-gpx', true);
59281 .attr('class', 'list-item-gpx-extent')
59283 .title(t('gpx.zoom'))
59284 .placement((textDirection === 'rtl') ? 'right' : 'left'))
59285 .on('click', function() {
59286 event.preventDefault();
59287 event.stopPropagation();
59290 .call(svgIcon('#icon-search'));
59294 .attr('class', 'list-item-gpx-browse')
59296 .title(t('gpx.browse'))
59297 .placement((textDirection === 'rtl') ? 'right' : 'left'))
59298 .on('click', function() {
59299 select(document.createElement('input'))
59300 .attr('type', 'file')
59301 .on('change', function() {
59302 gpx.files(event.target.files);
59306 .call(svgIcon('#icon-geolocate'));
59308 var labelGpx = enter
59310 .call(tooltip().title(t('gpx.drag_drop')).placement('top'));
59314 .attr('type', 'checkbox')
59315 .on('change', clickGpx);
59319 .text(t('gpx.local_layer'));
59323 gpxLayerItem = gpxLayerItem
59327 .classed('active', showsGpx)
59328 .selectAll('input')
59329 .property('disabled', !hasGpx)
59330 .property('checked', showsGpx);
59333 .selectAll('label')
59334 .classed('deemphasize', !hasGpx);
59338 function drawList(selection$$1, data, type, name, change, active$$1) {
59339 var items = selection$$1.selectAll('li')
59347 var enter = items.enter()
59349 .attr('class', 'layer')
59352 .title(function(d) {
59353 var tip = t(name + '.' + d + '.tooltip'),
59354 key = (d === 'wireframe' ? 'W' : null);
59356 if (name === 'feature' && autoHiddenFeature(d)) {
59357 tip += '<div>' + t('map_data.autohidden') + '</div>';
59359 return uiTooltipHtml(tip, key);
59369 .attr('type', type)
59370 .attr('name', name)
59371 .on('change', change);
59375 .text(function(d) { return t(name + '.' + d + '.description'); });
59382 .classed('active', active$$1)
59383 .selectAll('input')
59384 .property('checked', active$$1)
59385 .property('indeterminate', function(d) {
59386 return (name === 'feature' && autoHiddenFeature(d));
59391 function update() {
59392 dataLayerContainer.call(drawMapillaryItems);
59393 dataLayerContainer.call(drawGpxItem);
59395 fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);
59396 featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
59400 function hidePanel() {
59405 function togglePanel() {
59406 if (event) event.preventDefault();
59407 tooltipBehavior.hide(button);
59408 setVisible(!button.classed('active'));
59412 function toggleWireframe() {
59414 event.preventDefault();
59415 event.stopPropagation();
59417 setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
59418 context.map().pan([0,0]); // trigger a redraw
59422 function setVisible(show) {
59423 if (show !== shown) {
59424 button.classed('active', show);
59429 selection$$1.on('mousedown.map_data-inside', function() {
59430 return event.stopPropagation();
59432 content.style('display', 'block')
59433 .style('right', '-300px')
59436 .style('right', '0px');
59438 content.style('display', 'block')
59439 .style('right', '0px')
59442 .style('right', '-300px')
59443 .on('end', function() {
59444 select(this).style('display', 'none');
59446 selection$$1.on('mousedown.map_data-inside', null);
59452 var content = selection$$1
59454 .attr('class', 'fillL map-overlay col3 content hide'),
59455 tooltipBehavior = tooltip()
59456 .placement((textDirection === 'rtl') ? 'right' : 'left')
59458 .title(uiTooltipHtml(t('map_data.description'), key)),
59459 button = selection$$1
59461 .attr('tabindex', -1)
59462 .on('click', togglePanel)
59463 .call(svgIcon('#icon-data', 'light'))
59464 .call(tooltipBehavior),
59469 .text(t('map_data.title'));
59475 .text(t('map_data.data_layers'))
59477 .classed('hide-toggle', true)
59478 .classed('expanded', true)
59479 .on('click', function() {
59480 var exp = select(this).classed('expanded');
59481 dataLayerContainer.style('display', exp ? 'none' : 'block');
59482 select(this).classed('expanded', !exp);
59483 event.preventDefault();
59486 var dataLayerContainer = content
59488 .attr('class', 'data-data-layers')
59489 .style('display', 'block');
59495 .text(t('map_data.fill_area'))
59497 .classed('hide-toggle', true)
59498 .classed('expanded', false)
59499 .on('click', function() {
59500 var exp = select(this).classed('expanded');
59501 fillContainer.style('display', exp ? 'none' : 'block');
59502 select(this).classed('expanded', !exp);
59503 event.preventDefault();
59506 var fillContainer = content
59508 .attr('class', 'data-area-fills')
59509 .style('display', 'none');
59511 var fillList = fillContainer
59513 .attr('class', 'layer-list layer-fill-list');
59519 .text(t('map_data.map_features'))
59521 .classed('hide-toggle', true)
59522 .classed('expanded', false)
59523 .on('click', function() {
59524 var exp = select(this).classed('expanded');
59525 featureContainer.style('display', exp ? 'none' : 'block');
59526 select(this).classed('expanded', !exp);
59527 event.preventDefault();
59530 var featureContainer = content
59532 .attr('class', 'data-feature-filters')
59533 .style('display', 'none');
59535 var featureList = featureContainer
59537 .attr('class', 'layer-list layer-feature-list');
59541 .on('change.map_data-update', update);
59543 setFill(fillDefault);
59545 var keybinding = d3keybinding('features')
59546 .on(key, togglePanel)
59547 .on('W', toggleWireframe)
59548 .on('B', hidePanel)
59549 .on('H', hidePanel);
59554 context.surface().on('mousedown.map_data-outside', hidePanel);
59555 context.container().on('mousedown.map_data-outside', hidePanel);
59562 function uiModes(context) {
59564 modeAddPoint$$1(context),
59565 modeAddLine$$1(context),
59566 modeAddArea$$1(context)
59570 function editable() {
59571 return context.editable() && context.mode().id !== 'save';
59575 return function(selection$$1) {
59576 var buttons = selection$$1.selectAll('button.add-button')
59579 buttons = buttons.enter()
59581 .attr('tabindex', -1)
59582 .attr('class', function(mode) { return mode.id + ' add-button col4'; })
59583 .on('click.mode-buttons', function(mode) {
59584 if (mode.id === context.mode().id) {
59585 context.enter(modeBrowse(context));
59587 context.enter(mode);
59591 .placement('bottom')
59593 .title(function(mode) {
59594 return uiTooltipHtml(mode.description, mode.key);
59599 .on('move.modes', lodash.debounce(update, 500));
59602 .on('enter.modes', update);
59605 .each(function(d) {
59607 .call(svgIcon('#icon-' + d.button, 'pre-text'));
59612 .attr('class', 'label')
59613 .text(function(mode) { return mode.title; });
59616 .on('enter.editor', function(entered) {
59617 selection$$1.selectAll('button.add-button')
59618 .classed('active', function(mode) { return entered.button === mode.button; });
59619 context.container()
59620 .classed('mode-' + entered.id, true);
59624 .on('exit.editor', function(exited) {
59625 context.container()
59626 .classed('mode-' + exited.id, false);
59629 var keybinding = d3keybinding('mode-buttons');
59631 modes.forEach(function(m) {
59632 keybinding.on(m.key, function() {
59633 if (editable()) context.enter(m);
59641 function update() {
59642 selection$$1.selectAll('button.add-button')
59643 .property('disabled', !editable());
59648 function uiRestore(context) {
59650 return function(selection) {
59651 if (!context.history().lock() || !context.history().restorableChanges())
59654 var modalSelection = uiModal(selection, true);
59656 modalSelection.select('.modal')
59657 .attr('class', 'modal fillL col6');
59659 var introModal = modalSelection.select('.content');
59662 .attr('class','cf');
59666 .attr('class', 'modal-section')
59668 .text(t('restore.heading'));
59672 .attr('class','modal-section')
59674 .text(t('restore.description'));
59676 var buttonWrap = introModal
59678 .attr('class', 'modal-actions cf');
59680 var restore = buttonWrap
59682 .attr('class', 'restore col6')
59683 .text(t('restore.restore'))
59684 .on('click', function() {
59685 context.history().restore();
59686 modalSelection.remove();
59691 .attr('class', 'reset col6')
59692 .text(t('restore.reset'))
59693 .on('click', function() {
59694 context.history().clearSaved();
59695 modalSelection.remove();
59698 restore.node().focus();
59702 function uiSave(context) {
59703 var history = context.history(),
59707 function saving() {
59708 return context.mode().id === 'save';
59713 event.preventDefault();
59714 if (!context.inIntro() && !saving() && history.hasChanges()) {
59715 context.enter(modeSave$$1(context));
59720 function getBackground(numChanges) {
59722 if (numChanges === 0) {
59724 } else if (numChanges <= 50) {
59725 step = numChanges / 50;
59726 return rgb$1('#fff', '#ff8')(step); // white -> yellow
59728 step = Math.min((numChanges - 50) / 50, 1.0);
59729 return rgb$1('#ff8', '#f88')(step); // yellow -> red
59734 return function(selection$$1) {
59735 var numChanges = 0;
59737 function updateCount() {
59738 var _ = history.difference().summary().length;
59739 if (_ === numChanges) return;
59743 .title(uiTooltipHtml(
59744 t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key)
59747 var background = getBackground(numChanges);
59750 .classed('disabled', numChanges === 0)
59751 .classed('has-count', numChanges > 0)
59752 .style('background', background);
59754 button.select('span.count')
59756 .style('background', background)
59757 .style('border-color', background);
59761 var tooltipBehavior = tooltip()
59762 .placement('bottom')
59764 .title(uiTooltipHtml(t('save.no_changes'), key));
59766 var button = selection$$1
59768 .attr('class', 'save col12 disabled')
59769 .attr('tabindex', -1)
59771 .call(tooltipBehavior);
59774 .call(svgIcon('#icon-save', 'pre-text'))
59776 .attr('class', 'label')
59777 .text(t('save.title'));
59781 .attr('class', 'count')
59787 var keybinding = d3keybinding('save')
59788 .on(key, save, true);
59794 .on('change.save', updateCount);
59797 .on('enter.save', function() {
59798 button.property('disabled', saving());
59799 if (saving()) button.call(tooltipBehavior.hide);
59804 function uiScale(context) {
59805 var projection = context.projection,
59806 isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
59811 function scaleDefs(loc1, loc2) {
59812 var lat = (loc2[1] + loc1[1]) / 2,
59813 conversion = (isImperial ? 3.28084 : 1),
59814 dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
59815 scale = { dist: 0, px: 0, text: '' },
59816 buckets, i, val, dLon;
59819 buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
59821 buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
59824 // determine a user-friendly endpoint for the scale
59825 for (i = 0; i < buckets.length; i++) {
59828 scale.dist = Math.floor(dist / val) * val;
59831 scale.dist = +dist.toFixed(2);
59835 dLon = geoMetersToLon(scale.dist / conversion, lat);
59836 scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
59839 if (scale.dist >= 5280) {
59840 scale.dist /= 5280;
59841 scale.text = String(scale.dist) + ' mi';
59843 scale.text = String(scale.dist) + ' ft';
59846 if (scale.dist >= 1000) {
59847 scale.dist /= 1000;
59848 scale.text = String(scale.dist) + ' km';
59850 scale.text = String(scale.dist) + ' m';
59858 function update(selection) {
59859 // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
59860 var dims = context.map().dimensions(),
59861 loc1 = projection.invert([0, dims[1]]),
59862 loc2 = projection.invert([maxLength, dims[1]]),
59863 scale = scaleDefs(loc1, loc2);
59865 selection.select('#scalepath')
59866 .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
59868 selection.select('#scaletext')
59869 .attr('x', scale.px + 8)
59870 .attr('y', tickHeight)
59875 return function(selection) {
59876 function switchUnits() {
59877 isImperial = !isImperial;
59878 selection.call(update);
59881 var g = selection.append('svg')
59882 .attr('id', 'scale')
59883 .on('click', switchUnits)
59885 .attr('transform', 'translate(10,11)');
59887 g.append('path').attr('id', 'scalepath');
59888 g.append('text').attr('id', 'scaletext');
59890 selection.call(update);
59892 context.map().on('move.scale', function() {
59899 function search(x, dims, r) {
59900 if (!dims) dims = 'NSEW';
59901 if (typeof x !== 'string') return { val: null, regex: r };
59902 r = r || /[\s\,]*([\-|\—|\―]?[0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/gi;
59904 if (!m) return { val: null, regex: r };
59905 else if (m[4] && dims.indexOf(m[4]) === -1) return { val: null, regex: r };
59907 val: (((m[1]) ? parseFloat(m[1]) : 0) +
59908 ((m[2] ? parseFloat(m[2]) / 60 : 0)) +
59909 ((m[3] ? parseFloat(m[3]) / 3600 : 0))) *
59910 ((m[4] && m[4] === 'S' || m[4] === 'W') ? -1 : 1),
59917 function pair(x, dims) {
59919 var one = search(x, dims);
59920 if (one.val === null) return null;
59921 var two = search(x, dims, one.regex);
59922 if (two.val === null) return null;
59923 // null if one/two are not contiguous.
59924 if (one.raw + two.raw !== x) return null;
59926 return swapdim(one.val, two.val, one.dim);
59928 return [one.val, two.val];
59932 function swapdim(a, b, dim) {
59933 if (dim === 'N' || dim === 'S') return [a, b];
59934 if (dim === 'W' || dim === 'E') return [b, a];
59937 function uiFeatureList(context) {
59938 var geocodeResults;
59941 function featureList(selection$$1) {
59942 var header = selection$$1
59944 .attr('class', 'header fillL cf');
59946 header.append('h3')
59947 .text(t('inspector.feature_list'));
59949 var searchWrap = selection$$1
59951 .attr('class', 'search-header');
59953 var search = searchWrap
59955 .attr('placeholder', t('inspector.search'))
59956 .attr('type', 'search')
59958 .on('keypress', keypress)
59959 .on('input', inputevent);
59962 .call(svgIcon('#icon-search', 'pre-text'));
59964 var listWrap = selection$$1
59966 .attr('class', 'inspector-body');
59968 var list = listWrap
59970 .attr('class', 'feature-list cf');
59973 .on('exit.feature-list', clearSearch);
59975 .on('drawn.feature-list', mapDrawn);
59978 function keypress() {
59979 var q = search.property('value'),
59980 items = list.selectAll('.feature-list-item');
59981 if (event.keyCode === 13 && q.length && items.size()) {
59982 click(items.datum());
59987 function inputevent() {
59988 geocodeResults = undefined;
59993 function clearSearch() {
59994 search.property('value', '');
59999 function mapDrawn(e) {
60006 function features() {
60009 graph = context.graph(),
60010 q = search.property('value').toLowerCase();
60012 if (!q) return result;
60014 var idMatch = q.match(/^([nwr])([0-9]+)$/);
60019 geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
60020 type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
60025 var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
60027 if (locationMatch) {
60028 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
60032 type: t('inspector.location'),
60033 name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6),
60038 function addEntity(entity) {
60039 if (entity.id in entities || result.length > 200)
60042 entities[entity.id] = true;
60044 var name = utilDisplayName(entity) || '';
60045 if (name.toLowerCase().indexOf(q) >= 0) {
60046 var matched = context.presets().match(entity, graph),
60047 type = (matched && matched.name()) || utilDisplayType(entity.id);
60051 geometry: context.geometry(entity.id),
60057 graph.parentRelations(entity).forEach(function(parent) {
60062 var visible = context.surface().selectAll('.point, .line, .area').nodes();
60063 for (var i = 0; i < visible.length && result.length <= 200; i++) {
60064 addEntity(visible[i].__data__);
60067 (geocodeResults || []).forEach(function(d) {
60068 // https://github.com/openstreetmap/iD/issues/1890
60069 if (d.osm_type && d.osm_id) {
60071 id: osmEntity$$1.id.fromOSM(d.osm_type, d.osm_id),
60072 geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
60073 type: d.type !== 'yes' ? (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' ')
60074 : (d.class.charAt(0).toUpperCase() + d.class.slice(1)).replace('_', ' '),
60075 name: d.display_name,
60076 extent: new geoExtent$$1(
60077 [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
60078 [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
60087 function drawList() {
60088 var value = search.property('value'),
60089 results = features();
60091 list.classed('filtered', value.length);
60093 var noResultsWorldwide = geocodeResults && geocodeResults.length === 0;
60095 var resultsIndicator = list.selectAll('.no-results-item')
60097 .enter().append('button')
60098 .property('disabled', true)
60099 .attr('class', 'no-results-item')
60100 .call(svgIcon('#icon-alert', 'pre-text'));
60102 resultsIndicator.append('span')
60103 .attr('class', 'entity-name');
60105 list.selectAll('.no-results-item .entity-name')
60106 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
60108 list.selectAll('.geocode-item')
60110 .enter().append('button')
60111 .attr('class', 'geocode-item')
60112 .on('click', geocoderSearch)
60114 .attr('class', 'label')
60116 .attr('class', 'entity-name')
60117 .text(t('geocoder.search'));
60119 list.selectAll('.no-results-item')
60120 .style('display', (value.length && !results.length) ? 'block' : 'none');
60122 list.selectAll('.geocode-item')
60123 .style('display', (value && geocodeResults === undefined) ? 'block' : 'none');
60125 list.selectAll('.feature-list-item')
60129 var items = list.selectAll('.feature-list-item')
60130 .data(results, function(d) { return d.id; });
60132 var enter = items.enter()
60133 .insert('button', '.geocode-item')
60134 .attr('class', 'feature-list-item')
60135 .on('mouseover', mouseover)
60136 .on('mouseout', mouseout)
60137 .on('click', click);
60141 .attr('class', 'label');
60143 label.each(function(d) {
60145 .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
60148 label.append('span')
60149 .attr('class', 'entity-type')
60150 .text(function(d) { return d.type; });
60152 label.append('span')
60153 .attr('class', 'entity-name')
60154 .text(function(d) { return d.name; });
60156 enter.style('opacity', 0)
60158 .style('opacity', 1);
60167 function mouseover(d) {
60168 if (d.id === -1) return;
60170 context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
60171 .classed('hover', true);
60175 function mouseout() {
60176 context.surface().selectAll('.hover')
60177 .classed('hover', false);
60181 function click(d) {
60182 event.preventDefault();
60184 context.map().centerZoom([d.location[1], d.location[0]], 20);
60186 else if (d.entity) {
60187 if (d.entity.type === 'node') {
60188 context.map().center(d.entity.loc);
60189 } else if (d.entity.type === 'way') {
60190 var center = context.projection(context.map().center()),
60191 edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
60192 context.map().center(edge.loc);
60194 context.enter(modeSelect(context, [d.entity.id]).suppressMenu(true));
60196 context.zoomToEntity(d.id);
60201 function geocoderSearch() {
60202 services.geocoder.search(search.property('value'), function (err, resp) {
60203 geocodeResults = resp || [];
60210 return featureList;
60213 function uiPresetIcon() {
60214 var preset, geometry;
60217 function presetIcon(selection$$1) {
60218 selection$$1.each(render);
60222 function render() {
60223 var selection$$1 = select(this),
60224 p = preset.apply(this, arguments),
60225 geom = geometry.apply(this, arguments),
60226 picon = p.icon || (geom === 'line' ? 'other-line' : 'marker-stroked'),
60227 isMaki = dataFeatureIcons.indexOf(picon) !== -1;
60229 function tag_classes(p) {
60231 for (var i in p.tags) {
60233 if (p.tags[i] !== '*') {
60234 s += ' tag-' + i + '-' + p.tags[i];
60240 var fill = selection$$1.selectAll('.preset-icon-fill')
60243 fill = fill.enter()
60248 .attr('class', function() {
60249 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
60252 var frame = selection$$1.selectAll('.preset-icon-frame')
60255 frame = frame.enter()
60257 .call(svgIcon('#preset-icon-frame'))
60261 .attr('class', function() {
60262 return 'preset-icon-frame ' + (geom === 'area' ? '' : 'hide');
60266 var icon = selection$$1.selectAll('.preset-icon')
60269 icon = icon.enter()
60271 .attr('class', 'preset-icon')
60276 .attr('class', 'preset-icon preset-icon-' +
60277 (isMaki ? (geom === 'area' ? '24' : '28') : (geom === 'area' ? '44' : '60'))
60280 icon.selectAll('svg')
60281 .attr('class', function() {
60282 return 'icon ' + picon + (isMaki ? '' : tag_classes(p));
60285 icon.selectAll('use')
60286 .attr('href', '#' + picon + (isMaki ? '-15' : ''));
60290 presetIcon.preset = function(_) {
60291 if (!arguments.length) return preset;
60292 preset = utilFunctor(_);
60297 presetIcon.geometry = function(_) {
60298 if (!arguments.length) return geometry;
60299 geometry = utilFunctor(_);
60306 function d3combobox() {
60307 var event$$1 = dispatch('accept'),
60311 caseSensitive = false;
60313 var fetcher = function(val, cb) {
60314 cb(data.filter(function(d) {
60318 .indexOf(val.toLowerCase()) !== -1;
60322 var combobox = function(input, attachTo) {
60324 container = select(document.body)
60325 .selectAll('div.combobox')
60326 .filter(function(d) { return d === input.node(); }),
60327 shown = !container.empty();
60330 .classed('combobox-input', true)
60331 .on('focus.typeahead', focus)
60332 .on('blur.typeahead', blur)
60333 .on('keydown.typeahead', keydown)
60334 .on('keyup.typeahead', keyup)
60335 .on('input.typeahead', change)
60337 var parent = this.parentNode,
60338 sibling = this.nextSibling;
60340 var caret = select(parent).selectAll('.combobox-caret')
60341 .filter(function(d) { return d === input.node(); })
60342 .data([input.node()]);
60344 caret = caret.enter()
60345 .insert('div', function() { return sibling; })
60346 .attr('class', 'combobox-caret')
60350 .on('mousedown', function () {
60351 // prevent the form element from blurring. it blurs
60353 event.stopPropagation();
60354 event.preventDefault();
60356 input.node().focus();
60365 fetch(value(), render);
60369 window.setTimeout(hide, 150);
60374 container = select(document.body)
60375 .insert('div', ':first-child')
60376 .datum(input.node())
60377 .attr('class', 'combobox')
60378 .style('position', 'absolute')
60379 .style('display', 'block')
60380 .style('left', '0px')
60381 .on('mousedown', function () {
60382 // prevent moving focus out of the text field
60383 event.preventDefault();
60386 select(document.body)
60387 .on('scroll.combobox', render, true);
60396 container.remove();
60398 select(document.body)
60399 .on('scroll.combobox', null);
60405 function keydown() {
60406 switch (event.keyCode) {
60407 // backspace, delete
60410 input.on('input.typeahead', function() {
60413 var start = input.property('selectionStart');
60414 input.node().setSelectionRange(start, start);
60415 input.on('input.typeahead', change);
60420 container.selectAll('a.selected').each(function (d) {
60421 event$$1.call('accept', this, d);
60427 event.preventDefault();
60432 event.preventDefault();
60437 event.preventDefault();
60440 event.stopPropagation();
60444 switch (event.keyCode) {
60451 container.selectAll('a.selected').each(function (d) {
60452 event$$1.call('accept', this, d);
60459 function change() {
60460 fetch(value(), function() {
60461 if (input.property('selectionEnd') === input.property('value').length) {
60468 function nav(dir) {
60469 if (!suggestions.length) return;
60470 idx = Math.max(Math.min(idx + dir, suggestions.length - 1), 0);
60471 input.property('value', suggestions[idx].value);
60477 var value = input.property('value'),
60478 start = input.property('selectionStart'),
60479 end = input.property('selectionEnd');
60481 if (start && end) {
60482 value = value.substring(0, start);
60488 function fetch(v, cb) {
60489 fetcher.call(input, v, function(_) {
60495 function autocomplete() {
60496 var v = caseSensitive ? value() : value().toLowerCase();
60500 for (var i = 0; i < suggestions.length; i++) {
60501 var suggestion = suggestions[i].value,
60502 compare = caseSensitive ? suggestion : suggestion.toLowerCase();
60504 if (compare.indexOf(v) === 0) {
60506 input.property('value', suggestion);
60507 input.node().setSelectionRange(v.length, suggestion.length);
60513 function render() {
60514 if (suggestions.length >= minItems && document.activeElement === input.node()) {
60521 var options = container
60522 .selectAll('a.combobox-option')
60523 .data(suggestions, function(d) { return d.value; });
60530 .attr('class', 'combobox-option')
60531 .text(function(d) { return d.value; })
60533 .attr('title', function(d) { return d.title; })
60534 .classed('selected', function(d, i) { return i === idx; })
60535 .on('mouseover', select$$1)
60536 .on('click', accept)
60540 var node = attachTo ? attachTo.node() : input.node(),
60541 rect = node.getBoundingClientRect();
60544 .style('left', rect.left + 'px')
60545 .style('width', rect.width + 'px')
60546 .style('top', rect.height + rect.top + 'px');
60549 function select$$1(d, i) {
60554 function ensureVisible() {
60555 var node = container.selectAll('a.selected').node();
60556 if (node) node.scrollIntoView();
60559 function accept(d) {
60560 if (!shown) return;
60562 .property('value', d.value)
60563 .dispatch('change');
60564 event$$1.call('accept', this, d);
60569 combobox.fetcher = function(_) {
60570 if (!arguments.length) return fetcher;
60575 combobox.data = function(_) {
60576 if (!arguments.length) return data;
60581 combobox.minItems = function(_) {
60582 if (!arguments.length) return minItems;
60587 combobox.caseSensitive = function(_) {
60588 if (!arguments.length) return caseSensitive;
60593 return utilRebind(combobox, event$$1, 'on');
60597 d3combobox.off = function(input) {
60599 .on('focus.typeahead', null)
60600 .on('blur.typeahead', null)
60601 .on('keydown.typeahead', null)
60602 .on('keyup.typeahead', null)
60603 .on('input.typeahead', null)
60605 select(this.parentNode).selectAll('.combobox-caret')
60606 .filter(function(d) { return d === input.node(); })
60607 .on('mousedown', null);
60610 select(document.body)
60611 .on('scroll.combobox', null);
60614 function uiDisclosure() {
60615 var dispatch$$1 = dispatch('toggled'),
60618 content = function () {};
60621 var disclosure = function(selection$$1) {
60622 var hideToggle = selection$$1.selectAll('.hide-toggle')
60625 hideToggle = hideToggle.enter()
60628 .attr('class', 'hide-toggle')
60629 .merge(hideToggle);
60633 .on('click', toggle)
60634 .classed('expanded', expanded);
60637 var wrap = selection$$1.selectAll('div')
60640 wrap = wrap.enter()
60645 .classed('hide', !expanded)
60649 function toggle() {
60650 expanded = !expanded;
60651 hideToggle.classed('expanded', expanded);
60652 wrap.call(uiToggle(expanded));
60653 dispatch$$1.call('toggled', this, expanded);
60658 disclosure.title = function(_) {
60659 if (!arguments.length) return title;
60665 disclosure.expanded = function(_) {
60666 if (!arguments.length) return expanded;
60672 disclosure.content = function(_) {
60673 if (!arguments.length) return content;
60679 return utilRebind(disclosure, dispatch$$1, 'on');
60682 function uiRawMemberEditor(context) {
60684 taginfo = services.taginfo;
60687 function selectMember(d) {
60688 event.preventDefault();
60689 context.enter(modeSelect(context, [d.id]).suppressMenu(true));
60693 function changeRole(d) {
60694 var role = select(this).property('value');
60695 var member = { id: d.id, type: d.type, role: role };
60697 actionChangeMember(d.relation.id, member, d.index),
60698 t('operations.change_role.annotation')
60703 function deleteMember(d) {
60705 actionDeleteMember(d.relation.id, d.index),
60706 t('operations.delete_member.annotation')
60709 if (!context.hasEntity(d.relation.id)) {
60710 context.enter(modeBrowse(context));
60715 function rawMemberEditor(selection$$1) {
60716 var entity = context.entity(id),
60719 entity.members.forEach(function(member, index) {
60726 member: context.hasEntity(member.id)
60730 selection$$1.call(uiDisclosure()
60731 .title(t('inspector.all_members') + ' (' + memberships.length + ')')
60733 .on('toggled', toggled)
60738 function toggled(expanded) {
60740 selection$$1.node().parentNode.scrollTop += 200;
60745 function content(wrap) {
60746 var list = wrap.selectAll('.member-list')
60749 list = list.enter()
60751 .attr('class', 'member-list')
60755 var items = list.selectAll('li')
60756 .data(memberships, function(d) {
60757 return osmEntity$$1.key(d.relation) + ',' + d.index + ',' +
60758 (d.member ? osmEntity$$1.key(d.member) : 'incomplete');
60765 var enter = items.enter()
60767 .attr('class', 'member-row form-field')
60768 .classed('member-incomplete', function(d) { return !d.member; });
60771 .each(function(d) {
60773 var label = select(this).append('label')
60774 .attr('class', 'form-label')
60777 .on('click', selectMember);
60779 label.append('span')
60780 .attr('class', 'member-entity-type')
60781 .text(function(d) {
60782 var matched = context.presets().match(d.member, context.graph());
60783 return (matched && matched.name()) || utilDisplayType(d.member.id);
60786 label.append('span')
60787 .attr('class', 'member-entity-name')
60788 .text(function(d) { return utilDisplayName(d.member); });
60791 select(this).append('label')
60792 .attr('class', 'form-label')
60793 .text(t('inspector.incomplete', { id: d.id }));
60799 .attr('class', 'member-role')
60800 .property('type', 'text')
60801 .attr('maxlength', 255)
60802 .attr('placeholder', t('inspector.role'))
60804 .property('value', function(d) { return d.role; })
60805 .on('change', changeRole);
60809 .attr('tabindex', -1)
60810 .attr('class', 'remove button-input-action member-delete minor')
60811 .on('click', deleteMember)
60812 .call(svgIcon('#operation-delete'));
60815 enter.each(bindTypeahead);
60819 function bindTypeahead(d) {
60820 var row = select(this),
60821 role = row.selectAll('input.member-role');
60823 function sort(value, data) {
60824 var sameletter = [],
60826 for (var i = 0; i < data.length; i++) {
60827 if (data[i].value.substring(0, value.length) === value) {
60828 sameletter.push(data[i]);
60830 other.push(data[i]);
60833 return sameletter.concat(other);
60836 role.call(d3combobox()
60837 .fetcher(function(role, callback) {
60838 var rtype = entity.tags.type;
60841 rtype: rtype || '',
60842 geometry: context.geometry(d.member.id),
60844 }, function(err, data) {
60845 if (!err) callback(sort(role, data));
60851 function unbind() {
60852 var row = select(this);
60854 row.selectAll('input.member-role')
60855 .call(d3combobox.off);
60861 rawMemberEditor.entityID = function(_) {
60862 if (!arguments.length) return id;
60864 return rawMemberEditor;
60868 return rawMemberEditor;
60871 function uiRawMembershipEditor(context) {
60872 var taginfo = services.taginfo,
60876 function selectRelation(d) {
60877 event.preventDefault();
60878 context.enter(modeSelect(context, [d.relation.id]).suppressMenu(true));
60882 function changeRole(d) {
60883 var role = select(this).property('value');
60885 actionChangeMember(d.relation.id, lodash.extend({}, d.member, { role: role }), d.index),
60886 t('operations.change_role.annotation')
60891 function addMembership(d, role) {
60896 actionAddMember(d.relation.id, { id: id, type: context.entity(id).type, role: role }),
60897 t('operations.add_member.annotation')
60901 var relation = osmRelation();
60903 actionAddEntity(relation),
60904 actionAddMember(relation.id, { id: id, type: context.entity(id).type, role: role }),
60905 t('operations.add.annotation.relation')
60908 context.enter(modeSelect(context, [relation.id]).suppressMenu(true));
60913 function deleteMembership(d) {
60915 actionDeleteMember(d.relation.id, d.index),
60916 t('operations.delete_member.annotation')
60921 function relations(q) {
60922 var newRelation = {
60924 value: t('inspector.new_relation')
60927 graph = context.graph();
60929 context.intersects(context.extent()).forEach(function(entity) {
60930 if (entity.type !== 'relation' || entity.id === id)
60933 var matched = context.presets().match(entity, graph),
60934 presetName = (matched && matched.name()) || t('inspector.relation'),
60935 entityName = utilDisplayName(entity) || '';
60937 var value = presetName + ' ' + entityName;
60938 if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
60947 result.sort(function(a, b) {
60948 return osmRelation.creationOrder(a.relation, b.relation);
60951 // Dedupe identical names by appending relation id - see #2891
60952 var dupeGroups = lodash(result)
60954 .filter(function(v) { return v.length > 1; })
60957 dupeGroups.forEach(function(group) {
60958 group.forEach(function(obj) {
60959 obj.value += ' ' + obj.relation.id;
60963 result.unshift(newRelation);
60968 function rawMembershipEditor(selection$$1) {
60969 var entity = context.entity(id),
60972 context.graph().parentRelations(entity).forEach(function(relation) {
60973 relation.members.forEach(function(member, index) {
60974 if (member.id === entity.id) {
60975 memberships.push({ relation: relation, member: member, index: index });
60980 selection$$1.call(uiDisclosure()
60981 .title(t('inspector.all_relations') + ' (' + memberships.length + ')')
60983 .on('toggled', toggled)
60988 function toggled(expanded) {
60990 selection$$1.node().parentNode.scrollTop += 200;
60995 function content(wrap) {
60996 var list = wrap.selectAll('.member-list')
60999 list = list.enter()
61001 .attr('class', 'member-list')
61005 var items = list.selectAll('li.member-row-normal')
61006 .data(memberships, function(d) {
61007 return osmEntity$$1.key(d.relation) + ',' + d.index;
61014 var enter = items.enter()
61016 .attr('class', 'member-row member-row-normal form-field');
61020 .attr('class', 'form-label')
61023 .on('click', selectRelation);
61027 .attr('class', 'member-entity-type')
61028 .text(function(d) {
61029 var matched = context.presets().match(d.relation, context.graph());
61030 return (matched && matched.name()) || t('inspector.relation');
61035 .attr('class', 'member-entity-name')
61036 .text(function(d) { return utilDisplayName(d.relation); });
61040 .attr('class', 'member-role')
61041 .property('type', 'text')
61042 .attr('maxlength', 255)
61043 .attr('placeholder', t('inspector.role'))
61045 .property('value', function(d) { return d.member.role; })
61046 .on('change', changeRole);
61050 .attr('tabindex', -1)
61051 .attr('class', 'remove button-input-action member-delete minor')
61052 .on('click', deleteMembership)
61053 .call(svgIcon('#operation-delete'));
61056 enter.each(bindTypeahead);
61060 var newrow = list.selectAll('.member-row-new')
61061 .data(showBlank ? [0] : []);
61066 enter = newrow.enter()
61068 .attr('class', 'member-row member-row-new form-field');
61072 .attr('type', 'text')
61073 .attr('class', 'member-entity-input')
61078 .attr('class', 'member-role')
61079 .property('type', 'text')
61080 .attr('maxlength', 255)
61081 .attr('placeholder', t('inspector.role'))
61083 .on('change', changeRole);
61087 .attr('tabindex', -1)
61088 .attr('class', 'remove button-input-action member-delete minor')
61089 .on('click', deleteMembership)
61090 .call(svgIcon('#operation-delete'));
61095 newrow.selectAll('.member-entity-input')
61098 .fetcher(function(value, callback) { callback(relations(value)); })
61099 .on('accept', onAccept)
61103 var addrel = wrap.selectAll('.add-relation')
61106 addrel = addrel.enter()
61108 .attr('class', 'add-relation')
61112 .call(svgIcon('#icon-plus', 'light'))
61113 .on('click', function() {
61116 list.selectAll('.member-entity-input').node().focus();
61120 function onAccept(d) {
61121 var role = list.selectAll('.member-row-new .member-role').property('value');
61122 addMembership(d, role);
61126 function bindTypeahead(d) {
61127 var row = select(this),
61128 role = row.selectAll('input.member-role');
61130 function sort(value, data) {
61131 var sameletter = [],
61133 for (var i = 0; i < data.length; i++) {
61134 if (data[i].value.substring(0, value.length) === value) {
61135 sameletter.push(data[i]);
61137 other.push(data[i]);
61140 return sameletter.concat(other);
61143 role.call(d3combobox()
61144 .fetcher(function(role, callback) {
61145 var rtype = d.relation.tags.type;
61148 rtype: rtype || '',
61149 geometry: context.geometry(id),
61151 }, function(err, data) {
61152 if (!err) callback(sort(role, data));
61158 function unbind() {
61159 var row = select(this);
61161 row.selectAll('input.member-role')
61162 .call(d3combobox.off);
61168 rawMembershipEditor.entityID = function(_) {
61169 if (!arguments.length) return id;
61171 return rawMembershipEditor;
61175 return rawMembershipEditor;
61178 function uiTagReference(tag) {
61179 var taginfo = services.taginfo,
61187 function findLocal(data) {
61188 var locale = utilDetect().locale.toLowerCase(),
61191 if (locale !== 'pt-br') { // see #3776, prefer 'pt' over 'pt-br'
61192 localized = lodash.find(data, function(d) {
61193 return d.lang.toLowerCase() === locale;
61195 if (localized) return localized;
61198 // try the non-regional version of a language, like
61199 // 'en' if the language is 'en-US'
61200 if (locale.indexOf('-') !== -1) {
61201 var first = locale.split('-')[0];
61202 localized = lodash.find(data, function(d) {
61203 return d.lang.toLowerCase() === first;
61205 if (localized) return localized;
61208 // finally fall back to english
61209 return lodash.find(data, function(d) {
61210 return d.lang.toLowerCase() === 'en';
61215 function load(param) {
61216 if (!taginfo) return;
61218 button.classed('tag-reference-loading', true);
61220 taginfo.docs(param, function show(err, data) {
61222 if (!err && data) {
61223 docs = findLocal(data);
61229 if (!docs || !docs.title) {
61230 if (param.hasOwnProperty('value')) {
61231 load(lodash.omit(param, 'value')); // retry with key only
61233 body.append('p').text(t('inspector.no_documentation_key'));
61240 if (docs.image && docs.image.thumb_url_prefix) {
61243 .attr('class', 'wiki-image')
61244 .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
61245 .on('load', function() { done(); })
61246 .on('error', function() { select(this).remove(); done(); });
61253 .text(docs.description || t('inspector.documentation_redirect'));
61257 .attr('target', '_blank')
61258 .attr('tabindex', -1)
61259 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
61260 .call(svgIcon('#icon-out-link', 'inline'))
61262 .text(t('inspector.reference'));
61270 button.classed('tag-reference-loading', false);
61274 .style('max-height', '200px')
61275 .style('opacity', '1');
61281 function hide(selection$$1) {
61282 selection$$1 = selection$$1 || body.transition().duration(200);
61285 .style('max-height', '0px')
61286 .style('opacity', '0');
61292 tagReference.button = function(selection$$1) {
61293 button = selection$$1.selectAll('.tag-reference-button')
61296 button = button.enter()
61298 .attr('class', 'tag-reference-button')
61299 .attr('tabindex', -1)
61300 .call(svgIcon('#icon-inspect'))
61304 .on('click', function () {
61305 event.stopPropagation();
61306 event.preventDefault();
61309 } else if (loaded) {
61318 tagReference.body = function(selection$$1) {
61319 body = selection$$1.selectAll('.tag-reference-body')
61322 body = body.enter()
61324 .attr('class', 'tag-reference-body cf')
61325 .style('max-height', '0')
61326 .style('opacity', '0')
61329 if (showing === false) {
61335 tagReference.showing = function(_) {
61336 if (!arguments.length) return showing;
61338 return tagReference;
61342 return tagReference;
61345 function uiRawTagEditor(context) {
61346 var taginfo = services.taginfo,
61347 dispatch$$1 = dispatch('change'),
61355 function rawTagEditor(selection$$1) {
61356 var count = Object.keys(tags).filter(function(d) { return d; }).length;
61358 selection$$1.call(uiDisclosure()
61359 .title(t('inspector.all_tags') + ' (' + count + ')')
61360 .expanded(context.storage('raw_tag_editor.expanded') === 'true' || preset.isFallback())
61361 .on('toggled', toggled)
61362 .content(content));
61364 function toggled(expanded) {
61365 context.storage('raw_tag_editor.expanded', expanded);
61367 selection$$1.node().parentNode.scrollTop += 200;
61373 function content(wrap) {
61374 var entries$$1 = entries(tags);
61376 if (!entries$$1.length || showBlank) {
61378 entries$$1.push({key: '', value: ''});
61381 var list = wrap.selectAll('.tag-list')
61384 list = list.enter()
61386 .attr('class', 'tag-list')
61389 var newTag = wrap.selectAll('.add-tag')
61394 .attr('class', 'add-tag')
61395 .on('click', addTag)
61396 .call(svgIcon('#icon-plus', 'light'));
61399 var items = list.selectAll('.tag-row')
61400 .data(entries$$1, function(d) { return d.key; });
61408 var enter = items.enter()
61410 .attr('class', 'tag-row cf');
61414 .attr('class', 'key-wrap')
61416 .property('type', 'text')
61417 .attr('class', 'key')
61418 .attr('maxlength', 255)
61420 .on('blur', keyChange)
61421 .on('change', keyChange);
61425 .attr('class', 'input-wrap-position')
61427 .property('type', 'text')
61428 .attr('class', 'value')
61429 .attr('maxlength', 255)
61431 .on('blur', valueChange)
61432 .on('change', valueChange)
61433 .on('keydown.push-more', pushMore);
61437 .attr('tabindex', -1)
61438 .attr('class', 'remove minor')
61439 .call(svgIcon('#operation-delete'));
61446 .sort(function(a, b) {
61447 return (a.key === '') ? 1
61448 : (b.key === '') ? -1
61449 : ascending(a.key, b.key);
61453 .each(function(tag) {
61454 var row = select(this),
61455 key = row.select('input.key'), // propagate bound data to child
61456 value = row.select('input.value'); // propagate bound data to child
61459 bindTypeahead(key, value);
61462 var isRelation = (context.entity(id).type === 'relation'),
61465 if (isRelation && tag.key === 'type') {
61466 reference = uiTagReference({ rtype: tag.value }, context);
61468 reference = uiTagReference({ key: tag.key, value: tag.value }, context);
61471 if (state === 'hover') {
61472 reference.showing(false);
61476 .call(reference.button)
61477 .call(reference.body);
61480 items.selectAll('input.key')
61481 .attr('title', function(d) { return d.key; })
61482 .call(utilGetSetValue, function(d) { return d.key; });
61484 items.selectAll('input.value')
61485 .attr('title', function(d) { return d.value; })
61486 .call(utilGetSetValue, function(d) { return d.value; });
61488 items.selectAll('button.remove')
61489 .on('click', removeTag);
61492 function pushMore() {
61493 if (event.keyCode === 9 && !event.shiftKey &&
61494 list.selectAll('li:last-child input.value').node() === this) {
61500 function bindTypeahead(key, value) {
61502 function sort(value, data) {
61503 var sameletter = [],
61505 for (var i = 0; i < data.length; i++) {
61506 if (data[i].value.substring(0, value.length) === value) {
61507 sameletter.push(data[i]);
61509 other.push(data[i]);
61512 return sameletter.concat(other);
61515 key.call(d3combobox()
61516 .fetcher(function(value, callback) {
61519 geometry: context.geometry(id),
61521 }, function(err, data) {
61522 if (!err) callback(sort(value, data));
61526 value.call(d3combobox()
61527 .fetcher(function(value, callback) {
61530 key: utilGetSetValue(key),
61531 geometry: context.geometry(id),
61533 }, function(err, data) {
61534 if (!err) callback(sort(value, data));
61540 function unbind() {
61541 var row = select(this);
61543 row.selectAll('input.key')
61544 .call(d3combobox.off);
61546 row.selectAll('input.value')
61547 .call(d3combobox.off);
61551 function keyChange(d) {
61553 kNew = this.value.trim(),
61556 if (kNew && kNew !== kOld) {
61557 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
61559 suffix = +(match[2] || 1);
61560 while (tags[kNew]) { // rename key if already in use
61561 kNew = base + '_' + suffix++;
61564 tag[kOld] = undefined;
61565 tag[kNew] = d.value;
61566 d.key = kNew; // Maintain DOM identity through the subsequent update.
61568 dispatch$$1.call('change', this, tag);
61572 function valueChange(d) {
61574 tag[d.key] = this.value;
61575 dispatch$$1.call('change', this, tag);
61579 function removeTag(d) {
61581 tag[d.key] = undefined;
61582 dispatch$$1.call('change', this, tag);
61583 select(this.parentNode).remove();
61587 function addTag() {
61588 // Wrapped in a setTimeout in case it's being called from a blur
61589 // handler. Without the setTimeout, the call to `content` would
61590 // wipe out the pending value change.
61591 setTimeout(function() {
61594 list.selectAll('li:last-child input.key').node().focus();
61600 rawTagEditor.state = function(_) {
61601 if (!arguments.length) return state;
61603 return rawTagEditor;
61607 rawTagEditor.preset = function(_) {
61608 if (!arguments.length) return preset;
61610 return rawTagEditor;
61614 rawTagEditor.tags = function(_) {
61615 if (!arguments.length) return tags;
61617 return rawTagEditor;
61621 rawTagEditor.entityID = function(_) {
61622 if (!arguments.length) return id;
61624 return rawTagEditor;
61628 return utilRebind(rawTagEditor, dispatch$$1, 'on');
61631 function uiFieldCheck(field) {
61632 var dispatch$$1 = dispatch('change'),
61633 options = field.strings && field.strings.options,
61636 input = select(null),
61637 text$$1 = select(null),
61638 label = select(null),
61642 for (var k in options) {
61643 values$$1.push(k === 'undefined' ? undefined : k);
61644 texts.push(field.t('options.' + k, { 'default': options[k] }));
61647 values$$1 = [undefined, 'yes'];
61648 texts = [t('inspector.unknown'), t('inspector.check.yes')];
61649 if (field.type === 'check') {
61650 values$$1.push('no');
61651 texts.push(t('inspector.check.no'));
61656 var check = function(selection$$1) {
61657 // hack: pretend oneway field is a oneway_yes field
61658 // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
61659 if (field.id === 'oneway') {
61660 for (var key in entity.tags) {
61661 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
61662 texts[0] = t('presets.fields.oneway_yes.options.undefined');
61668 selection$$1.classed('checkselect', 'true');
61670 label = selection$$1.selectAll('.preset-input-wrap')
61673 var enter = label.enter()
61675 .attr('class', 'preset-input-wrap');
61679 .property('indeterminate', field.type === 'check')
61680 .attr('type', 'checkbox')
61681 .attr('id', 'preset-input-' + field.id);
61686 .attr('class', 'value');
61688 label = label.merge(enter);
61689 input = label.selectAll('input');
61690 text$$1 = label.selectAll('span.value');
61693 .on('click', function() {
61695 t$$1[field.key] = values$$1[(values$$1.indexOf(value) + 1) % values$$1.length];
61696 dispatch$$1.call('change', this, t$$1);
61697 event.stopPropagation();
61702 check.entity = function(_) {
61703 if (!arguments.length) return entity;
61709 check.tags = function(tags) {
61710 value = tags[field.key];
61711 input.property('indeterminate', field.type === 'check' && !value);
61712 input.property('checked', value === 'yes');
61713 text$$1.text(texts[values$$1.indexOf(value)]);
61714 label.classed('set', !!value);
61718 check.focus = function() {
61719 input.node().focus();
61722 return utilRebind(check, dispatch$$1, 'on');
61725 function uiFieldCombo(field, context) {
61726 var dispatch$$1 = dispatch('change'),
61727 nominatim = services.geocoder,
61728 taginfo = services.taginfo,
61729 isMulti = (field.type === 'multiCombo'),
61730 isNetwork = (field.type === 'networkCombo'),
61731 optstrings = field.strings && field.strings.options,
61732 optarray = field.options,
61733 snake_case = (field.snake_case || (field.snake_case === undefined)),
61734 combobox = d3combobox().minItems(isMulti ? 1 : 2),
61742 // ensure multiCombo field.key ends with a ':'
61743 if (isMulti && field.key.match(/:$/) === null) {
61748 function snake(s) {
61749 return s.replace(/\s+/g, '_');
61752 function unsnake(s) {
61753 return s.replace(/_+/g, ' ');
61756 function clean(s) {
61757 return s.split(';')
61758 .map(function(s) { return s.trim(); })
61763 // returns the tag value for a display value
61764 // (for multiCombo, dval should be the key suffix, not the entire key)
61765 function tagValue(dval) {
61766 dval = clean(dval || '');
61769 var match = lodash.find(comboData, function(o) {
61770 return o.key && clean(o.value) === dval;
61777 if (field.type === 'typeCombo' && !dval) {
61781 return (snake_case ? snake(dval) : dval) || undefined;
61785 // returns the display value for a tag value
61786 // (for multiCombo, tval should be the key suffix, not the entire key)
61787 function displayValue(tval) {
61791 var match = lodash.find(comboData, function(o) { return o.key === tval && o.value; });
61793 return match.value;
61797 if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
61801 return snake_case ? unsnake(tval) : tval;
61805 function objectDifference(a, b) {
61806 return lodash.reject(a, function(d1) {
61807 return lodash.some(b, function(d2) { return d1.value === d2.value; });
61812 function initCombo(selection$$1, attachTo) {
61814 selection$$1.attr('readonly', 'readonly');
61815 selection$$1.call(combobox, attachTo);
61816 setStaticValues(setPlaceholder);
61818 } else if (optarray) {
61819 selection$$1.call(combobox, attachTo);
61820 setStaticValues(setPlaceholder);
61822 } else if (taginfo) {
61823 selection$$1.call(combobox.fetcher(setTaginfoValues), attachTo);
61824 setTaginfoValues('', setPlaceholder);
61829 function setStaticValues(callback) {
61830 if (!(optstrings || optarray)) return;
61833 comboData = Object.keys(optstrings).map(function(k) {
61834 var v = field.t('options.' + k, { 'default': optstrings[k] });
61842 } else if (optarray) {
61843 comboData = optarray.map(function(k) {
61844 var v = snake_case ? unsnake(k) : k;
61853 combobox.data(objectDifference(comboData, multiData));
61854 if (callback) callback(comboData);
61858 function setTaginfoValues(q, callback) {
61859 var fn = isMulti ? 'multikeys' : 'values';
61860 var query = (isMulti ? field.key : '') + q;
61861 var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
61862 if (hasCountryPrefix) {
61863 query = country + ':';
61868 geometry: context.geometry(entity.id),
61870 }, function(err, data) {
61872 if (hasCountryPrefix) {
61873 data = lodash.filter(data, function(d) {
61874 return d.value.toLowerCase().indexOf(country + ':') === 0;
61877 comboData = lodash.map(data, function(d) {
61879 if (isMulti) k = k.replace(field.key, '');
61880 var v = snake_case ? unsnake(k) : k;
61884 title: isMulti ? v : d.title
61887 comboData = objectDifference(comboData, multiData);
61888 if (callback) callback(comboData);
61893 function setPlaceholder(d) {
61896 ph = field.placeholder() || t('inspector.add');
61898 var vals = lodash.map(d, 'value').filter(function(s) { return s.length < 20; }),
61899 placeholders = vals.length > 1 ? vals : lodash.map(d, 'key');
61900 ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
61903 container.selectAll('input')
61904 .attr('placeholder', ph + '…');
61908 function change() {
61909 var val = tagValue(utilGetSetValue(input)),
61914 container.classed('active', false);
61915 utilGetSetValue(input, '');
61916 field.keys.push(field.key + val);
61917 t$$1[field.key + val] = 'yes';
61918 window.setTimeout(function() { input.node().focus(); }, 10);
61921 t$$1[field.key] = val;
61924 dispatch$$1.call('change', this, t$$1);
61928 function removeMultikey(d) {
61929 event.stopPropagation();
61931 t$$1[d.key] = undefined;
61932 dispatch$$1.call('change', this, t$$1);
61936 function combo(selection$$1) {
61938 container = selection$$1.selectAll('ul').data([0]);
61940 container = container.enter()
61942 .attr('class', 'form-field-multicombo')
61943 .on('click', function() {
61944 window.setTimeout(function() { input.node().focus(); }, 10);
61949 container = selection$$1;
61952 input = container.selectAll('input')
61955 input = input.enter()
61957 .attr('type', 'text')
61958 .attr('id', 'preset-input-' + field.id)
61960 .call(initCombo, selection$$1)
61963 if (isNetwork && nominatim && entity) {
61964 var center = entity.extent(context.graph()).center();
61965 nominatim.countryCode(center, function (err, code) {
61971 .on('change', change)
61972 .on('blur', change);
61976 .on('accept', function() {
61977 input.node().blur();
61978 input.node().focus();
61982 .on('focus', function() { container.classed('active', true); });
61987 combo.tags = function(tags) {
61991 // Build multiData array containing keys already set..
61992 Object.keys(tags).forEach(function(key) {
61993 if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
61995 var suffix = key.substring(field.key.length);
61998 value: displayValue(suffix)
62002 // Set keys for form-field modified (needed for undo and reset buttons)..
62003 field.keys = lodash.map(multiData, 'key');
62005 // Exclude existing multikeys from combo options..
62006 var available = objectDifference(comboData, multiData);
62007 combobox.data(available);
62009 // Hide 'Add' button if this field uses fixed set of
62010 // translateable optstrings and they're all currently used..
62011 container.selectAll('.combobox-input, .combobox-caret')
62012 .classed('hide', optstrings && !available.length);
62016 var chips = container.selectAll('.chips')
62022 var enter = chips.enter()
62023 .insert('li', 'input')
62024 .attr('class', 'chips');
62026 enter.append('span');
62029 chips = chips.merge(enter);
62031 chips.select('span')
62032 .text(function(d) { return d.value; });
62035 .on('click', removeMultikey)
62036 .attr('class', 'remove')
62040 utilGetSetValue(input, displayValue(tags[field.key]));
62045 combo.focus = function() {
62046 input.node().focus();
62050 combo.entity = function(_) {
62051 if (!arguments.length) return entity;
62057 return utilRebind(combo, dispatch$$1, 'on');
62060 function uiFieldText(field, context) {
62061 var dispatch$$1 = dispatch('change'),
62062 nominatim = services.geocoder,
62067 function i(selection$$1) {
62068 var fieldId = 'preset-input-' + field.id;
62070 input = selection$$1.selectAll('input')
62073 input = input.enter()
62075 .attr('type', field.type)
62076 .attr('id', fieldId)
62077 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
62082 .on('input', change(true))
62083 .on('blur', change())
62084 .on('change', change());
62086 if (field.type === 'tel' && nominatim && entity) {
62087 var center = entity.extent(context.graph()).center();
62088 nominatim.countryCode(center, function (err, countryCode) {
62089 if (err || !dataPhoneFormats[countryCode]) return;
62090 selection$$1.selectAll('#' + fieldId)
62091 .attr('placeholder', dataPhoneFormats[countryCode]);
62094 } else if (field.type === 'number') {
62095 input.attr('type', 'text');
62097 var spinControl = selection$$1.selectAll('.spin-control')
62100 var enter = spinControl.enter()
62102 .attr('class', 'spin-control');
62107 .attr('class', 'increment')
62108 .attr('tabindex', -1);
62113 .attr('class', 'decrement')
62114 .attr('tabindex', -1);
62116 spinControl = spinControl
62119 spinControl.selectAll('button')
62120 .on('click', function(d) {
62121 event.preventDefault();
62122 var num = parseInt(input.node().value || 0, 10);
62123 if (!isNaN(num)) input.node().value = num + d;
62130 function change(onInput) {
62131 return function() {
62133 t$$1[field.key] = utilGetSetValue(input) || undefined;
62134 dispatch$$1.call('change', this, t$$1, onInput);
62139 i.entity = function(_) {
62140 if (!arguments.length) return entity;
62146 i.tags = function(tags) {
62147 utilGetSetValue(input, tags[field.key] || '');
62151 i.focus = function() {
62152 var node = input.node();
62153 if (node) node.focus();
62156 return utilRebind(i, dispatch$$1, 'on');
62159 function uiFieldAccess(field) {
62160 var dispatch$$1 = dispatch('change'),
62163 function access(selection$$1) {
62164 var wrap = selection$$1.selectAll('.preset-input-wrap')
62167 wrap = wrap.enter()
62169 .attr('class', 'cf preset-input-wrap')
62173 var list = wrap.selectAll('ul')
62176 list = list.enter()
62181 items = list.selectAll('li')
62185 var enter = items.enter()
62187 .attr('class', function(d) { return 'cf preset-access-' + d; });
62191 .attr('class', 'col6 label preset-label-access')
62192 .attr('for', function(d) { return 'preset-input-access-' + d; })
62193 .text(function(d) { return field.t('types.' + d); });
62197 .attr('class', 'col6 preset-input-access-wrap')
62199 .attr('type', 'text')
62200 .attr('class', 'preset-input-access')
62201 .attr('id', function(d) { return 'preset-input-access-' + d; })
62203 .each(function(d) {
62206 .data(access.options(d)));
62211 items = items.merge(enter);
62213 wrap.selectAll('.preset-input-access')
62214 .on('change', change)
62215 .on('blur', change);
62219 function change(d) {
62221 tag[d] = utilGetSetValue(select(this)) || undefined;
62222 dispatch$$1.call('change', this, tag);
62226 access.options = function(type) {
62227 var options = ['no', 'permissive', 'private', 'destination'];
62229 if (type !== 'access') {
62230 options.unshift('yes');
62231 options.push('designated');
62233 if (type === 'bicycle') {
62234 options.push('dismount');
62238 return options.map(function(option) {
62240 title: field.t('options.' + option + '.description'),
62247 var placeholders = {
62249 foot: 'designated',
62250 motor_vehicle: 'no'
62254 motor_vehicle: 'no',
62260 motor_vehicle: 'no'
62263 motor_vehicle: 'no',
62264 bicycle: 'designated'
62267 motor_vehicle: 'no',
62268 horse: 'designated'
62272 motor_vehicle: 'no',
62278 motor_vehicle: 'yes',
62283 motor_vehicle: 'yes'
62287 motor_vehicle: 'yes',
62293 motor_vehicle: 'yes',
62299 motor_vehicle: 'yes',
62305 motor_vehicle: 'yes',
62311 motor_vehicle: 'yes',
62317 motor_vehicle: 'yes',
62323 motor_vehicle: 'yes',
62328 motor_vehicle: 'yes'
62332 motor_vehicle: 'yes',
62338 motor_vehicle: 'yes',
62344 motor_vehicle: 'yes',
62351 access.tags = function(tags) {
62352 utilGetSetValue(items.selectAll('.preset-input-access'),
62353 function(d) { return tags[d] || ''; })
62354 .attr('placeholder', function() {
62355 return tags.access ? tags.access : field.placeholder();
62358 items.selectAll('#preset-input-access-access')
62359 .attr('placeholder', 'yes');
62361 lodash.forEach(placeholders[tags.highway], function(v, k) {
62362 items.selectAll('#preset-input-access-' + k)
62363 .attr('placeholder', function() { return (tags.access || v); });
62368 access.focus = function() {
62369 items.selectAll('.preset-input-access')
62374 return utilRebind(access, dispatch$$1, 'on');
62377 function uiFieldAddress(field, context) {
62378 var dispatch$$1 = dispatch('init', 'change'),
62379 nominatim = services.geocoder,
62380 wrap = select(null),
62381 isInitialized = false,
62384 function getNearStreets() {
62385 var extent$$1 = entity.extent(context.graph()),
62386 l = extent$$1.center(),
62387 box = geoExtent$$1(l).padByMeters(200);
62389 var streets = context.intersects(box)
62390 .filter(isAddressable)
62392 var loc = context.projection([
62393 (extent$$1[0][0] + extent$$1[1][0]) / 2,
62394 (extent$$1[0][1] + extent$$1[1][1]) / 2]),
62395 choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
62397 title: d.tags.name,
62398 value: d.tags.name,
62399 dist: choice.distance
62402 .sort(function(a, b) {
62403 return a.dist - b.dist;
62406 return lodash.uniqBy(streets, 'value');
62408 function isAddressable(d) {
62409 return d.tags.highway && d.tags.name && d.type === 'way';
62414 function getNearCities() {
62415 var extent$$1 = entity.extent(context.graph()),
62416 l = extent$$1.center(),
62417 box = geoExtent$$1(l).padByMeters(200);
62419 var cities = context.intersects(box)
62420 .filter(isAddressable)
62423 title: d.tags['addr:city'] || d.tags.name,
62424 value: d.tags['addr:city'] || d.tags.name,
62425 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62428 .sort(function(a, b) {
62429 return a.dist - b.dist;
62432 return lodash.uniqBy(cities, 'value');
62435 function isAddressable(d) {
62437 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
62440 if (d.tags.place && d.tags.name && (
62441 d.tags.place === 'city' ||
62442 d.tags.place === 'town' ||
62443 d.tags.place === 'village'))
62446 if (d.tags['addr:city']) return true;
62452 function getNearValues(key) {
62453 var extent$$1 = entity.extent(context.graph()),
62454 l = extent$$1.center(),
62455 box = geoExtent$$1(l).padByMeters(200);
62457 var results = context.intersects(box)
62458 .filter(function hasTag(d) {
62459 return d.tags[key];
62463 title: d.tags[key],
62464 value: d.tags[key],
62465 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
62468 .sort(function(a, b) {
62469 return a.dist - b.dist;
62472 return lodash.uniqBy(results, 'value');
62476 function initCallback(err, countryCode) {
62479 var addressFormat = lodash.find(dataAddressFormats, function (a) {
62480 return a && a.countryCodes && lodash.includes(a.countryCodes, countryCode);
62481 }) || lodash.first(dataAddressFormats);
62483 var widths = addressFormat.widths || {
62484 housenumber: 1/3, street: 2/3,
62485 city: 2/3, state: 1/4, postcode: 1/3
62489 // Normalize widths.
62490 var total = lodash.reduce(r, function(sum$$1, field) {
62491 return sum$$1 + (widths[field] || 0.5);
62494 return r.map(function (field) {
62497 width: (widths[field] || 0.5) / total
62502 wrap.selectAll('div.addr-row')
62503 .data(addressFormat.format)
62506 .attr('class', 'addr-row')
62507 .selectAll('input')
62511 .property('type', 'text')
62512 .attr('placeholder', function (d) {
62513 var localkey = d.id + '!' + countryCode,
62514 tkey = field.strings.placeholders[localkey] ? localkey : d.id;
62515 return field.t('placeholders.' + tkey);
62517 .attr('class', function (d) { return 'addr-' + d.id; })
62519 .style('width', function (d) { return d.width * 100 + '%'; });
62523 // setup dropdowns for common address tags
62524 var dropdowns = addressFormat.dropdowns || [
62525 'city', 'county', 'country', 'district', 'hamlet',
62526 'neighbourhood', 'place', 'postcode', 'province',
62527 'quarter', 'state', 'street', 'subdistrict', 'suburb'
62530 // If fields exist for any of these tags, create dropdowns to pick nearby values..
62531 dropdowns.forEach(function(tag) {
62532 var nearValues = (tag === 'street') ? getNearStreets
62533 : (tag === 'city') ? getNearCities
62536 wrap.selectAll('input.addr-' + tag)
62539 .fetcher(function(value, callback) {
62540 callback(nearValues('addr:' + tag));
62544 wrap.selectAll('input')
62545 .on('blur', change())
62546 .on('change', change());
62548 wrap.selectAll('input:not(.combobox-input)')
62549 .on('input', change(true));
62551 dispatch$$1.call('init');
62552 isInitialized = true;
62556 function address(selection$$1) {
62557 isInitialized = false;
62559 wrap = selection$$1.selectAll('.preset-input-wrap')
62562 wrap = wrap.enter()
62564 .attr('class', 'preset-input-wrap')
62567 if (nominatim && entity) {
62568 var center = entity.extent(context.graph()).center();
62569 nominatim.countryCode(center, initCallback);
62574 function change(onInput) {
62575 return function() {
62578 wrap.selectAll('input')
62579 .each(function (field) {
62580 tags['addr:' + field.id] = this.value || undefined;
62583 dispatch$$1.call('change', this, tags, onInput);
62588 function updateTags(tags) {
62589 utilGetSetValue(wrap.selectAll('input'), function (field) {
62590 return tags['addr:' + field.id] || '';
62595 address.entity = function(_) {
62596 if (!arguments.length) return entity;
62602 address.tags = function(tags) {
62603 if (isInitialized) {
62606 dispatch$$1.on('init', function () {
62607 dispatch$$1.on('init', null);
62614 address.focus = function() {
62615 var node = wrap.selectAll('input').node();
62616 if (node) node.focus();
62620 return utilRebind(address, dispatch$$1, 'on');
62623 function uiFieldCycleway(field) {
62624 var dispatch$$1 = dispatch('change'),
62625 items = select(null);
62628 function cycleway(selection$$1) {
62630 function stripcolon(s) {
62631 return s.replace(':', '');
62635 var wrap = selection$$1.selectAll('.preset-input-wrap')
62638 wrap = wrap.enter()
62640 .attr('class', 'cf preset-input-wrap')
62644 var div = wrap.selectAll('ul')
62652 items = div.selectAll('li')
62655 var enter = items.enter()
62657 .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
62661 .attr('class', 'col6 label preset-label-cycleway')
62662 .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
62663 .text(function(d) { return field.t('types.' + d); });
62667 .attr('class', 'col6 preset-input-cycleway-wrap')
62669 .attr('type', 'text')
62670 .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
62672 .each(function(d) {
62673 select(this).call(d3combobox().data(cycleway.options(d)));
62678 wrap.selectAll('.preset-input-cycleway')
62679 .on('change', change)
62680 .on('blur', change);
62684 function change() {
62685 var left = utilGetSetValue(select('.preset-input-cyclewayleft')),
62686 right = utilGetSetValue(select('.preset-input-cyclewayright')),
62689 if (left === 'none' || left === '') { left = undefined; }
62690 if (right === 'none' || right === '') { right = undefined; }
62692 // Always set both left and right as changing one can affect the other
62694 cycleway: undefined,
62695 'cycleway:left': left,
62696 'cycleway:right': right
62699 // If the left and right tags match, use the cycleway tag to tag both
62700 // sides the same way
62701 if (left === right) {
62704 'cycleway:left': undefined,
62705 'cycleway:right': undefined
62709 dispatch$$1.call('change', this, tag);
62713 cycleway.options = function() {
62714 return keys(field.strings.options).map(function(option) {
62716 title: field.t('options.' + option + '.description'),
62723 cycleway.tags = function(tags) {
62724 utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
62725 // If cycleway is set, always return that
62726 if (tags.cycleway) {
62727 return tags.cycleway;
62729 return tags[d] || '';
62731 .attr('placeholder', field.placeholder());
62735 cycleway.focus = function() {
62736 items.selectAll('.preset-input-cycleway')
62741 return utilRebind(cycleway, dispatch$$1, 'on');
62744 function uiFieldLanes(field, context) {
62745 var dispatch$$1 = dispatch('change'),
62751 function lanes(selection$$1) {
62752 lanesData = context.entity(wayID).lanes();
62754 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
62755 selection$$1.call(lanes.off);
62759 var wrap = selection$$1.selectAll('.preset-input-wrap')
62762 wrap = wrap.enter()
62764 .attr('class', 'preset-input-wrap')
62767 var surface = wrap.selectAll('.surface')
62770 var d = utilGetDimensions(wrap);
62771 var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
62773 surface = surface.enter()
62775 .attr('width', d[0])
62776 .attr('height', 300)
62777 .attr('class', 'surface')
62781 var lanesSelection = surface.selectAll('.lanes')
62784 lanesSelection = lanesSelection.enter()
62786 .attr('class', 'lanes')
62787 .merge(lanesSelection);
62790 .attr('transform', function () {
62791 return 'translate(' + (freeSpace / 2) + ', 0)';
62795 var lane = lanesSelection.selectAll('.lane')
62796 .data(lanesData.lanes);
62801 var enter = lane.enter()
62803 .attr('class', 'lane');
62809 .attr('width', LANE_WIDTH)
62810 .attr('height', LANE_HEIGHT);
62814 .attr('class', 'forward')
62822 .attr('class', 'bothways')
62830 .attr('class', 'backward')
62841 .attr('transform', function(d) {
62842 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
62845 lane.select('.forward')
62846 .style('visibility', function(d) {
62847 return d.direction === 'forward' ? 'visible' : 'hidden';
62850 lane.select('.bothways')
62851 .style('visibility', function(d) {
62852 return d.direction === 'bothways' ? 'visible' : 'hidden';
62855 lane.select('.backward')
62856 .style('visibility', function(d) {
62857 return d.direction === 'backward' ? 'visible' : 'hidden';
62862 lanes.entity = function(_) {
62863 if (!wayID || wayID !== _.id) {
62868 lanes.tags = function() {};
62869 lanes.focus = function() {};
62870 lanes.off = function() {};
62872 return utilRebind(lanes, dispatch$$1, 'on');
62875 function uiFieldLocalized(field, context) {
62876 var dispatch$$1 = dispatch('change', 'input'),
62877 wikipedia = services.wikipedia,
62878 input = select(null),
62879 localizedInputs = select(null),
62884 function localized(selection$$1) {
62885 input = selection$$1.selectAll('.localized-main')
62888 input = input.enter()
62890 .attr('type', 'text')
62891 .attr('id', 'preset-input-' + field.id)
62892 .attr('class', 'localized-main')
62893 .attr('placeholder', field.placeholder())
62897 if (field.id === 'name') {
62898 var preset = context.presets().match(entity, context.graph());
62899 input.call(d3combobox().fetcher(
62900 utilSuggestNames(preset, dataSuggestions)
62905 .on('input', change(true))
62906 .on('blur', change())
62907 .on('change', change());
62910 var translateButton = selection$$1.selectAll('.localized-add')
62913 translateButton = translateButton.enter()
62915 .attr('class', 'button-input-action localized-add minor')
62916 .attr('tabindex', -1)
62917 .call(svgIcon('#icon-plus'))
62919 .title(t('translate.translate'))
62920 .placement('left'))
62921 .merge(translateButton);
62924 .on('click', addNew);
62927 localizedInputs = selection$$1.selectAll('.localized-wrap')
62930 localizedInputs = localizedInputs.enter().append('div')
62931 .attr('class', 'localized-wrap')
62932 .merge(localizedInputs);
62936 function addNew() {
62937 event.preventDefault();
62938 var data$$1 = localizedInputs.selectAll('div.entry').data();
62939 var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
62940 var langExists = lodash.find(data$$1, function(datum) { return datum.lang === defaultLang;});
62941 var isLangEn = defaultLang.indexOf('en') > -1;
62942 if (isLangEn || langExists) {
62945 data$$1.push({ lang: defaultLang, value: '' });
62946 localizedInputs.call(render, data$$1);
62950 function change(onInput) {
62951 return function() {
62953 t$$1[field.key] = utilGetSetValue(select(this)) || undefined;
62954 dispatch$$1.call('change', this, t$$1, onInput);
62959 function key(lang) {
62960 return field.key + ':' + lang;
62964 function changeLang(d) {
62965 var lang = utilGetSetValue(select(this)),
62967 language = lodash.find(dataWikipedia, function(d) {
62968 return d[0].toLowerCase() === lang.toLowerCase() ||
62969 d[1].toLowerCase() === lang.toLowerCase();
62972 if (language) lang = language[2];
62974 if (d.lang && d.lang !== lang) {
62975 t$$1[key(d.lang)] = undefined;
62978 var value = utilGetSetValue(select(this.parentNode)
62979 .selectAll('.localized-value'));
62981 if (lang && value) {
62982 t$$1[key(lang)] = value;
62983 } else if (lang && wikiTitles && wikiTitles[d.lang]) {
62984 t$$1[key(lang)] = wikiTitles[d.lang];
62988 dispatch$$1.call('change', this, t$$1);
62992 function changeValue(d) {
62993 if (!d.lang) return;
62995 t$$1[key(d.lang)] = utilGetSetValue(select(this)) || undefined;
62996 dispatch$$1.call('change', this, t$$1);
63000 function fetcher(value, cb) {
63001 var v = value.toLowerCase();
63003 cb(dataWikipedia.filter(function(d) {
63004 return d[0].toLowerCase().indexOf(v) >= 0 ||
63005 d[1].toLowerCase().indexOf(v) >= 0 ||
63006 d[2].toLowerCase().indexOf(v) >= 0;
63007 }).map(function(d) {
63008 return { value: d[1] };
63013 function render(selection$$1, data$$1) {
63014 var wraps = selection$$1.selectAll('div.entry').
63015 data(data$$1, function(d) { return d.lang; });
63020 .style('max-height','0px')
63021 .style('opacity', '0')
63022 .style('top','-10px')
63025 var innerWrap = wraps.enter()
63026 .insert('div', ':first-child');
63028 innerWrap.attr('class', 'entry')
63030 var wrap = select(this);
63031 var langcombo = d3combobox().fetcher(fetcher).minItems(0);
63035 .attr('class','form-label')
63036 .text(t('translate.localized_translation_label'))
63037 .attr('for','localized-lang');
63041 .attr('class', 'minor remove')
63042 .on('click', function(d){
63043 event.preventDefault();
63045 t$$1[key(d.lang)] = undefined;
63046 dispatch$$1.call('change', this, t$$1);
63047 select(this.parentNode.parentNode)
63049 .style('max-height','240px')
63051 .style('opacity', '0')
63052 .style('max-height','0px')
63055 .call(svgIcon('#operation-delete'));
63059 .attr('class', 'localized-lang')
63060 .attr('type', 'text')
63061 .attr('placeholder',t('translate.localized_translation_language'))
63062 .on('blur', changeLang)
63063 .on('change', changeLang)
63068 .on('blur', changeValue)
63069 .on('change', changeValue)
63070 .attr('type', 'text')
63071 .attr('placeholder', t('translate.localized_translation_name'))
63072 .attr('class', 'localized-value');
63076 .style('margin-top', '0px')
63077 .style('max-height', '0px')
63078 .style('opacity', '0')
63081 .style('margin-top', '10px')
63082 .style('max-height', '240px')
63083 .style('opacity', '1')
63084 .on('end', function() {
63086 .style('max-height', '')
63087 .style('overflow', 'visible');
63091 var entry = selection$$1.selectAll('.entry');
63093 utilGetSetValue(entry.select('.localized-lang'), function(d) {
63094 var lang = lodash.find(dataWikipedia, function(lang) { return lang[2] === d.lang; });
63095 return lang ? lang[1] : d.lang;
63098 utilGetSetValue(entry.select('.localized-value'),
63099 function(d) { return d.value; });
63103 localized.tags = function(tags) {
63104 // Fetch translations from wikipedia
63105 if (tags.wikipedia && !wikiTitles) {
63107 var wm = tags.wikipedia.match(/([^:]+):(.+)/);
63108 if (wm && wm[0] && wm[1]) {
63109 wikipedia.translations(wm[1], wm[2], function(d) {
63115 utilGetSetValue(input, tags[field.key] || '');
63117 var postfixed = [], k, m;
63119 m = k.match(/^(.*):([a-zA-Z_-]+)$/);
63120 if (m && m[1] === field.key && m[2]) {
63121 postfixed.push({ lang: m[2], value: tags[k] });
63125 localizedInputs.call(render, postfixed.reverse());
63129 localized.focus = function() {
63130 input.node().focus();
63134 localized.entity = function(_) {
63135 if (!arguments.length) return entity;
63140 return utilRebind(localized, dispatch$$1, 'on');
63143 function uiFieldMaxspeed(field, context) {
63144 var dispatch$$1 = dispatch('change'),
63147 unitInput = select(null),
63148 input = select(null),
63151 var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
63152 imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
63155 function maxspeed(selection$$1) {
63156 combobox = d3combobox();
63157 var unitCombobox = d3combobox().data(['km/h', 'mph'].map(comboValues));
63159 input = selection$$1.selectAll('#preset-input-' + field.id)
63162 input = input.enter()
63164 .attr('type', 'text')
63165 .attr('id', 'preset-input-' + field.id)
63166 .attr('placeholder', field.placeholder())
63172 .on('change', change)
63173 .on('blur', change);
63175 var childNodes = context.graph().childNodes(context.entity(entity.id)),
63176 loc = childNodes[~~(childNodes.length/2)].loc;
63178 isImperial = lodash.some(dataImperial.features, function(f) {
63179 return lodash.some(f.geometry.coordinates, function(d) {
63180 return geoPointInPolygon(loc, d);
63184 unitInput = selection$$1.selectAll('input.maxspeed-unit')
63187 unitInput = unitInput.enter()
63189 .attr('type', 'text')
63190 .attr('class', 'maxspeed-unit')
63191 .call(unitCombobox)
63195 .on('blur', changeUnits)
63196 .on('change', changeUnits);
63199 function changeUnits() {
63200 isImperial = utilGetSetValue(unitInput) === 'mph';
63201 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
63208 function setSuggestions() {
63209 combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
63210 utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
63214 function comboValues(d) {
63216 value: d.toString(),
63217 title: d.toString()
63222 function change() {
63224 value = utilGetSetValue(input);
63227 tag[field.key] = undefined;
63228 } else if (isNaN(value) || !isImperial) {
63229 tag[field.key] = value;
63231 tag[field.key] = value + ' mph';
63234 dispatch$$1.call('change', this, tag);
63238 maxspeed.tags = function(tags) {
63239 var value = tags[field.key];
63241 if (value && value.indexOf('mph') >= 0) {
63242 value = parseInt(value, 10);
63244 } else if (value) {
63245 isImperial = false;
63249 utilGetSetValue(input, value || '');
63253 maxspeed.focus = function() {
63254 input.node().focus();
63258 maxspeed.entity = function(_) {
63263 return utilRebind(maxspeed, dispatch$$1, 'on');
63266 function uiFieldRadio(field) {
63267 var dispatch$$1 = dispatch('change'),
63268 placeholder = select(null),
63269 labels = select(null),
63270 radios = select(null);
63273 function radio(selection$$1) {
63274 selection$$1.classed('preset-radio', true);
63276 var wrap = selection$$1.selectAll('.preset-input-wrap')
63279 var enter = wrap.enter()
63281 .attr('class', 'preset-input-wrap toggle-list');
63285 .attr('class', 'placeholder');
63291 placeholder = wrap.selectAll('.placeholder');
63293 labels = wrap.selectAll('label')
63294 .data(field.options || field.keys);
63296 enter = labels.enter()
63299 enter.append('input')
63300 .attr('type', 'radio')
63301 .attr('name', field.id)
63302 .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
63303 .attr('checked', false);
63305 enter.append('span')
63306 .text(function(d) { return field.t('options.' + d, { 'default': d }); });
63311 radios = labels.selectAll('input')
63312 .on('change', change);
63316 function change() {
63318 if (field.key) t$$1[field.key] = undefined;
63319 radios.each(function(d) {
63320 var active$$1 = select(this).property('checked');
63322 if (active$$1) t$$1[field.key] = d;
63324 t$$1[d] = active$$1 ? 'yes' : undefined;
63327 dispatch$$1.call('change', this, t$$1);
63331 radio.tags = function(tags) {
63332 function checked(d) {
63334 return tags[field.key] === d;
63336 return !!(tags[d] && tags[d] !== 'no');
63340 labels.classed('active', checked);
63341 radios.property('checked', checked);
63342 var selection$$1 = radios.filter(function() { return this.checked; });
63343 if (selection$$1.empty()) {
63344 placeholder.text(t('inspector.none'));
63346 placeholder.text(selection$$1.attr('value'));
63351 radio.focus = function() {
63352 radios.node().focus();
63356 return utilRebind(radio, dispatch$$1, 'on');
63359 function uiFieldRestrictions(field, context) {
63360 var dispatch$$1 = dispatch('change'),
63361 breathe = behaviorBreathe(context),
63362 hover = behaviorHover(context),
63363 initialized = false,
63368 function restrictions(selection$$1) {
63369 // if form field is hidden or has detached from dom, clean up.
63370 if (!select('.inspector-wrap.inspector-hidden').empty() || !selection$$1.node().parentNode) {
63371 selection$$1.call(restrictions.off);
63375 var wrap = selection$$1.selectAll('.preset-input-wrap')
63378 var enter = wrap.enter()
63380 .attr('class', 'preset-input-wrap');
63384 .attr('class', 'restriction-help');
63387 var intersection = osmIntersection(context.graph(), vertexID),
63388 graph = intersection.graph,
63389 vertex = graph.entity(vertexID),
63390 filter = utilFunctor(true),
63391 extent$$1 = geoExtent$$1(),
63392 projection = geoRawMercator();
63394 var d = utilGetDimensions(wrap.merge(enter)),
63395 c = [d[0] / 2, d[1] / 2],
63399 .scale(256 * Math.pow(2, z) / (2 * Math.PI));
63401 var s = projection(vertex.loc);
63404 .translate([c[0] - s[0], c[1] - s[1]])
63405 .clipExtent([[0, 0], d]);
63407 var drawLayers = svgLayers(projection, context).only('osm').dimensions(d),
63408 drawVertices = svgVertices$$1(projection, context),
63409 drawLines = svgLines$$1(projection, context),
63410 drawTurns = svgTurns(projection, context);
63418 var surface = wrap.selectAll('.surface');
63420 if (!enter.empty()) {
63421 initialized = true;
63428 .call(utilSetDimensions, d)
63429 .call(drawVertices, graph, [vertex], filter, extent$$1, z)
63430 .call(drawLines, graph, intersection.ways, filter)
63431 .call(drawTurns, graph, intersection.turns(fromNodeID));
63434 .on('click.restrictions', click)
63435 .on('mouseover.restrictions', mouseover)
63436 .on('mouseout.restrictions', mouseout);
63439 .selectAll('.selected')
63440 .classed('selected', false);
63444 .selectAll('.' + intersection.highways[fromNodeID].id)
63445 .classed('selected', true);
63451 .on('change.restrictions', render);
63454 .on('resize.restrictions', function() {
63455 utilSetDimensions(wrap, null);
63465 var datum = event.target.__data__;
63466 if (datum instanceof osmEntity$$1) {
63467 fromNodeID = intersection.adjacentNodeId(datum.id);
63469 } else if (datum instanceof osmTurn) {
63470 if (datum.restriction) {
63472 actionUnrestrictTurn(datum, projection),
63473 t('operations.restriction.annotation.delete')
63477 actionRestrictTurn(datum, projection),
63478 t('operations.restriction.annotation.create')
63485 function mouseover() {
63486 var datum = event.target.__data__;
63487 if (datum instanceof osmTurn) {
63488 var graph = context.graph(),
63489 presets = context.presets(),
63492 if (datum.restriction) {
63493 preset = presets.match(graph.entity(datum.restriction), graph);
63495 preset = presets.item('type/restriction/' +
63496 osmInferRestriction(
63506 wrap.selectAll('.restriction-help')
63507 .text(t('operations.restriction.help.' +
63508 (datum.restriction ? 'toggle_off' : 'toggle_on'),
63509 { restriction: preset.name() })
63515 function mouseout() {
63516 wrap.selectAll('.restriction-help')
63517 .text(t('operations.restriction.help.' +
63518 (fromNodeID ? 'toggle' : 'select'))
63523 function render() {
63524 if (context.hasEntity(vertexID)) {
63525 restrictions(selection$$1);
63531 restrictions.entity = function(_) {
63532 if (!vertexID || vertexID !== _.id) {
63539 restrictions.tags = function() {};
63540 restrictions.focus = function() {};
63543 restrictions.off = function(selection$$1) {
63544 if (!initialized) return;
63546 selection$$1.selectAll('.surface')
63549 .on('click.restrictions', null)
63550 .on('mouseover.restrictions', null)
63551 .on('mouseout.restrictions', null);
63554 .on('change.restrictions', null);
63557 .on('resize.restrictions', null);
63561 return utilRebind(restrictions, dispatch$$1, 'on');
63564 function uiFieldTextarea(field) {
63565 var dispatch$$1 = dispatch('change'),
63566 input = select(null);
63569 function textarea(selection$$1) {
63570 input = selection$$1.selectAll('textarea')
63573 input = input.enter()
63574 .append('textarea')
63575 .attr('id', 'preset-input-' + field.id)
63576 .attr('placeholder', field.placeholder() || t('inspector.unknown'))
63577 .attr('maxlength', 255)
63579 .on('input', change(true))
63580 .on('blur', change())
63581 .on('change', change())
63586 function change(onInput) {
63587 return function() {
63589 t$$1[field.key] = utilGetSetValue(input) || undefined;
63590 dispatch$$1.call('change', this, t$$1, onInput);
63595 textarea.tags = function(tags) {
63596 utilGetSetValue(input, tags[field.key] || '');
63600 textarea.focus = function() {
63601 input.node().focus();
63605 return utilRebind(textarea, dispatch$$1, 'on');
63608 function uiFieldWikipedia(field, context) {
63609 var dispatch$$1 = dispatch('change'),
63610 wikipedia = services.wikipedia,
63611 wikidata = services.wikidata,
63612 link = select(null),
63613 lang = select(null),
63614 title = select(null),
63618 function wiki(selection$$1) {
63619 var langcombo = d3combobox()
63620 .fetcher(function(value, cb) {
63621 var v = value.toLowerCase();
63623 cb(dataWikipedia.filter(function(d) {
63624 return d[0].toLowerCase().indexOf(v) >= 0 ||
63625 d[1].toLowerCase().indexOf(v) >= 0 ||
63626 d[2].toLowerCase().indexOf(v) >= 0;
63627 }).map(function(d) {
63628 return { value: d[1] };
63632 var titlecombo = d3combobox()
63633 .fetcher(function(value, cb) {
63635 value = context.entity(entity.id).tags.name || '';
63638 var searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
63639 searchfn(language()[2], value, function(query, data$$1) {
63640 cb(data$$1.map(function(d) {
63641 return { value: d };
63647 lang = selection$$1.selectAll('input.wiki-lang')
63650 lang = lang.enter()
63652 .attr('type', 'text')
63653 .attr('class', 'wiki-lang')
63654 .attr('placeholder', t('translate.localized_translation_language'))
63658 utilGetSetValue(lang, language()[1]);
63662 .on('blur', changeLang)
63663 .on('change', changeLang);
63666 title = selection$$1.selectAll('input.wiki-title')
63669 title = title.enter()
63671 .attr('type', 'text')
63672 .attr('class', 'wiki-title')
63673 .attr('id', 'preset-input-' + field.id)
63680 .on('change', change);
63683 link = selection$$1.selectAll('a.wiki-link')
63686 link = link.enter()
63688 .attr('class', 'wiki-link button-input-action minor')
63689 .attr('tabindex', -1)
63690 .attr('target', '_blank')
63691 .call(svgIcon('#icon-out-link', 'inline'))
63696 function language() {
63697 var value = utilGetSetValue(lang).toLowerCase();
63698 var locale = utilDetect().locale.toLowerCase();
63699 var localeLanguage;
63700 return lodash.find(dataWikipedia, function(d) {
63701 if (d[2] === locale) localeLanguage = d;
63702 return d[0].toLowerCase() === value ||
63703 d[1].toLowerCase() === value ||
63705 }) || localeLanguage || ['English', 'English', 'en'];
63709 function changeLang() {
63710 utilGetSetValue(lang, language()[1]);
63720 function change(skipWikidata) {
63721 var value = utilGetSetValue(title),
63722 m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
63723 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
63728 // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
63729 value = decodeURIComponent(m[2]).replace(/_/g, ' ');
63732 // Best-effort `anchordecode:` implementation
63733 anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
63735 anchor = decodeURIComponent(m[3]);
63737 value += '#' + anchor.replace(/_/g, ' ');
63739 value = value.slice(0, 1).toUpperCase() + value.slice(1);
63740 utilGetSetValue(lang, l[1]);
63741 utilGetSetValue(title, value);
63744 syncTags.wikipedia = value ? language()[2] + ':' + value : undefined;
63745 if (!skipWikidata) {
63746 syncTags.wikidata = undefined;
63749 dispatch$$1.call('change', this, syncTags);
63752 if (skipWikidata || !value || !language()[2]) return;
63754 // attempt asynchronous update of wikidata tag..
63755 var initEntityId = entity.id,
63756 initWikipedia = context.entity(initEntityId).tags.wikipedia;
63758 wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
63759 if (!data$$1 || !Object.keys(data$$1).length) return;
63760 var qids = Object.keys(data$$1);
63762 // 1. most recent change was a tag change
63763 var annotation = t('operations.change_tags.annotation'),
63764 currAnnotation = context.history().undoAnnotation();
63765 if (currAnnotation !== annotation) return;
63767 // 2. same entity exists and still selected
63768 var selectedIds = context.selectedIDs(),
63769 currEntityId = selectedIds.length > 0 && selectedIds[0];
63770 if (currEntityId !== initEntityId) return;
63772 // 3. wikipedia value has not changed
63773 var currTags = lodash.clone(context.entity(currEntityId).tags);
63774 if (initWikipedia !== currTags.wikipedia) return;
63776 // ok to coalesce the update of wikidata tag into the previous tag change
63777 currTags.wikidata = qids && lodash.find(qids, function(id) {
63778 return id.match(/^Q\d+$/);
63781 context.overwrite(actionChangeTags(currEntityId, currTags), annotation);
63782 dispatch$$1.call('change', this, currTags);
63787 wiki.tags = function(tags) {
63788 var value = tags[field.key] || '',
63789 m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
63790 l = m && lodash.find(dataWikipedia, function(d) { return m[1] === d[2]; }),
63791 anchor = m && m[3];
63793 // value in correct format
63795 utilGetSetValue(lang, l[1]);
63796 utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
63799 // Best-effort `anchorencode:` implementation
63800 anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
63802 anchor = anchor.replace(/ /g, '_');
63805 link.attr('href', 'https://' + m[1] + '.wikipedia.org/wiki/' +
63806 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : ''));
63808 // unrecognized value format
63810 utilGetSetValue(title, value);
63811 if (value && value !== '') {
63812 utilGetSetValue(lang, '');
63814 link.attr('href', 'https://en.wikipedia.org/wiki/Special:Search?search=' + value);
63819 wiki.entity = function(_) {
63820 if (!arguments.length) return entity;
63826 wiki.focus = function() {
63827 title.node().focus();
63831 return utilRebind(wiki, dispatch$$1, 'on');
63835 access: uiFieldAccess,
63836 address: uiFieldAddress,
63837 check: uiFieldCheck,
63838 defaultcheck: uiFieldCheck,
63839 combo: uiFieldCombo,
63840 typeCombo: uiFieldCombo,
63841 multiCombo: uiFieldCombo,
63842 networkCombo: uiFieldCombo,
63843 cycleway: uiFieldCycleway,
63846 number: uiFieldText,
63847 email: uiFieldText,
63849 localized: uiFieldLocalized,
63850 lanes: uiFieldLanes,
63851 maxspeed: uiFieldMaxspeed,
63852 radio: uiFieldRadio,
63853 restrictions: uiFieldRestrictions,
63854 textarea: uiFieldTextarea,
63855 wikipedia: uiFieldWikipedia
63858 function uiPreset(context) {
63859 var dispatch$$1 = dispatch('change'),
63867 // Field Constructor
63868 function UIField(field, entity, show) {
63869 field = lodash.clone(field);
63871 field.input = uiFields[field.type](field, context)
63872 .on('change', function(t$$1, onInput) {
63873 dispatch$$1.call('change', field, t$$1, onInput);
63876 if (field.input.entity) field.input.entity(entity);
63878 field.keys = field.keys || [field.key];
63882 field.shown = function() {
63883 return field.id === 'name' || field.show || lodash.some(field.keys, function(key) { return !!tags[key]; });
63886 field.modified = function() {
63887 var original = context.graph().base().entities[entity.id];
63888 return lodash.some(field.keys, function(key) {
63889 return original ? tags[key] !== original.tags[key] : tags[key];
63893 field.revert = function() {
63894 var original = context.graph().base().entities[entity.id],
63896 field.keys.forEach(function(key) {
63897 t$$1[key] = original ? original.tags[key] : undefined;
63902 field.present = function() {
63903 return lodash.some(field.keys, function(key) {
63908 field.remove = function() {
63910 field.keys.forEach(function(key) {
63911 t$$1[key] = undefined;
63920 function fieldKey(field) {
63925 function presets(selection$$1) {
63926 selection$$1.call(uiDisclosure()
63927 .title(t('inspector.all_fields'))
63928 .expanded(context.storage('preset_fields.expanded') !== 'false')
63929 .on('toggled', toggled)
63933 function toggled(expanded) {
63934 context.storage('preset_fields.expanded', expanded);
63939 function content(selection$$1) {
63941 var entity = context.entity(id),
63942 geometry = context.geometry(id),
63943 presets = context.presets();
63947 if (presets.field('name')) {
63948 fieldsArr.push(UIField(presets.field('name'), entity));
63951 preset.fields.forEach(function(field) {
63952 if (field.matchGeometry(geometry)) {
63953 fieldsArr.push(UIField(field, entity, true));
63957 if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
63958 fieldsArr.push(UIField(presets.field('restrictions'), entity, true));
63961 presets.universal().forEach(function(field) {
63962 if (preset.fields.indexOf(field) < 0) {
63963 fieldsArr.push(UIField(field, entity));
63968 var shown = fieldsArr.filter(function(field) { return field.shown(); }),
63969 notShown = fieldsArr.filter(function(field) { return !field.shown(); });
63972 var form = selection$$1.selectAll('.preset-form')
63975 form = form.enter()
63977 .attr('class', 'preset-form inspector-inner fillL3')
63981 var fields = form.selectAll('.form-field')
63982 .data(shown, fieldKey);
63988 var enter = fields.enter()
63990 .attr('class', function(field) {
63991 return 'form-field form-field-' + field.id;
63996 .attr('class', 'form-label')
63997 .attr('for', function(field) { return 'preset-input-' + field.id; })
63998 .text(function(field) { return field.label(); });
64002 .attr('class', 'form-label-button-wrap');
64004 wrap.append('button')
64005 .attr('class', 'remove-icon')
64006 .attr('tabindex', -1)
64007 .call(svgIcon('#operation-delete'));
64009 wrap.append('button')
64010 .attr('class', 'modified-icon')
64011 .attr('tabindex', -1)
64013 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
64021 fields.selectAll('.form-label-button-wrap .remove-icon')
64022 .on('click', remove);
64024 fields.selectAll('.modified-icon')
64025 .on('click', revert);
64029 .classed('modified', function(field) { return field.modified(); })
64030 .classed('present', function(field) { return field.present(); })
64031 .each(function(field) {
64032 var reference = uiTagReference(field.reference || { key: field.key }, context);
64034 if (state === 'hover') {
64035 reference.showing(false);
64040 .selectAll('input')
64041 .on('keydown', function() {
64042 // if user presses enter, and combobox is not active, accept edits..
64043 if (event.keyCode === 13 && select('.combobox').empty()) {
64044 context.enter(modeBrowse(context));
64047 .call(reference.body)
64048 .select('.form-label-button-wrap')
64049 .call(reference.button);
64051 field.input.tags(tags);
64054 notShown = notShown.map(function(field) {
64056 title: field.label(),
64057 value: field.label(),
64063 var more = selection$$1.selectAll('.more-fields')
64064 .data((notShown.length > 0) ? [0] : []);
64069 more = more.enter()
64071 .attr('class', 'more-fields')
64073 .text(t('inspector.add_fields'))
64077 var input = more.selectAll('.value')
64083 input = input.enter()
64085 .attr('class', 'value')
64086 .attr('type', 'text')
64091 .call(utilGetSetValue, '')
64092 .attr('placeholder', function() {
64093 var placeholder = [];
64094 for (var field in notShown) {
64095 placeholder.push(notShown[field].title);
64097 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
64099 .call(d3combobox().data(notShown)
64101 .on('accept', show));
64104 function show(field) {
64105 field = field.field;
64107 content(selection$$1);
64108 field.input.focus();
64112 function revert(field) {
64113 event.stopPropagation();
64114 event.preventDefault();
64115 dispatch$$1.call('change', field, field.revert());
64119 function remove(field) {
64120 event.stopPropagation();
64121 event.preventDefault();
64122 dispatch$$1.call('change', field, field.remove());
64127 presets.preset = function(_) {
64128 if (!arguments.length) return preset;
64129 if (preset && preset.id === _.id) return presets;
64136 presets.state = function(_) {
64137 if (!arguments.length) return state;
64143 presets.tags = function(_) {
64144 if (!arguments.length) return tags;
64146 // Don't reset fieldsArr here.
64151 presets.entityID = function(_) {
64152 if (!arguments.length) return id;
64153 if (id === _) return presets;
64160 return utilRebind(presets, dispatch$$1, 'on');
64163 function uiEntityEditor(context) {
64164 var dispatch$$1 = dispatch('choose'),
64166 coalesceChanges = false,
64173 var presetEditor = uiPreset(context)
64174 .on('change', changeTags);
64175 var rawTagEditor = uiRawTagEditor(context)
64176 .on('change', changeTags);
64179 function entityEditor(selection$$1) {
64180 var entity = context.entity(id),
64181 tags = lodash.clone(entity.tags);
64184 var header = selection$$1.selectAll('.header')
64188 var enter = header.enter()
64190 .attr('class', 'header fillL cf');
64194 .attr('class', 'fl preset-reset preset-choose')
64195 .call(svgIcon((textDirection === 'rtl') ? '#icon-forward' : '#icon-backward'));
64199 .attr('class', 'fr preset-close')
64200 .on('click', function() { context.enter(modeBrowse(context)); })
64201 .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
64205 .text(t('inspector.edit'));
64211 header.selectAll('.preset-reset')
64212 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
64216 var body = selection$$1.selectAll('.inspector-body')
64220 enter = body.enter()
64222 .attr('class', 'inspector-body');
64226 .attr('class', 'preset-list-item inspector-inner')
64228 .attr('class', 'preset-list-button-wrap')
64230 .attr('class', 'preset-list-button preset-reset')
64231 .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
64233 .attr('class', 'label');
64237 .attr('class', 'inspector-border inspector-preset');
64241 .attr('class', 'inspector-border raw-tag-editor inspector-inner');
64245 .attr('class', 'inspector-border raw-member-editor inspector-inner');
64249 .attr('class', 'raw-membership-editor inspector-inner');
64255 body.selectAll('.preset-list-button-wrap')
64256 .call(reference.button);
64258 body.selectAll('.preset-list-item')
64259 .call(reference.body);
64261 body.selectAll('.preset-reset')
64262 .on('click', function() { dispatch$$1.call('choose', this, activePreset); });
64264 body.select('.preset-list-item button')
64265 .call(uiPresetIcon()
64266 .geometry(context.geometry(id))
64267 .preset(activePreset));
64269 body.select('.preset-list-item .label')
64270 .text(activePreset.name());
64272 body.select('.inspector-preset')
64274 .preset(activePreset)
64279 body.select('.raw-tag-editor')
64281 .preset(activePreset)
64286 if (entity.type === 'relation') {
64287 body.select('.raw-member-editor')
64288 .style('display', 'block')
64289 .call(uiRawMemberEditor(context)
64292 body.select('.raw-member-editor')
64293 .style('display', 'none');
64296 body.select('.raw-membership-editor')
64297 .call(uiRawMembershipEditor(context)
64302 .on('change.entity-editor', historyChanged);
64305 function historyChanged() {
64306 if (state === 'hide') return;
64308 var entity = context.hasEntity(id),
64309 graph = context.graph();
64310 if (!entity) return;
64312 entityEditor.preset(context.presets().match(entity, graph));
64313 entityEditor.modified(base !== graph);
64314 entityEditor(selection$$1);
64319 function clean(o) {
64321 function cleanVal(k, v) {
64322 function keepSpaces(k) {
64323 var whitelist = ['opening_hours', 'service_times', 'collection_times',
64324 'operating_times', 'smoking_hours', 'happy_hours'];
64325 return lodash.some(whitelist, function(s) { return k.indexOf(s) !== -1; });
64328 var blacklist = ['description', 'note', 'fixme'];
64329 if (lodash.some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
64331 var cleaned = v.split(';')
64332 .map(function(s) { return s.trim(); })
64333 .join(keepSpaces(k) ? '; ' : ';');
64335 // The code below is not intended to validate websites and emails.
64336 // It is only intended to prevent obvious copy-paste errors. (#2323)
64338 // clean website- and email-like tags
64339 if (k.indexOf('website') !== -1 ||
64340 k.indexOf('email') !== -1 ||
64341 cleaned.indexOf('http') === 0) {
64343 .replace(/[\u200B-\u200F\uFEFF]/g, ''); // strip LRM and other zero width chars
64350 var out = {}, k, v;
64352 if (k && (v = o[k]) !== undefined) {
64353 out[k] = cleanVal(k, v);
64360 // Tag changes that fire on input can all get coalesced into a single
64361 // history operation when the user leaves the field. #2342
64362 function changeTags(changed, onInput) {
64363 var entity = context.entity(id),
64364 annotation = t('operations.change_tags.annotation'),
64365 tags = lodash.clone(entity.tags);
64367 lodash.forEach(changed, function(v, k) {
64368 if (v !== undefined || tags.hasOwnProperty(k)) {
64374 tags = clean(tags);
64377 if (!lodash.isEqual(entity.tags, tags)) {
64378 if (coalesceChanges) {
64379 context.overwrite(actionChangeTags(id, tags), annotation);
64381 context.perform(actionChangeTags(id, tags), annotation);
64382 coalesceChanges = !!onInput;
64388 entityEditor.modified = function(_) {
64389 if (!arguments.length) return modified;
64391 selectAll('button.preset-close use')
64392 .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
64396 entityEditor.state = function(_) {
64397 if (!arguments.length) return state;
64399 return entityEditor;
64403 entityEditor.entityID = function(_) {
64404 if (!arguments.length) return id;
64406 base = context.graph();
64407 entityEditor.preset(context.presets().match(context.entity(id), base));
64408 entityEditor.modified(false);
64409 coalesceChanges = false;
64410 return entityEditor;
64414 entityEditor.preset = function(_) {
64415 if (!arguments.length) return activePreset;
64416 if (_ !== activePreset) {
64418 reference = uiTagReference(activePreset.reference(context.geometry(id)), context)
64421 return entityEditor;
64425 return utilRebind(entityEditor, dispatch$$1, 'on');
64428 function uiPresetList(context) {
64429 var dispatch$$1 = dispatch('choose'),
64435 function presetList(selection$$1) {
64436 var entity = context.entity(id),
64437 geometry = context.geometry(id);
64439 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
64440 if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
64441 geometry = 'point';
64444 var presets = context.presets().matchGeometry(geometry);
64446 selection$$1.html('');
64448 var messagewrap = selection$$1
64450 .attr('class', 'header fillL cf');
64452 var message = messagewrap
64454 .text(t('inspector.choose'));
64456 if (context.entity(id).isUsed(context.graph())) {
64459 .attr('class', 'preset-choose')
64460 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
64461 .call(svgIcon((textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'));
64465 .attr('class', 'close')
64466 .on('click', function() {
64467 context.enter(modeBrowse(context));
64469 .call(svgIcon('#icon-close'));
64472 function keydown() {
64473 // hack to let delete shortcut work when search is autofocused
64474 if (search.property('value').length === 0 &&
64475 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
64476 event.keyCode === d3keybinding.keyCodes['⌦'])) {
64477 event.preventDefault();
64478 event.stopPropagation();
64479 operationDelete([id], context)();
64480 } else if (search.property('value').length === 0 &&
64481 (event.ctrlKey || event.metaKey) &&
64482 event.keyCode === d3keybinding.keyCodes.z) {
64483 event.preventDefault();
64484 event.stopPropagation();
64486 } else if (!event.ctrlKey && !event.metaKey) {
64487 select(this).on('keydown', null);
64491 function keypress() {
64493 var value = search.property('value');
64494 if (event.keyCode === 13 && value.length) {
64495 list.selectAll('.preset-list-item:first-child').datum().choose();
64499 function inputevent() {
64500 var value = search.property('value');
64501 list.classed('filtered', value.length);
64502 if (value.length) {
64503 var results = presets.search(value, geometry);
64504 message.text(t('inspector.results', {
64505 n: results.collection.length,
64508 list.call(drawList, results);
64510 list.call(drawList, context.presets().defaults(geometry, 36));
64511 message.text(t('inspector.choose'));
64515 var searchWrap = selection$$1
64517 .attr('class', 'search-header');
64519 var search = searchWrap
64521 .attr('class', 'preset-search-input')
64522 .attr('placeholder', t('inspector.search'))
64523 .attr('type', 'search')
64525 .on('keydown', keydown)
64526 .on('keypress', keypress)
64527 .on('input', inputevent);
64530 .call(svgIcon('#icon-search', 'pre-text'));
64533 search.node().focus();
64536 var listWrap = selection$$1
64538 .attr('class', 'inspector-body');
64540 var list = listWrap
64542 .attr('class', 'preset-list fillL cf')
64543 .call(drawList, context.presets().defaults(geometry, 36));
64547 function drawList(list, presets) {
64548 var collection = presets.collection.map(function(preset) {
64549 return preset.members ? CategoryItem(preset) : PresetItem(preset);
64552 var items = list.selectAll('.preset-list-item')
64553 .data(collection, function(d) { return d.preset.id; });
64562 .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
64563 .classed('current', function(item) { return item.preset === currentPreset; })
64564 .each(function(item) { select(this).call(item); })
64565 .style('opacity', 0)
64567 .style('opacity', 1);
64571 function CategoryItem(preset) {
64572 var box, sublist, shown = false;
64574 function item(selection$$1) {
64575 var wrap = selection$$1.append('div')
64576 .attr('class', 'preset-list-button-wrap category col12');
64580 .attr('class', 'preset-list-button')
64581 .classed('expanded', false)
64582 .call(uiPresetIcon()
64583 .geometry(context.geometry(id))
64585 .on('click', function() {
64586 var isExpanded = select(this).classed('expanded');
64587 var iconName = isExpanded ?
64588 (textDirection === 'rtl' ? '#icon-backward' : '#icon-forward') : '#icon-down';
64590 .classed('expanded', !isExpanded);
64591 select(this).selectAll('div.label svg.icon use')
64592 .attr('href', iconName);
64598 .attr('class', 'label');
64601 .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'))
64603 .html(function() { return preset.name() + '…'; });
64605 box = selection$$1.append('div')
64606 .attr('class', 'subgrid col12')
64607 .style('max-height', '0px')
64608 .style('opacity', 0);
64611 .attr('class', 'arrow');
64613 sublist = box.append('div')
64614 .attr('class', 'preset-list fillL3 cf fl');
64618 item.choose = function() {
64619 if (!box || !sublist) return;
64625 .style('opacity', '0')
64626 .style('max-height', '0px')
64627 .style('padding-bottom', '0px');
64630 sublist.call(drawList, preset.members);
64633 .style('opacity', '1')
64634 .style('max-height', 200 + preset.members.collection.length * 80 + 'px')
64635 .style('padding-bottom', '20px');
64639 item.preset = preset;
64645 function PresetItem(preset) {
64646 function item(selection$$1) {
64647 var wrap = selection$$1.append('div')
64648 .attr('class', 'preset-list-button-wrap col12');
64650 wrap.append('button')
64651 .attr('class', 'preset-list-button')
64652 .call(uiPresetIcon()
64653 .geometry(context.geometry(id))
64655 .on('click', item.choose)
64657 .attr('class', 'label')
64658 .text(preset.name());
64660 wrap.call(item.reference.button);
64661 selection$$1.call(item.reference.body);
64664 item.choose = function() {
64665 context.presets().choose(preset);
64668 actionChangePreset(id, currentPreset, preset),
64669 t('operations.change_tags.annotation')
64672 dispatch$$1.call('choose', this, preset);
64675 item.help = function() {
64676 event.stopPropagation();
64677 item.reference.toggle();
64680 item.preset = preset;
64681 item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
64687 presetList.autofocus = function(_) {
64688 if (!arguments.length) return autofocus;
64694 presetList.entityID = function(_) {
64695 if (!arguments.length) return id;
64697 presetList.preset(context.presets().match(context.entity(id), context.graph()));
64702 presetList.preset = function(_) {
64703 if (!arguments.length) return currentPreset;
64709 return utilRebind(presetList, dispatch$$1, 'on');
64712 function uiViewOnOSM(context) {
64715 function viewOnOSM(selection) {
64716 var entity = context.entity(id);
64718 selection.style('display', entity.isNew() ? 'none' : null);
64720 var link = selection.selectAll('.view-on-osm')
64723 var enter = link.enter()
64725 .attr('class', 'view-on-osm')
64726 .attr('target', '_blank')
64727 .call(svgIcon('#icon-out-link', 'inline'));
64731 .text(t('inspector.view_on_osm'));
64735 .attr('href', context.connection().entityURL(entity));
64739 viewOnOSM.entityID = function(_) {
64740 if (!arguments.length) return id;
64748 function uiInspector(context) {
64749 var presetList = uiPresetList(context),
64750 entityEditor = uiEntityEditor(context),
64753 newFeature = false;
64756 function inspector(selection$$1) {
64758 .entityID(entityID)
64759 .autofocus(newFeature)
64760 .on('choose', setPreset);
64764 .entityID(entityID)
64765 .on('choose', showList);
64767 var wrap = selection$$1.selectAll('.panewrap')
64770 var enter = wrap.enter()
64772 .attr('class', 'panewrap');
64776 .attr('class', 'preset-list-pane pane');
64780 .attr('class', 'entity-editor-pane pane');
64782 wrap = wrap.merge(enter);
64783 var presetPane = wrap.selectAll('.preset-list-pane');
64784 var editorPane = wrap.selectAll('.entity-editor-pane');
64786 var graph = context.graph(),
64787 entity = context.entity(entityID),
64788 showEditor = state === 'hover' ||
64789 entity.isUsed(graph) ||
64790 entity.isHighwayIntersection(graph);
64793 wrap.style('right', '0%');
64794 editorPane.call(entityEditor);
64796 wrap.style('right', '-100%');
64797 presetPane.call(presetList);
64800 var footer = selection$$1.selectAll('.footer')
64803 footer = footer.enter()
64805 .attr('class', 'footer')
64809 .call(uiViewOnOSM(context).entityID(entityID));
64812 function showList(preset) {
64814 .styleTween('right', function() { return value$1('0%', '-100%'); });
64817 .call(presetList.preset(preset).autofocus(true));
64821 function setPreset(preset) {
64823 .styleTween('right', function() { return value$1('-100%', '0%'); });
64826 .call(entityEditor.preset(preset));
64831 inspector.state = function(_) {
64832 if (!arguments.length) return state;
64834 entityEditor.state(state);
64839 inspector.entityID = function(_) {
64840 if (!arguments.length) return entityID;
64846 inspector.newFeature = function(_) {
64847 if (!arguments.length) return newFeature;
64856 function uiNotice(context) {
64858 return function(selection) {
64859 var div = selection
64861 .attr('class', 'notice');
64865 .attr('class', 'zoom-to notice')
64866 .on('click', function() { context.map().zoom(context.minEditableZoom()); });
64869 .call(svgIcon('#icon-plus', 'pre-text'))
64871 .attr('class', 'label')
64872 .text(t('zoom_in_edit'));
64875 function disableTooHigh() {
64876 div.style('display', context.editable() ? 'none' : 'block');
64880 .on('move.notice', lodash.debounce(disableTooHigh, 500));
64886 function uiSidebar(context) {
64887 var inspector = uiInspector(context),
64891 function sidebar(selection) {
64892 var featureListWrap = selection
64894 .attr('class', 'feature-list-pane')
64895 .call(uiFeatureList(context));
64898 .call(uiNotice(context));
64900 var inspectorWrap = selection
64902 .attr('class', 'inspector-hidden inspector-wrap fr');
64905 function hover(id) {
64906 if (!current && context.hasEntity(id)) {
64908 .classed('inspector-hidden', true);
64911 .classed('inspector-hidden', false)
64912 .classed('inspector-hover', true);
64914 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
64923 } else if (!current) {
64925 .classed('inspector-hidden', false);
64927 .classed('inspector-hidden', true);
64934 sidebar.hover = lodash.throttle(hover, 200);
64937 sidebar.select = function(id, newFeature) {
64938 if (!current && id) {
64940 .classed('inspector-hidden', true);
64943 .classed('inspector-hidden', false)
64944 .classed('inspector-hover', false);
64946 if (inspector.entityID() !== id || inspector.state() !== 'select') {
64950 .newFeature(newFeature);
64956 } else if (!current) {
64958 .classed('inspector-hidden', false);
64960 .classed('inspector-hidden', true);
64967 sidebar.show = function(component) {
64969 .classed('inspector-hidden', true);
64971 .classed('inspector-hidden', true);
64973 if (current) current.remove();
64974 current = selection
64976 .attr('class', 'sidebar-component')
64981 sidebar.hide = function() {
64983 .classed('inspector-hidden', false);
64985 .classed('inspector-hidden', true);
64987 if (current) current.remove();
64993 sidebar.hover = function() {};
64994 sidebar.hover.cancel = function() {};
64995 sidebar.select = function() {};
64996 sidebar.show = function() {};
64997 sidebar.hide = function() {};
65002 function uiSpinner(context) {
65003 var connection = context.connection();
65006 return function(selection) {
65007 var img = selection
65009 .attr('src', context.imagePath('loader-black.gif'))
65010 .style('opacity', 0);
65013 .on('loading.spinner', function() {
65015 .style('opacity', 1);
65019 .on('loaded.spinner', function() {
65021 .style('opacity', 0);
65026 function uiSplash(context) {
65028 return function(selection$$1) {
65029 if (context.storage('sawSplash'))
65032 context.storage('sawSplash', true);
65034 var modalSelection = uiModal(selection$$1);
65036 modalSelection.select('.modal')
65037 .attr('class', 'modal-splash modal col6');
65039 var introModal = modalSelection.select('.content')
65041 .attr('class', 'fillL');
65045 .attr('class','modal-section cf')
65046 .append('h3').text(t('splash.welcome'));
65050 .attr('class','modal-section')
65052 .html(t('splash.text', {
65053 version: context.version,
65054 website: '<a href="http://ideditor.com/">ideditor.com</a>',
65055 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
65058 var buttons = introModal
65060 .attr('class', 'modal-actions cf');
65064 .attr('class', 'col6 walkthrough')
65065 .text(t('splash.walkthrough'))
65066 .on('click', function() {
65067 select(document.body).call(uiIntro(context));
65068 modalSelection.close();
65073 .attr('class', 'col6 start')
65074 .text(t('splash.start'))
65075 .on('click', modalSelection.close);
65077 modalSelection.select('button.close')
65078 .attr('class','hide');
65083 function uiStatus(context) {
65084 var connection = context.connection();
65086 return function(selection$$1) {
65088 function update() {
65089 connection.status(function(err, apiStatus) {
65090 selection$$1.html('');
65093 if (apiStatus === 'rateLimited') {
65095 .text(t('status.rateLimit'))
65097 .attr('class', 'api-status-login')
65098 .attr('target', '_blank')
65099 .call(svgIcon('#icon-out-link', 'inline'))
65102 .on('click.login', function() {
65103 event.preventDefault();
65104 connection.authenticate();
65107 // TODO: nice messages for different error types
65108 selection$$1.text(t('status.error'));
65111 } else if (apiStatus === 'readonly') {
65112 selection$$1.text(t('status.readonly'));
65113 } else if (apiStatus === 'offline') {
65114 selection$$1.text(t('status.offline'));
65117 selection$$1.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
65122 .on('change', function() { update(selection$$1); });
65124 window.setInterval(update, 90000);
65125 update(selection$$1);
65129 function uiUndoRedo(context) {
65133 action: function() { if (!(context.inIntro() || saving())) context.undo(); },
65134 annotation: function() { return context.history().undoAnnotation(); }
65138 action: function() {if (!(context.inIntro() || saving())) context.redo(); },
65139 annotation: function() { return context.history().redoAnnotation(); }
65143 function saving() {
65144 return context.mode().id === 'save';
65148 return function(selection$$1) {
65149 var tooltipBehavior = tooltip()
65150 .placement('bottom')
65152 .title(function (d) {
65153 return uiTooltipHtml(d.annotation() ?
65154 t(d.id + '.tooltip', {action: d.annotation()}) :
65155 t(d.id + '.nothing'), d.cmd);
65158 var buttons = selection$$1.selectAll('button')
65162 .attr('class', 'col6 disabled')
65163 .on('click', function(d) { return d.action(); })
65164 .call(tooltipBehavior);
65166 buttons.each(function(d) {
65167 var iconName = d.id;
65168 if (textDirection === 'rtl') {
65169 if (iconName === 'undo') {
65171 } else if (iconName === 'redo') {
65176 .call(svgIcon('#icon-' + iconName));
65179 var keybinding = d3keybinding('undo')
65180 .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
65181 .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
65187 .on('change.undo_redo', update);
65190 .on('enter.undo_redo', update);
65192 function update() {
65194 .property('disabled', saving())
65195 .classed('disabled', function(d) { return !d.annotation(); })
65197 var selection$$1 = select(this);
65198 if (selection$$1.property('tooltipVisible')) {
65199 selection$$1.call(tooltipBehavior.show);
65206 function uiZoom(context) {
65210 title: t('zoom.in'),
65211 action: context.zoomIn,
65216 title: t('zoom.out'),
65217 action: context.zoomOut,
65222 function zoomIn() {
65223 event.preventDefault();
65224 if (!context.inIntro()) context.zoomIn();
65228 function zoomOut() {
65229 event.preventDefault();
65230 if (!context.inIntro()) context.zoomOut();
65234 function zoomInFurther() {
65235 event.preventDefault();
65236 if (!context.inIntro()) context.zoomInFurther();
65240 function zoomOutFurther() {
65241 event.preventDefault();
65242 if (!context.inIntro()) context.zoomOutFurther();
65246 return function(selection$$1) {
65247 var button = selection$$1.selectAll('button')
65251 .attr('tabindex', -1)
65252 .attr('class', function(d) { return d.id; })
65253 .on('click.editor', function(d) { d.action(); })
65255 .placement((textDirection === 'rtl') ? 'right' : 'left')
65257 .title(function(d) {
65258 return uiTooltipHtml(d.title, d.key);
65262 button.each(function(d) {
65264 .call(svgIcon('#icon-' + d.icon, 'light'));
65267 var keybinding = d3keybinding('zoom');
65269 lodash.each(['=','ffequals','plus','ffplus'], function(key) {
65270 keybinding.on([key, '⇧' + key], zoomIn);
65271 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomInFurther);
65273 lodash.each(['-','ffminus','dash'], function(key) {
65274 keybinding.on([key, '⇧' + key], zoomOut);
65275 keybinding.on([uiCmd('⌘' + key), uiCmd('⌘⇧' + key)], zoomOutFurther);
65283 function uiInit(context) {
65284 var uiInitCounter = 0;
65287 function render(container) {
65289 .attr('dir', textDirection);
65291 var map$$1 = context.map();
65293 var hash = behaviorHash(context);
65296 if (!hash.hadHash) {
65297 map$$1.centerZoom([0, 0], 2);
65302 .attr('id', 'defs')
65303 .call(svgDefs(context));
65307 .attr('id', 'sidebar')
65308 .attr('class', 'col4')
65311 var content = container
65313 .attr('id', 'content')
65314 .attr('class', 'active');
65319 .attr('class', 'fillD');
65324 .attr('dir', 'ltr')
65328 .call(uiMapInMap(context));
65332 .call(uiInfo(context));
65336 .attr('class', 'spacer col4');
65338 var limiter = bar.append('div')
65339 .attr('class', 'limiter');
65343 .attr('class', 'button-wrap joined col3')
65344 .call(uiModes(context), limiter);
65348 .attr('class', 'button-wrap joined col1')
65349 .call(uiUndoRedo(context));
65353 .attr('class', 'button-wrap col1')
65354 .call(uiSave(context));
65358 .attr('class', 'full-screen')
65359 .call(uiFullScreen(context));
65363 .attr('class', 'spinner')
65364 .call(uiSpinner(context));
65368 .attr('class', 'map-controls');
65372 .attr('class', 'map-control zoombuttons')
65373 .call(uiZoom(context));
65377 .attr('class', 'map-control geolocate-control')
65378 .call(uiGeolocate(context));
65382 .attr('class', 'map-control background-control')
65383 .call(uiBackground(context));
65387 .attr('class', 'map-control map-data-control')
65388 .call(uiMapData(context));
65392 .attr('class', 'map-control help-control')
65393 .call(uiHelp(context));
65395 var about = content
65397 .attr('id', 'about');
65401 .attr('id', 'attrib')
65402 .attr('dir', 'ltr')
65403 .call(uiAttribution(context));
65407 .attr('id', 'footer')
65408 .attr('class', 'fillD');
65412 .attr('class', 'api-status')
65413 .call(uiStatus(context));
65417 .attr('id', 'scale-block')
65418 .call(uiScale(context));
65420 var aboutList = footer
65422 .attr('id', 'info-block')
65424 .attr('id', 'about-list');
65426 if (!context.embed()) {
65427 aboutList.call(uiAccount(context));
65433 .attr('target', '_blank')
65434 .attr('tabindex', -1)
65435 .attr('href', 'https://github.com/openstreetmap/iD')
65436 .text(context.version);
65438 var issueLinks = aboutList
65443 .attr('target', '_blank')
65444 .attr('tabindex', -1)
65445 .attr('href', 'https://github.com/openstreetmap/iD/issues')
65446 .call(svgIcon('#icon-bug', 'light'))
65447 .call(tooltip().title(t('report_a_bug')).placement('top'));
65451 .attr('target', '_blank')
65452 .attr('tabindex', -1)
65453 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
65454 .call(svgIcon('#icon-translate', 'light'))
65455 .call(tooltip().title(t('help_translate')).placement('top'));
65459 .attr('class', 'feature-warning')
65460 .attr('tabindex', -1)
65461 .call(uiFeatureInfo(context));
65465 .attr('class', 'user-list')
65466 .attr('tabindex', -1)
65467 .call(uiContributors(context));
65470 window.onbeforeunload = function() {
65471 return context.save();
65474 window.onunload = function() {
65475 context.history().unlock();
65478 var mapDimensions = map$$1.dimensions();
65481 function onResize() {
65482 mapDimensions = utilGetDimensions(content, true);
65483 map$$1.dimensions(mapDimensions);
65487 .on('resize.editor', onResize);
65492 return function() {
65493 event.preventDefault();
65494 if (!context.inIntro()) {
65495 context.pan(d, 100);
65504 var keybinding = d3keybinding('main')
65505 .on('⌫', function() { event.preventDefault(); })
65506 .on('←', pan([pa, 0]))
65507 .on('↑', pan([0, pa]))
65508 .on('→', pan([-pa, 0]))
65509 .on('↓', pan([0, -pa]))
65510 .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
65511 .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
65512 .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
65513 .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
65518 context.enter(modeBrowse(context));
65520 if (!uiInitCounter++) {
65521 context.container()
65522 .call(uiSplash(context))
65523 .call(uiRestore(context));
65526 var authenticating = uiLoading(context)
65527 .message(t('loading_auth'))
65530 context.connection()
65531 .on('authLoading.ui', function() {
65532 context.container()
65533 .call(authenticating);
65535 .on('authDone.ui', function() {
65536 authenticating.close();
65543 var renderCallback;
65545 function ui(node, callback) {
65546 renderCallback = callback;
65547 var container = select(node);
65548 context.container(container);
65549 context.loadLocale(function(err) {
65560 ui.restart = function(arg) {
65561 context.locale(arg);
65562 context.loadLocale(function(err) {
65564 context.container().selectAll('*').remove();
65565 render(context.container());
65566 if (renderCallback) renderCallback();
65572 ui.sidebar = uiSidebar(context);
65577 function uiCommit(context) {
65578 var dispatch$$1 = dispatch('cancel', 'save');
65581 function commit(selection$$1) {
65582 var changes = context.history().changes(),
65583 summary = context.history().difference().summary();
65587 .attr('class', 'header fillL')
65589 .text(t('commit.title'));
65591 var body = selection$$1
65593 .attr('class', 'body');
65595 var commentSection = body
65597 .attr('class', 'modal-section form-field commit-form');
65601 .attr('class', 'form-label')
65602 .text(t('commit.message_label'));
65604 var commentField = commentSection
65605 .append('textarea')
65606 .attr('placeholder', t('commit.description_placeholder'))
65607 .attr('maxlength', 255)
65608 .property('value', context.storage('comment') || '')
65609 .on('input.save', checkComment)
65610 .on('change.save', checkComment)
65611 .on('blur.save', function() {
65612 context.storage('comment', this.value);
65616 commentField.node().select();
65618 context.connection().userChangesets(function (err, changesets) {
65621 var comments = changesets.map(function(changeset) {
65623 title: changeset.tags.comment,
65624 value: changeset.tags.comment
65630 .caseSensitive(true)
65631 .data(lodash.uniqBy(comments, 'title'))
65635 var clippyArea = commentSection.append('div')
65636 .attr('class', 'clippy-area');
65638 var changeSetInfo = commentSection.append('div')
65639 .attr('class', 'changeset-info');
65641 changeSetInfo.append('a')
65642 .attr('target', '_blank')
65643 .attr('tabindex', -1)
65644 .call(svgIcon('#icon-out-link', 'inline'))
65645 .attr('href', t('commit.about_changeset_comments_link'))
65647 .text(t('commit.about_changeset_comments'));
65651 var warnings = body.selectAll('div.warning-section')
65652 .data([context.history().validate(changes)]);
65654 warnings = warnings.enter()
65656 .attr('class', 'modal-section warning-section fillL2')
65657 .style('display', function(d) { return lodash.isEmpty(d) ? 'none' : null; })
65658 .style('background', '#ffb')
65663 .text(t('commit.warnings'));
65667 .attr('class', 'changeset-list');
65669 var warningLi = warnings.select('ul').selectAll('li')
65670 .data(function(d) { return d; });
65672 warningLi = warningLi.enter()
65674 .on('mouseover', mouseover)
65675 .on('mouseout', mouseout)
65676 .on('click', warningClick)
65680 .call(svgIcon('#icon-alert', 'pre-text'));
65684 .text(function(d) { return d.message; });
65686 warningLi.filter(function(d) { return d.tooltip; })
65688 .title(function(d) { return d.tooltip; })
65693 // Upload Explanation
65694 var saveSection = body
65696 .attr('class','modal-section save-section fillL cf');
65698 var prose = saveSection
65700 .attr('class', 'commit-info')
65701 .html(t('commit.upload_explanation'));
65704 context.connection().userDetails(function(err, user) {
65707 var userLink = select(document.createElement('div'));
65709 if (user.image_url) {
65712 .attr('src', user.image_url)
65713 .attr('class', 'icon pre-text user-icon');
65718 .attr('class','user-info')
65719 .text(user.display_name)
65720 .attr('href', context.connection().userURL(user.display_name))
65721 .attr('tabindex', -1)
65722 .attr('target', '_blank');
65725 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
65730 var buttonSection = saveSection
65732 .attr('class','buttons fillL cf');
65734 var cancelButton = buttonSection
65736 .attr('class', 'secondary-action col5 button cancel-button')
65737 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
65741 .attr('class', 'label')
65742 .text(t('commit.cancel'));
65744 var saveButton = buttonSection
65746 .attr('class', 'action col5 button save-button')
65747 .attr('disabled', function() {
65748 var n = select('.commit-form textarea').node();
65749 return (n && n.value.length) ? null : true;
65751 .on('click.save', function() {
65752 dispatch$$1.call('save', this, {
65753 comment: commentField.node().value
65759 .attr('class', 'label')
65760 .text(t('commit.save'));
65764 var changeSection = body
65766 .attr('class', 'commit-section modal-section fillL2');
65768 changeSection.append('h3')
65769 .text(t('commit.changes', { count: summary.length }));
65771 var li = changeSection
65773 .attr('class', 'changeset-list')
65779 .on('mouseover', mouseover)
65780 .on('mouseout', mouseout)
65781 .on('click', zoomToEntity)
65784 li.each(function(d) {
65786 .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
65790 .attr('class', 'change-type')
65791 .text(function(d) { return t('commit.' + d.changeType) + ' '; });
65793 li.append('strong')
65794 .attr('class', 'entity-type')
65795 .text(function(d) {
65796 var matched = context.presets().match(d.entity, d.graph);
65797 return (matched && matched.name()) || utilDisplayType(d.entity.id);
65801 .attr('class', 'entity-name')
65802 .text(function(d) {
65803 var name = utilDisplayName(d.entity) || '',
65805 if (name !== '') string += ':';
65806 return string += ' ' + name;
65809 li.style('opacity', 0)
65811 .style('opacity', 1);
65814 // Call checkComment off the bat, in case a changeset
65815 // comment is recovered from localStorage
65816 utilTriggerEvent(commentField, 'input');
65819 function mouseover(d) {
65821 context.surface().selectAll(
65822 utilEntityOrMemberSelector([d.entity.id], context.graph())
65823 ).classed('hover', true);
65828 function mouseout() {
65829 context.surface().selectAll('.hover')
65830 .classed('hover', false);
65834 function warningClick(d) {
65836 context.map().zoomTo(d.entity);
65838 modeSelect(context, [d.entity.id]).suppressMenu(true)
65844 function zoomToEntity(change) {
65845 var entity = change.entity;
65846 if (change.changeType !== 'deleted' &&
65847 context.graph().entity(entity.id).geometry(context.graph()) !== 'vertex') {
65848 context.map().zoomTo(entity);
65849 context.surface().selectAll(
65850 utilEntityOrMemberSelector([entity.id], context.graph()))
65851 .classed('hover', true);
65856 function checkComment() {
65857 selectAll('.save-section .save-button')
65858 .attr('disabled', (this.value.length ? null : true));
65860 var googleWarning = clippyArea
65863 .data(this.value.match(/google/i) ? [true] : []);
65865 googleWarning.exit()
65868 googleWarning.enter()
65870 .attr('target', '_blank')
65871 .attr('tabindex', -1)
65872 .call(svgIcon('#icon-alert', 'inline'))
65873 .attr('href', t('commit.google_warning_link'))
65875 .text(t('commit.google_warning'));
65879 return utilRebind(commit, dispatch$$1, 'on');
65882 function uiConfirm(selection) {
65883 var modalSelection = uiModal(selection);
65885 modalSelection.select('.modal')
65886 .classed('modal-alert', true);
65888 var section = modalSelection.select('.content');
65890 section.append('div')
65891 .attr('class', 'modal-section header');
65893 section.append('div')
65894 .attr('class', 'modal-section message-text');
65896 var buttons = section.append('div')
65897 .attr('class', 'modal-section buttons cf');
65900 modalSelection.okButton = function() {
65903 .attr('class', 'action col4')
65904 .on('click.confirm', function() {
65905 modalSelection.remove();
65907 .text(t('confirm.okay'));
65909 return modalSelection;
65913 return modalSelection;
65916 function uiConflicts(context) {
65917 var dispatch$$1 = dispatch('download', 'cancel', 'save'),
65921 function conflicts(selection$$1) {
65922 var header = selection$$1
65924 .attr('class', 'header fillL');
65928 .attr('class', 'fr')
65929 .on('click', function() { dispatch$$1.call('cancel'); })
65930 .call(svgIcon('#icon-close'));
65934 .text(t('save.conflict.header'));
65936 var body = selection$$1
65938 .attr('class', 'body fillL');
65942 .attr('class', 'conflicts-help')
65943 .text(t('save.conflict.help'))
65945 .attr('class', 'conflicts-download')
65946 .text(t('save.conflict.download_changes'))
65947 .on('click.download', function() { dispatch$$1.call('download'); });
65951 .attr('class', 'conflict-container fillL3')
65952 .call(showConflict, 0);
65956 .attr('class', 'conflicts-done')
65957 .attr('opacity', 0)
65958 .style('display', 'none')
65959 .text(t('save.conflict.done'));
65963 .attr('class','buttons col12 joined conflicts-buttons');
65967 .attr('disabled', list.length > 1)
65968 .attr('class', 'action conflicts-button col6')
65969 .text(t('save.title'))
65970 .on('click.try_again', function() { dispatch$$1.call('save'); });
65974 .attr('class', 'secondary-action conflicts-button col6')
65975 .text(t('confirm.cancel'))
65976 .on('click.cancel', function() { dispatch$$1.call('cancel'); });
65980 function showConflict(selection$$1, index) {
65981 if (index < 0 || index >= list.length) return;
65983 var parent = select(selection$$1.node().parentNode);
65985 // enable save button if this is the last conflict being reviewed..
65986 if (index === list.length - 1) {
65987 window.setTimeout(function() {
65988 parent.select('.conflicts-button')
65989 .attr('disabled', null);
65991 parent.select('.conflicts-done')
65993 .attr('opacity', 1)
65994 .style('display', 'block');
65998 var item = selection$$1
65999 .selectAll('.conflict')
66000 .data([list[index]]);
66002 var enter = item.enter()
66004 .attr('class', 'conflict');
66008 .attr('class', 'conflict-count')
66009 .text(t('save.conflict.count', { num: index + 1, total: list.length }));
66013 .attr('class', 'conflict-description')
66015 .text(function(d) { return d.name; })
66016 .on('click', function(d) {
66017 zoomToEntity(d.id);
66018 event.preventDefault();
66021 var details = enter
66023 .attr('class', 'conflict-detail-container');
66027 .attr('class', 'conflict-detail-list')
66029 .data(function(d) { return d.details || []; })
66032 .attr('class', 'conflict-detail-item')
66033 .html(function(d) { return d; });
66037 .attr('class', 'conflict-choices')
66042 .attr('class', 'conflict-nav-buttons joined cf')
66043 .selectAll('button')
66044 .data(['previous', 'next'])
66047 .text(function(d) { return t('save.conflict.' + d); })
66048 .attr('class', 'conflict-nav-button action col6')
66049 .attr('disabled', function(d, i) {
66050 return (i === 0 && index === 0) ||
66051 (i === 1 && index === list.length - 1) || null;
66053 .on('click', function(d, i) {
66054 var container = parent.select('.conflict-container'),
66055 sign = (i === 0 ? -1 : 1);
66058 .selectAll('.conflict')
66062 .call(showConflict, index + sign);
66064 event.preventDefault();
66072 function addChoices(selection$$1) {
66073 var choices = selection$$1
66075 .attr('class', 'layer-list')
66077 .data(function(d) { return d.choices || []; });
66079 var enter = choices.enter()
66081 .attr('class', 'layer');
66088 .attr('type', 'radio')
66089 .attr('name', function(d) { return d.id; })
66090 .on('change', function(d, i) {
66091 var ul = this.parentNode.parentNode.parentNode;
66092 ul.__data__.chosen = i;
66098 .text(function(d) { return d.text; });
66101 .each(function(d, i) {
66102 var ul = this.parentNode;
66103 if (ul.__data__.chosen === i) choose(ul, d);
66108 function choose(ul, datum) {
66109 if (event) event.preventDefault();
66113 .classed('active', function(d) { return d === datum; })
66114 .selectAll('input')
66115 .property('checked', function(d) { return d === datum; });
66117 var extent$$1 = geoExtent$$1(),
66120 entity = context.graph().hasEntity(datum.id);
66121 if (entity) extent$$1._extend(entity.extent(context.graph()));
66125 entity = context.graph().hasEntity(datum.id);
66126 if (entity) extent$$1._extend(entity.extent(context.graph()));
66128 zoomToEntity(datum.id, extent$$1);
66132 function zoomToEntity(id, extent$$1) {
66133 context.surface().selectAll('.hover')
66134 .classed('hover', false);
66136 var entity = context.graph().hasEntity(id);
66139 context.map().trimmedExtent(extent$$1);
66141 context.map().zoomTo(entity);
66143 context.surface().selectAll(
66144 utilEntityOrMemberSelector([entity.id], context.graph()))
66145 .classed('hover', true);
66150 // The conflict list should be an array of objects like:
66153 // name: entityName(local),
66154 // details: merge.conflicts(),
66157 // choice(id, keepMine, forceLocal),
66158 // choice(id, keepTheirs, forceRemote)
66161 conflicts.list = function(_) {
66162 if (!arguments.length) return list;
66168 return utilRebind(conflicts, dispatch$$1, 'on');
66171 function uiFlash(selection) {
66172 var modalSelection = uiModal(selection);
66174 modalSelection.select('.modal')
66175 .classed('modal-flash', true);
66177 modalSelection.select('.content')
66178 .classed('modal-section', true)
66180 .attr('class', 'description');
66182 modalSelection.on('click.flash', function() {
66183 modalSelection.remove();
66186 setTimeout(function() {
66187 modalSelection.remove();
66192 return modalSelection;
66195 function uiLasso(context) {
66196 var group, polygon;
66198 lasso.coordinates = [];
66200 function lasso(selection$$1) {
66201 context.container()
66202 .classed('lasso', true);
66204 group = selection$$1
66206 .attr('class', 'lasso hide');
66210 .attr('class', 'lasso-path');
66213 .call(uiToggle(true));
66219 polygon.data([lasso.coordinates])
66220 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
66225 lasso.extent = function () {
66226 return lasso.coordinates.reduce(function(extent$$1, point) {
66227 return extent$$1.extend(geoExtent$$1(point));
66228 }, geoExtent$$1());
66232 lasso.p = function(_) {
66233 if (!arguments.length) return lasso;
66234 lasso.coordinates.push(_);
66240 lasso.close = function() {
66242 group.call(uiToggle(false, function() {
66243 select(this).remove();
66246 context.container().classed('lasso', false);
66253 function uiRadialMenu(context, operations) {
66259 var radialMenu = function(selection$$1) {
66260 if (!operations.length) return;
66262 selection$$1.node().parentNode.focus();
66264 function click(operation) {
66265 event.stopPropagation();
66266 if (operation.disabled()) return;
66268 radialMenu.close();
66271 menu = selection$$1
66273 .attr('class', 'radial-menu')
66274 .attr('transform', 'translate(' + center + ')')
66275 .attr('opacity', 0);
66279 .attr('opacity', 1);
66284 a1 = a0 + (operations.length - 1) * a;
66288 .attr('class', 'radial-menu-background')
66289 .attr('d', 'M' + r * Math.sin(a0) + ',' +
66291 ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
66292 (r * Math.sin(a1) + 1e-3) + ',' +
66293 (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
66294 .attr('stroke-width', 50)
66295 .attr('stroke-linecap', 'round');
66297 var button = menu.selectAll()
66301 .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
66302 .classed('disabled', function(d) { return d.disabled(); })
66303 .attr('transform', function(d, i) {
66304 return 'translate(' + geoRoundCoords([
66305 r * Math.sin(a0 + i * a),
66306 r * Math.cos(a0 + i * a)]).join(',') + ')';
66312 .on('click', click)
66313 .on('mousedown', mousedown)
66314 .on('mouseover', mouseover)
66315 .on('mouseout', mouseout);
66319 .attr('transform', 'translate(-10,-10)')
66320 .attr('width', '20')
66321 .attr('height', '20')
66322 .attr('xlink:href', function(d) { return '#operation-' + d.id; });
66324 tooltip = select(document.body)
66326 .attr('class', 'tooltip-inner radial-menu-tooltip');
66328 function mousedown() {
66329 event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
66332 function mouseover(d, i) {
66333 var rect = context.surfaceRect(),
66334 angle = a0 + i * a,
66335 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
66336 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
66337 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
66338 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
66341 .style('top', null)
66342 .style('left', null)
66343 .style('bottom', null)
66344 .style('right', null)
66345 .style('display', 'block')
66346 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
66350 .style('right', right)
66351 .style('top', top);
66352 } else if (i >= 4) {
66354 .style('left', left)
66355 .style('bottom', bottom);
66358 .style('left', left)
66359 .style('top', top);
66363 function mouseout() {
66364 tooltip.style('display', 'none');
66369 radialMenu.close = function() {
66372 .style('pointer-events', 'none')
66374 .attr('opacity', 0)
66384 radialMenu.center = function(_) {
66385 if (!arguments.length) return center;
66394 function uiSelectionList(context, selectedIDs) {
66396 function selectEntity(entity) {
66397 context.enter(modeSelect(context, [entity.id]).suppressMenu(true));
66401 function deselectEntity(entity) {
66402 event.stopPropagation();
66403 var index = selectedIDs.indexOf(entity.id);
66405 selectedIDs.splice(index, 1);
66407 context.enter(modeSelect(context, selectedIDs).suppressMenu(true));
66411 function selectionList(selection$$1) {
66412 selection$$1.classed('selection-list-pane', true);
66414 var header = selection$$1
66416 .attr('class', 'header fillL cf');
66420 .text(t('inspector.multiselect'));
66422 var listWrap = selection$$1
66424 .attr('class', 'inspector-body');
66426 var list = listWrap
66428 .attr('class', 'feature-list cf');
66430 context.history().on('change.selection-list', drawList);
66434 function drawList() {
66435 var entities = selectedIDs
66436 .map(function(id) { return context.hasEntity(id); })
66437 .filter(function(entity) { return entity; });
66439 var items = list.selectAll('.feature-list-item')
66440 .data(entities, osmEntity$$1.key);
66446 var enter = items.enter()
66448 .attr('class', 'feature-list-item')
66449 .on('click', selectEntity);
66453 .attr('class', 'label');
66457 .attr('class', 'close')
66458 .on('click', deselectEntity)
66459 .call(svgIcon('#icon-close'));
66463 .attr('class', 'entity-geom-icon')
66464 .call(svgIcon('', 'pre-text'));
66468 .attr('class', 'entity-type');
66472 .attr('class', 'entity-name');
66475 items = items.merge(enter);
66477 items.selectAll('.entity-geom-icon use')
66478 .attr('href', function() {
66479 var entity = this.parentNode.parentNode.__data__;
66480 return '#icon-' + context.geometry(entity.id);
66483 items.selectAll('.entity-type')
66484 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
66486 items.selectAll('.entity-name')
66487 .text(function(entity) { return utilDisplayName(entity); });
66491 return selectionList;
66494 function uiSourceSwitch(context) {
66499 event.preventDefault();
66501 if (context.history().hasChanges() &&
66502 !window.confirm(t('source_switch.lose_changes'))) return;
66504 var live = select(this)
66507 context.connection()
66508 .switch(live ? keys$$1[1] : keys$$1[0]);
66510 context.enter(modeBrowse(context));
66514 .text(live ? t('source_switch.dev') : t('source_switch.live'))
66515 .classed('live', !live);
66518 var sourceSwitch = function(selection$$1) {
66522 .text(t('source_switch.live'))
66523 .classed('live', true)
66524 .attr('tabindex', -1)
66525 .on('click', click);
66529 sourceSwitch.keys = function(_) {
66530 if (!arguments.length) return keys$$1;
66532 return sourceSwitch;
66536 return sourceSwitch;
66539 function uiSuccess(context) {
66540 var dispatch$$1 = dispatch('cancel'),
66544 function success(selection$$1) {
66545 var message = (changeset.comment || t('success.edited_osm')).substring(0, 130) +
66546 ' ' + context.connection().changesetURL(changeset.id);
66548 var header = selection$$1
66550 .attr('class', 'header fillL');
66554 .attr('class', 'fr')
66555 .on('click', function() { dispatch$$1.call('cancel'); })
66556 .call(svgIcon('#icon-close'));
66560 .text(t('success.just_edited'));
66562 var body = selection$$1
66564 .attr('class', 'body save-success fillL');
66568 .html(t('success.help_html'));
66572 .attr('class', 'details')
66573 .attr('target', '_blank')
66574 .attr('tabindex', -1)
66575 .call(svgIcon('#icon-out-link', 'inline'))
66576 .attr('href', t('success.help_link_url'))
66578 .text(t('success.help_link_text'));
66580 var changesetURL = context.connection().changesetURL(changeset.id);
66584 .attr('class', 'button col12 osm')
66585 .attr('target', '_blank')
66586 .attr('href', changesetURL)
66587 .text(t('success.view_on_osm'));
66590 facebook: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL),
66591 twitter: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message),
66592 google: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL)
66595 body.selectAll('.button.social')
66596 .data(entries(sharing))
66599 .attr('class', 'button social col4')
66600 .attr('target', '_blank')
66601 .attr('href', function(d) { return d.value; })
66603 .title(function(d) { return t('success.' + d.key); })
66604 .placement('bottom'))
66605 .each(function(d) { select(this).call(svgIcon('#logo-' + d.key, 'social')); });
66609 success.changeset = function(_) {
66610 if (!arguments.length) return changeset;
66616 return utilRebind(success, dispatch$$1, 'on');
66619 function coreHistory(context) {
66620 var imageryUsed = ['Bing'],
66621 dispatch$$1 = dispatch('change', 'undone', 'redone'),
66622 lock = utilSessionMutex('lock'),
66624 stack$$1, index, tree$$1;
66627 // internal _act, accepts list of actions and eased time
66628 function _act(actions, t) {
66629 actions = Array.prototype.slice.call(actions);
66633 if (!lodash.isFunction(lodash.last(actions))) {
66634 annotation = actions.pop();
66637 stack$$1[index].transform = context.projection.transform();
66638 stack$$1[index].selectedIDs = context.selectedIDs();
66640 var graph = stack$$1[index].graph;
66641 for (var i = 0; i < actions.length; i++) {
66642 graph = actions[i](graph, t);
66647 annotation: annotation,
66648 imageryUsed: imageryUsed
66653 // internal _perform with eased time
66654 function _perform(args, t) {
66655 var previous = stack$$1[index].graph;
66656 stack$$1 = stack$$1.slice(0, index + 1);
66657 stack$$1.push(_act(args, t));
66659 return change(previous);
66663 // internal _replace with eased time
66664 function _replace(args, t) {
66665 var previous = stack$$1[index].graph;
66666 // assert(index == stack.length - 1)
66667 stack$$1[index] = _act(args, t);
66668 return change(previous);
66672 // internal _overwrite with eased time
66673 function _overwrite(args, t) {
66674 var previous = stack$$1[index].graph;
66679 stack$$1 = stack$$1.slice(0, index + 1);
66680 stack$$1.push(_act(args, t));
66682 return change(previous);
66686 // determine diffrence and dispatch a change event
66687 function change(previous) {
66688 var difference = coreDifference(previous, history.graph());
66689 dispatch$$1.call('change', this, difference);
66694 // iD uses namespaced keys so multiple installations do not conflict
66695 function getKey(n) {
66696 return 'iD_' + window.location.origin + '_' + n;
66702 graph: function() {
66703 return stack$$1[index].graph;
66708 return stack$$1[0].graph;
66712 merge: function(entities, extent$$1) {
66713 stack$$1[0].graph.rebase(entities, lodash.map(stack$$1, 'graph'), false);
66714 tree$$1.rebase(entities, false);
66716 dispatch$$1.call('change', this, undefined, extent$$1);
66720 perform: function() {
66721 // complete any transition already in progress
66722 select(document).interrupt('history.perform');
66724 var transitionable = false,
66725 action0 = arguments[0];
66727 if (arguments.length === 1 ||
66728 arguments.length === 2 && !lodash.isFunction(arguments[1])) {
66729 transitionable = !!action0.transitionable;
66732 if (transitionable) {
66733 var origArguments = arguments;
66735 .transition('history.perform')
66736 .duration(duration)
66738 .tween('history.tween', function() {
66739 return function(t) {
66740 if (t < 1) _overwrite([action0], t);
66743 .on('start', function() {
66744 _perform([action0], 0);
66746 .on('end interrupt', function() {
66747 _overwrite(origArguments, 1);
66751 return _perform(arguments);
66756 replace: function() {
66757 select(document).interrupt('history.perform');
66758 return _replace(arguments, 1);
66762 // Same as calling pop and then perform
66763 overwrite: function() {
66764 select(document).interrupt('history.perform');
66765 return _overwrite(arguments, 1);
66770 select(document).interrupt('history.perform');
66772 var previous = stack$$1[index].graph;
66776 return change(previous);
66782 select(document).interrupt('history.perform');
66784 var previous = stack$$1[index].graph;
66786 // Pop to the next annotated state.
66787 while (index > 0) {
66789 if (stack$$1[index].annotation) break;
66792 dispatch$$1.call('undone', this, stack$$1[index]);
66793 return change(previous);
66798 select(document).interrupt('history.perform');
66800 var previous = stack$$1[index].graph;
66801 while (index < stack$$1.length - 1) {
66803 if (stack$$1[index].annotation) break;
66806 dispatch$$1.call('redone', this, stack$$1[index]);
66807 return change(previous);
66811 undoAnnotation: function() {
66814 if (stack$$1[i].annotation) return stack$$1[i].annotation;
66820 redoAnnotation: function() {
66822 while (i <= stack$$1.length - 1) {
66823 if (stack$$1[i].annotation) return stack$$1[i].annotation;
66829 intersects: function(extent$$1) {
66830 return tree$$1.intersects(extent$$1, stack$$1[index].graph);
66834 difference: function() {
66835 var base = stack$$1[0].graph,
66836 head = stack$$1[index].graph;
66837 return coreDifference(base, head);
66841 changes: function(action) {
66842 var base = stack$$1[0].graph,
66843 head = stack$$1[index].graph;
66846 head = action(head);
66849 var difference = coreDifference(base, head);
66852 modified: difference.modified(),
66853 created: difference.created(),
66854 deleted: difference.deleted()
66859 validate: function(changes) {
66860 return lodash(Validations)
66861 .map(function(fn) { return fn()(changes, stack$$1[index].graph); })
66867 hasChanges: function() {
66868 return this.difference().length() > 0;
66872 imageryUsed: function(sources) {
66874 imageryUsed = sources;
66877 return lodash(stack$$1.slice(1, index + 1))
66878 .map('imageryUsed')
66881 .without(undefined, 'Custom')
66887 reset: function() {
66888 stack$$1 = [{graph: coreGraph$$1()}];
66890 tree$$1 = coreTree(stack$$1[0].graph);
66891 dispatch$$1.call('change');
66896 toJSON: function() {
66897 if (!this.hasChanges()) return;
66899 var allEntities = {},
66901 base = stack$$1[0];
66903 var s = stack$$1.map(function(i) {
66904 var modified = [], deleted = [];
66906 lodash.forEach(i.graph.entities, function(entity, id) {
66908 var key = osmEntity$$1.key(entity);
66909 allEntities[key] = entity;
66910 modified.push(key);
66915 // make sure that the originals of changed or deleted entities get merged
66916 // into the base of the stack after restoring the data from JSON.
66917 if (id in base.graph.entities) {
66918 baseEntities[id] = base.graph.entities[id];
66920 // get originals of parent entities too
66921 lodash.forEach(base.graph._parentWays[id], function(parentId) {
66922 if (parentId in base.graph.entities) {
66923 baseEntities[parentId] = base.graph.entities[parentId];
66930 if (modified.length) x.modified = modified;
66931 if (deleted.length) x.deleted = deleted;
66932 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
66933 if (i.annotation) x.annotation = i.annotation;
66938 return JSON.stringify({
66940 entities: lodash.values(allEntities),
66941 baseEntities: lodash.values(baseEntities),
66943 nextIDs: osmEntity$$1.id.next,
66949 fromJSON: function(json$$1, loadChildNodes) {
66950 var h = JSON.parse(json$$1),
66951 loadComplete = true;
66953 osmEntity$$1.id.next = h.nextIDs;
66956 if (h.version === 2 || h.version === 3) {
66957 var allEntities = {};
66959 h.entities.forEach(function(entity) {
66960 allEntities[osmEntity$$1.key(entity)] = osmEntity$$1(entity);
66963 if (h.version === 3) {
66964 // This merges originals for changed entities into the base of
66965 // the stack even if the current stack doesn't have them (for
66966 // example when iD has been restarted in a different region)
66967 var baseEntities = h.baseEntities.map(function(d) { return osmEntity$$1(d); });
66968 stack$$1[0].graph.rebase(baseEntities, lodash.map(stack$$1, 'graph'), true);
66969 tree$$1.rebase(baseEntities, true);
66971 // When we restore a modified way, we also need to fetch any missing
66972 // childnodes that would normally have been downloaded with it.. #2142
66973 if (loadChildNodes) {
66974 var missing = lodash(baseEntities)
66975 .filter({ type: 'way' })
66979 .reject(function(n) { return stack$$1[0].graph.hasEntity(n); })
66982 if (!lodash.isEmpty(missing)) {
66983 loadComplete = false;
66984 context.redrawEnable(false);
66986 var loading = uiLoading(context).blocking(true);
66987 context.container().call(loading);
66989 var childNodesLoaded = function(err, result) {
66991 var visible = lodash.groupBy(result.data, 'visible');
66992 if (!lodash.isEmpty(visible.true)) {
66993 missing = lodash.difference(missing, lodash.map(visible.true, 'id'));
66994 stack$$1[0].graph.rebase(visible.true, lodash.map(stack$$1, 'graph'), true);
66995 tree$$1.rebase(visible.true, true);
66998 // fetch older versions of nodes that were deleted..
66999 lodash.each(visible.false, function(entity) {
67000 context.connection()
67001 .loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
67005 if (err || lodash.isEmpty(missing)) {
67007 context.redrawEnable(true);
67008 dispatch$$1.call('change');
67012 context.connection().loadMultiple(missing, childNodesLoaded);
67017 stack$$1 = h.stack.map(function(d) {
67018 var entities = {}, entity;
67021 d.modified.forEach(function(key) {
67022 entity = allEntities[key];
67023 entities[entity.id] = entity;
67028 d.deleted.forEach(function(id) {
67029 entities[id] = undefined;
67034 graph: coreGraph$$1(stack$$1[0].graph).load(entities),
67035 annotation: d.annotation,
67036 imageryUsed: d.imageryUsed
67040 } else { // original version
67041 stack$$1 = h.stack.map(function(d) {
67044 for (var i in d.entities) {
67045 var entity = d.entities[i];
67046 entities[i] = entity === 'undefined' ? undefined : osmEntity$$1(entity);
67049 d.graph = coreGraph$$1(stack$$1[0].graph).load(entities);
67054 if (loadComplete) {
67055 dispatch$$1.call('change');
67063 if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
67068 clearSaved: function() {
67069 context.debouncedSave.cancel();
67070 if (lock.locked()) context.storage(getKey('saved_history'), null);
67076 return lock.lock();
67080 unlock: function() {
67085 // is iD not open in another window and it detects that
67086 // there's a history stored in localStorage that's recoverable?
67087 restorableChanges: function() {
67088 return lock.locked() && !!context.storage(getKey('saved_history'));
67092 // load history from a version stored in localStorage
67093 restore: function() {
67094 if (!lock.locked()) return;
67096 var json$$1 = context.storage(getKey('saved_history'));
67097 if (json$$1) history.fromJSON(json$$1, true);
67108 return utilRebind(history, dispatch$$1, 'on');
67111 function presetCollection(collection) {
67112 var maxSearchResults = 50,
67113 maxSuggestionResults = 10;
67117 collection: collection,
67120 item: function(id) {
67121 return lodash.find(collection, function(d) {
67122 return d.id === id;
67127 matchGeometry: function(geometry) {
67128 return presetCollection(collection.filter(function(d) {
67129 return d.matchGeometry(geometry);
67134 search: function(value, geometry) {
67135 if (!value) return this;
67137 function leading(a) {
67138 var index = a.indexOf(value);
67139 return index === 0 || a[index - 1] === ' ';
67142 function suggestionName(name) {
67143 var nameArray = name.split(' - ');
67144 if (nameArray.length > 1) {
67145 name = nameArray.slice(0, nameArray.length - 1).join(' - ');
67147 return name.toLowerCase();
67151 value = value.toLowerCase();
67153 var searchable = lodash.filter(collection, function(a) {
67154 return a.searchable !== false && a.suggestion !== true;
67156 suggestions = lodash.filter(collection, function(a) {
67157 return a.suggestion === true;
67161 // matches value to preset.name
67162 var leading_name = lodash.filter(searchable, function(a) {
67163 return leading(a.name().toLowerCase());
67164 }).sort(function(a, b) {
67165 var i = a.name().toLowerCase().indexOf(value) - b.name().toLowerCase().indexOf(value);
67166 if (i === 0) return a.name().length - b.name().length;
67170 // matches value to preset.terms values
67171 var leading_terms = lodash.filter(searchable, function(a) {
67172 return lodash.some(a.terms() || [], leading);
67175 // matches value to preset.tags values
67176 var leading_tag_values = lodash.filter(searchable, function(a) {
67177 return lodash.some(lodash.without(lodash.values(a.tags || {}), '*'), leading);
67181 // finds close matches to value in preset.name
67182 var similar_name = searchable.map(function(a) {
67185 dist: utilEditDistance(value, a.name())
67187 }).filter(function(a) {
67188 return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
67189 }).sort(function(a, b) {
67190 return a.dist - b.dist;
67191 }).map(function(a) {
67195 // finds close matches to value in preset.terms
67196 var similar_terms = lodash.filter(searchable, function(a) {
67197 return lodash.some(a.terms() || [], function(b) {
67198 return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
67202 var leading_suggestions = lodash.filter(suggestions, function(a) {
67203 return leading(suggestionName(a.name()));
67204 }).sort(function(a, b) {
67205 a = suggestionName(a.name());
67206 b = suggestionName(b.name());
67207 var i = a.indexOf(value) - b.indexOf(value);
67208 if (i === 0) return a.length - b.length;
67212 var similar_suggestions = suggestions.map(function(a) {
67215 dist: utilEditDistance(value, suggestionName(a.name()))
67217 }).filter(function(a) {
67218 return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
67219 }).sort(function(a, b) {
67220 return a.dist - b.dist;
67221 }).map(function(a) {
67225 var other = presets.item(geometry);
67227 var results = leading_name.concat(
67229 leading_tag_values,
67230 leading_suggestions.slice(0, maxSuggestionResults + 5),
67233 similar_suggestions.slice(0, maxSuggestionResults)
67234 ).slice(0, maxSearchResults - 1);
67236 return presetCollection(lodash.uniq(results.concat(other)));
67244 function presetCategory(id, category, all) {
67245 category = lodash.clone(category);
67250 category.members = presetCollection(category.members.map(function(id) {
67251 return all.item(id);
67255 category.matchGeometry = function(geometry) {
67256 return category.geometry.indexOf(geometry) >= 0;
67260 category.matchScore = function() {
67265 category.name = function() {
67266 return t('presets.categories.' + id + '.name', {'default': id});
67270 category.terms = function() {
67278 function presetField(id, field) {
67279 field = lodash.clone(field);
67284 field.matchGeometry = function(geometry) {
67285 return !field.geometry || field.geometry === geometry;
67289 field.t = function(scope, options) {
67290 return t('presets.fields.' + id + '.' + scope, options);
67294 field.label = function() {
67295 return field.t('label', {'default': id});
67299 var placeholder = field.placeholder;
67300 field.placeholder = function() {
67301 return field.t('placeholder', {'default': placeholder});
67308 function presetPreset(id, preset, fields) {
67309 preset = lodash.clone(preset);
67312 preset.fields = (preset.fields || []).map(getFields);
67313 preset.geometry = (preset.geometry || []);
67316 function getFields(f) {
67321 preset.matchGeometry = function(geometry) {
67322 return preset.geometry.indexOf(geometry) >= 0;
67326 var matchScore = preset.matchScore || 1;
67327 preset.matchScore = function(entity) {
67328 var tags = preset.tags,
67331 for (var t$$1 in tags) {
67332 if (entity.tags[t$$1] === tags[t$$1]) {
67333 score += matchScore;
67334 } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
67335 score += matchScore / 2;
67345 preset.t = function(scope, options) {
67346 return t('presets.presets.' + id + '.' + scope, options);
67350 var name = preset.name || '';
67351 preset.name = function() {
67352 if (preset.suggestion) {
67353 id = id.split('/');
67354 id = id[0] + '/' + id[1];
67355 return name + ' - ' + t('presets.presets.' + id + '.name');
67357 return preset.t('name', {'default': name});
67361 preset.terms = function() {
67362 return preset.t('terms', {'default': ''}).toLowerCase().trim().split(/\s*,+\s*/);
67366 preset.isFallback = function() {
67367 var tagCount = Object.keys(preset.tags).length;
67368 return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
67372 preset.reference = function(geometry) {
67373 var key = Object.keys(preset.tags)[0],
67374 value = preset.tags[key];
67376 if (geometry === 'relation' && key === 'type') {
67377 if (value in preset.tags) {
67379 value = preset.tags[key];
67381 return { rtype: value };
67385 if (value === '*') {
67386 return { key: key };
67388 return { key: key, value: value };
67393 var removeTags = preset.removeTags || preset.tags;
67394 preset.removeTags = function(tags, geometry) {
67395 tags = lodash.omit(tags, lodash.keys(removeTags));
67397 for (var f in preset.fields) {
67398 var field = preset.fields[f];
67399 if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
67400 delete tags[field.key];
67409 var applyTags = preset.addTags || preset.tags;
67410 preset.applyTags = function(tags, geometry) {
67413 tags = lodash.clone(tags);
67415 for (k in applyTags) {
67416 if (applyTags[k] === '*') {
67419 tags[k] = applyTags[k];
67423 // Add area=yes if necessary.
67424 // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
67425 // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
67426 // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
67427 if (geometry === 'area') {
67428 var needsAreaTag = true;
67429 if (preset.geometry.indexOf('line') === -1) {
67430 for (k in applyTags) {
67431 if (k in areaKeys) {
67432 needsAreaTag = false;
67437 if (needsAreaTag) {
67442 for (var f in preset.fields) {
67443 var field = preset.fields[f];
67444 if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
67445 tags[field.key] = field.default;
67456 function presetIndex() {
67457 // a presetCollection with methods for
67458 // loading new data and returning defaults
67460 var all = presetCollection([]),
67461 defaults = { area: all, line: all, point: all, vertex: all, relation: all },
67464 recent = presetCollection([]);
67466 // Index of presets by (geometry, tag key).
67475 all.match = function(entity, resolver) {
67476 var geometry = entity.geometry(resolver);
67478 // Treat entities on addr:interpolation lines as points, not vertices (#3241)
67479 if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
67480 geometry = 'point';
67483 var geometryMatches = index[geometry],
67487 for (var k in entity.tags) {
67488 var keyMatches = geometryMatches[k];
67489 if (!keyMatches) continue;
67491 for (var i = 0; i < keyMatches.length; i++) {
67492 var score = keyMatches[i].matchScore(entity);
67493 if (score > best) {
67495 match = keyMatches[i];
67500 return match || all.item(geometry);
67504 // Because of the open nature of tagging, iD will never have a complete
67505 // list of tags used in OSM, so we want it to have logic like "assume
67506 // that a closed way with an amenity tag is an area, unless the amenity
67507 // is one of these specific types". This function computes a structure
67508 // that allows testing of such conditions, based on the presets designated
67509 // as as supporting (or not supporting) the area geometry.
67511 // The returned object L is a whitelist/blacklist of tags. A closed way
67512 // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
67513 // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
67514 // and the subkeys form the blacklist.
67515 all.areaKeys = function() {
67517 ignore = ['barrier', 'highway', 'footway', 'railway', 'type'],
67518 presets = lodash.reject(all.collection, 'suggestion');
67521 presets.forEach(function(d) {
67522 for (var key in d.tags) break;
67524 if (ignore.indexOf(key) !== -1) return;
67526 if (d.geometry.indexOf('area') !== -1) {
67527 areaKeys[key] = areaKeys[key] || {};
67532 presets.forEach(function(d) {
67533 for (var key in d.tags) break;
67535 if (ignore.indexOf(key) !== -1) return;
67537 var value = d.tags[key];
67538 if (d.geometry.indexOf('area') === -1 &&
67539 d.geometry.indexOf('line') !== -1 &&
67540 key in areaKeys && value !== '*') {
67541 areaKeys[key][value] = true;
67549 all.init = function() {
67550 var d = data.presets;
67553 lodash.forEach(d.fields, function(d, id) {
67554 fields[id] = presetField(id, d);
67555 if (d.universal) universal.push(fields[id]);
67560 lodash.forEach(d.presets, function(d, id) {
67561 all.collection.push(presetPreset(id, d, fields));
67565 if (d.categories) {
67566 lodash.forEach(d.categories, function(d, id) {
67567 all.collection.push(presetCategory(id, d, all));
67572 var getItem = lodash.bind(all.item, all);
67574 area: presetCollection(d.defaults.area.map(getItem)),
67575 line: presetCollection(d.defaults.line.map(getItem)),
67576 point: presetCollection(d.defaults.point.map(getItem)),
67577 vertex: presetCollection(d.defaults.vertex.map(getItem)),
67578 relation: presetCollection(d.defaults.relation.map(getItem))
67582 for (var i = 0; i < all.collection.length; i++) {
67583 var preset = all.collection[i],
67584 geometry = preset.geometry;
67586 for (var j = 0; j < geometry.length; j++) {
67587 var g = index[geometry[j]];
67588 for (var k in preset.tags) {
67589 (g[k] = g[k] || []).push(preset);
67597 all.field = function(id) {
67601 all.universal = function() {
67605 all.defaults = function(geometry, n) {
67606 var rec = recent.matchGeometry(geometry).collection.slice(0, 4),
67607 def = lodash.uniq(rec.concat(defaults[geometry].collection)).slice(0, n - 1);
67608 return presetCollection(lodash.uniq(rec.concat(def).concat(all.item(geometry))));
67611 all.choose = function(preset) {
67612 if (!preset.isFallback()) {
67613 recent = presetCollection(lodash.uniq([preset].concat(recent.collection)));
67623 function setAreaKeys(value) {
67628 function coreContext() {
67630 // create a special translation that contains the keys in place of the strings
67631 var tkeys = lodash.cloneDeep(en);
67634 function traverser(v, k, obj) {
67636 if (lodash.isObject(v)) {
67637 lodash.forOwn(v, traverser);
67638 } else if (lodash.isString(v)) {
67639 obj[k] = parents.join('.');
67644 lodash.forOwn(tkeys, traverser);
67645 addTranslation('_tkeys_', tkeys);
67647 addTranslation('en', en);
67650 var dispatch$$1 = dispatch('enter', 'exit', 'change'),
67653 // https://github.com/openstreetmap/iD/issues/772
67654 // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
67656 try { storage = localStorage; } catch (e) {} // eslint-disable-line no-empty
67657 storage = storage || (function() {
67660 getItem: function(k) { return s[k]; },
67661 setItem: function(k, v) { s[k] = v; },
67662 removeItem: function(k) { delete s[k]; }
67666 context.storage = function(k, v) {
67668 if (arguments.length === 1) return storage.getItem(k);
67669 else if (v === null) storage.removeItem(k);
67670 else storage.setItem(k, v);
67672 // localstorage quota exceeded
67673 /* eslint-disable no-console */
67674 if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
67675 /* eslint-enable no-console */
67680 /* Straight accessors. Avoid using these if you can. */
67681 var ui, connection, history;
67682 context.ui = function() { return ui; };
67683 context.connection = function() { return connection; };
67684 context.history = function() { return history; };
67688 function entitiesLoaded(err, result) {
67689 if (!err) history.merge(result.data, result.extent);
67692 context.preauth = function(options) {
67693 connection.switch(options);
67697 context.loadTiles = function(projection, dimensions, callback) {
67698 function done(err, result) {
67699 entitiesLoaded(err, result);
67700 if (callback) callback(err, result);
67702 connection.loadTiles(projection, dimensions, done);
67705 context.loadEntity = function(id, callback) {
67706 function done(err, result) {
67707 entitiesLoaded(err, result);
67708 if (callback) callback(err, result);
67710 connection.loadEntity(id, done);
67713 context.zoomToEntity = function(id, zoomTo) {
67714 if (zoomTo !== false) {
67715 this.loadEntity(id, function(err, result) {
67717 var entity = lodash.find(result.data, function(e) { return e.id === id; });
67718 if (entity) { map$$1.zoomTo(entity); }
67722 map$$1.on('drawn.zoomToEntity', function() {
67723 if (!context.hasEntity(id)) return;
67724 map$$1.on('drawn.zoomToEntity', null);
67725 context.on('enter.zoomToEntity', null);
67726 context.enter(modeSelect(context, [id]));
67729 context.on('enter.zoomToEntity', function() {
67730 if (mode.id !== 'browse') {
67731 map$$1.on('drawn.zoomToEntity', null);
67732 context.on('enter.zoomToEntity', null);
67737 var minEditableZoom = 16;
67738 context.minEditableZoom = function(_) {
67739 if (!arguments.length) return minEditableZoom;
67740 minEditableZoom = _;
67741 connection.tileZoom(_);
67747 var inIntro = false;
67748 context.inIntro = function(_) {
67749 if (!arguments.length) return inIntro;
67754 context.save = function() {
67755 // no history save, no message onbeforeunload
67756 if (inIntro || select('.modal').size()) return;
67759 if (mode && mode.id === 'save') {
67762 canSave = context.selectedIDs().every(function(id) {
67763 var entity = context.hasEntity(id);
67764 return entity && !entity.isDegenerate();
67771 if (history.hasChanges()) {
67772 return t('save.unsaved_changes');
67778 context.hasEntity = function(id) {
67779 return history.graph().hasEntity(id);
67781 context.entity = function(id) {
67782 return history.graph().entity(id);
67784 context.childNodes = function(way) {
67785 return history.graph().childNodes(way);
67787 context.geometry = function(id) {
67788 return context.entity(id).geometry(history.graph());
67794 context.mode = function() {
67797 context.enter = function(newMode) {
67800 dispatch$$1.call('exit', this, mode);
67805 dispatch$$1.call('enter', this, mode);
67808 context.selectedIDs = function() {
67809 if (mode && mode.selectedIDs) {
67810 return mode.selectedIDs();
67818 context.install = function(behavior) {
67819 context.surface().call(behavior);
67821 context.uninstall = function(behavior) {
67822 context.surface().call(behavior.off);
67827 var copyIDs = [], copyGraph;
67828 context.copyGraph = function() { return copyGraph; };
67829 context.copyIDs = function(_) {
67830 if (!arguments.length) return copyIDs;
67832 copyGraph = history.graph();
67839 context.background = function() { return background; };
67844 context.features = function() { return features; };
67845 context.hasHiddenConnections = function(id) {
67846 var graph = history.graph(),
67847 entity = graph.entity(id);
67848 return features.hasHiddenConnections(entity, graph);
67854 context.presets = function() { return presets; };
67859 context.map = function() { return map$$1; };
67860 context.layers = function() { return map$$1.layers; };
67861 context.surface = function() { return map$$1.surface; };
67862 context.editable = function() { return map$$1.editable(); };
67864 context.surfaceRect = function() {
67865 // Work around a bug in Firefox.
67866 // http://stackoverflow.com/questions/18153989/
67867 // https://bugzilla.mozilla.org/show_bug.cgi?id=530985
67868 return context.surface().node().parentNode.getBoundingClientRect();
67880 context.debugFlags = function() {
67883 context.setDebug = function(flag, val) {
67884 if (arguments.length === 1) val = true;
67885 debugFlags[flag] = val;
67886 dispatch$$1.call('change');
67889 context.getDebug = function(flag) {
67890 return flag && debugFlags[flag];
67895 var container, embed;
67896 context.container = function(_) {
67897 if (!arguments.length) return container;
67899 container.classed('id-container', true);
67902 context.embed = function(_) {
67903 if (!arguments.length) return embed;
67910 var assetPath = '';
67911 context.assetPath = function(_) {
67912 if (!arguments.length) return assetPath;
67918 context.assetMap = function(_) {
67919 if (!arguments.length) return assetMap;
67924 context.asset = function(_) {
67925 var filename = assetPath + _;
67926 return assetMap[filename] || filename;
67929 context.imagePath = function(_) {
67930 return context.asset('img/' + _);
67935 // `locale` variable contains a "requested locale".
67936 // It won't become the `currentLocale` until after loadLocale() is called.
67937 var locale, localePath;
67939 context.locale = function(loc, path$$1) {
67940 if (!arguments.length) return currentLocale;
67942 localePath = path$$1;
67946 context.loadLocale = function(callback) {
67947 if (locale && locale !== 'en' && dataLocales.hasOwnProperty(locale)) {
67948 localePath = localePath || context.asset('locales/' + locale + '.json');
67949 json(localePath, function(err, result) {
67951 addTranslation(locale, result[locale]);
67971 /* reset (aka flush) */
67972 context.reset = context.flush = function() {
67973 context.debouncedSave.cancel();
67974 lodash.each(services, function(service) {
67975 if (service && typeof service.reset === 'function') {
67976 service.reset(context);
67986 context.version = '2.1.3';
67988 context.projection = geoRawMercator();
67990 locale = utilDetect().locale;
67991 if (locale && !dataLocales.hasOwnProperty(locale)) {
67992 locale = locale.split('-')[0];
67995 history = coreHistory(context);
67996 context.graph = history.graph;
67997 context.changes = history.changes;
67998 context.intersects = history.intersects;
68000 // Debounce save, since it's a synchronous localStorage write,
68001 // and history changes can happen frequently (e.g. when dragging).
68002 context.debouncedSave = lodash.debounce(context.save, 350);
68003 function withDebouncedSave(fn) {
68004 return function() {
68005 var result = fn.apply(history, arguments);
68006 context.debouncedSave();
68011 context.perform = withDebouncedSave(history.perform);
68012 context.replace = withDebouncedSave(history.replace);
68013 context.pop = withDebouncedSave(history.pop);
68014 context.overwrite = withDebouncedSave(history.overwrite);
68015 context.undo = withDebouncedSave(history.undo);
68016 context.redo = withDebouncedSave(history.redo);
68018 ui = uiInit(context);
68020 connection = services.osm;
68021 background = rendererBackground(context);
68022 features = rendererFeatures(context);
68023 presets = presetIndex();
68025 map$$1 = rendererMap(context);
68026 context.mouse = map$$1.mouse;
68027 context.extent = map$$1.extent;
68028 context.pan = map$$1.pan;
68029 context.zoomIn = map$$1.zoomIn;
68030 context.zoomOut = map$$1.zoomOut;
68031 context.zoomInFurther = map$$1.zoomInFurther;
68032 context.zoomOutFurther = map$$1.zoomOutFurther;
68033 context.redrawEnable = map$$1.redrawEnable;
68035 lodash.each(services, function(service) {
68036 if (service && typeof service.init === 'function') {
68037 service.init(context);
68043 areaKeys = presets.areaKeys();
68046 return utilRebind(context, dispatch$$1, 'on');
68049 function osmWay() {
68050 if (!(this instanceof osmWay)) {
68051 return (new osmWay()).initialize(arguments);
68052 } else if (arguments.length) {
68053 this.initialize(arguments);
68058 osmEntity$$1.way = osmWay;
68060 osmWay.prototype = Object.create(osmEntity$$1.prototype);
68063 lodash.extend(osmWay.prototype, {
68068 copy: function(resolver, copies) {
68069 if (copies[this.id])
68070 return copies[this.id];
68072 var copy = osmEntity$$1.prototype.copy.call(this, resolver, copies);
68074 var nodes = this.nodes.map(function(id) {
68075 return resolver.entity(id).copy(resolver, copies).id;
68078 copy = copy.update({ nodes: nodes });
68079 copies[this.id] = copy;
68085 extent: function(resolver) {
68086 return resolver.transient(this, 'extent', function() {
68087 var extent$$1 = geoExtent$$1();
68088 for (var i = 0; i < this.nodes.length; i++) {
68089 var node = resolver.hasEntity(this.nodes[i]);
68091 extent$$1._extend(node.extent());
68099 first: function() {
68100 return this.nodes[0];
68105 return this.nodes[this.nodes.length - 1];
68109 contains: function(node) {
68110 return this.nodes.indexOf(node) >= 0;
68114 affix: function(node) {
68115 if (this.nodes[0] === node) return 'prefix';
68116 if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
68120 layer: function() {
68121 // explicit layer tag, clamp between -10, 10..
68122 if (isFinite(this.tags.layer)) {
68123 return Math.max(-10, Math.min(+(this.tags.layer), 10));
68126 // implied layer tag..
68127 if (this.tags.location === 'overground') return 1;
68128 if (this.tags.location === 'underground') return -1;
68129 if (this.tags.location === 'underwater') return -10;
68131 if (this.tags.power === 'line') return 10;
68132 if (this.tags.power === 'minor_line') return 10;
68133 if (this.tags.aerialway) return 10;
68134 if (this.tags.bridge) return 1;
68135 if (this.tags.cutting) return -1;
68136 if (this.tags.tunnel) return -1;
68137 if (this.tags.waterway) return -1;
68138 if (this.tags.man_made === 'pipeline') return -10;
68139 if (this.tags.boundary) return -10;
68144 isOneWay: function() {
68145 // explicit oneway tag..
68146 if (['yes', '1', '-1'].indexOf(this.tags.oneway) !== -1) { return true; }
68147 if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; }
68149 // implied oneway tag..
68150 for (var key in this.tags) {
68151 if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
68158 lanes: function() {
68159 return osmLanes(this);
68163 isClosed: function() {
68164 return this.nodes.length > 1 && this.first() === this.last();
68168 isConvex: function(resolver) {
68169 if (!this.isClosed() || this.isDegenerate()) return null;
68171 var nodes = lodash.uniq(resolver.childNodes(this)),
68172 coords = lodash.map(nodes, 'loc'),
68173 curr = 0, prev = 0;
68175 for (var i = 0; i < coords.length; i++) {
68176 var o = coords[(i+1) % coords.length],
68178 b = coords[(i+2) % coords.length],
68179 res = geoCross(o, a, b);
68181 curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
68184 } else if (prev && curr !== prev) {
68193 isArea: function() {
68194 if (this.tags.area === 'yes')
68196 if (!this.isClosed() || this.tags.area === 'no')
68198 for (var key in this.tags) {
68199 if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
68207 isDegenerate: function() {
68208 return lodash.uniq(this.nodes).length < (this.isArea() ? 3 : 2);
68212 areAdjacent: function(n1, n2) {
68213 for (var i = 0; i < this.nodes.length; i++) {
68214 if (this.nodes[i] === n1) {
68215 if (this.nodes[i - 1] === n2) return true;
68216 if (this.nodes[i + 1] === n2) return true;
68223 geometry: function(graph) {
68224 return graph.transient(this, 'geometry', function() {
68225 return this.isArea() ? 'area' : 'line';
68230 // If this way is not closed, append the beginning node to the end of the nodelist to close it.
68231 close: function() {
68232 if (this.isClosed() || !this.nodes.length) return this;
68234 var nodes = this.nodes.slice();
68235 nodes = nodes.filter(noRepeatNodes);
68236 nodes.push(nodes[0]);
68237 return this.update({ nodes: nodes });
68241 // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
68242 unclose: function() {
68243 if (!this.isClosed()) return this;
68245 var nodes = this.nodes.slice(),
68246 connector = this.first(),
68247 i = nodes.length - 1;
68249 // remove trailing connectors..
68250 while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68251 nodes.splice(i, 1);
68252 i = nodes.length - 1;
68255 nodes = nodes.filter(noRepeatNodes);
68256 return this.update({ nodes: nodes });
68260 // Adds a node (id) in front of the node which is currently at position index.
68261 // If index is undefined, the node will be added to the end of the way for linear ways,
68262 // or just before the final connecting node for circular ways.
68263 // Consecutive duplicates are eliminated including existing ones.
68264 // Circularity is always preserved when adding a node.
68265 addNode: function(id, index) {
68266 var nodes = this.nodes.slice(),
68267 isClosed = this.isClosed(),
68268 max$$1 = isClosed ? nodes.length - 1 : nodes.length;
68270 if (index === undefined) {
68274 if (index < 0 || index > max$$1) {
68275 throw new RangeError('index ' + index + ' out of range 0..' + max$$1);
68278 // If this is a closed way, remove all connector nodes except the first one
68279 // (there may be duplicates) and adjust index if necessary..
68281 var connector = this.first();
68283 // leading connectors..
68285 while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
68286 nodes.splice(i, 1);
68287 if (index > i) index--;
68290 // trailing connectors..
68291 i = nodes.length - 1;
68292 while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68293 nodes.splice(i, 1);
68294 if (index > i) index--;
68295 i = nodes.length - 1;
68299 nodes.splice(index, 0, id);
68300 nodes = nodes.filter(noRepeatNodes);
68302 // If the way was closed before, append a connector node to keep it closed..
68303 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68304 nodes.push(nodes[0]);
68307 return this.update({ nodes: nodes });
68311 // Replaces the node which is currently at position index with the given node (id).
68312 // Consecutive duplicates are eliminated including existing ones.
68313 // Circularity is preserved when updating a node.
68314 updateNode: function(id, index) {
68315 var nodes = this.nodes.slice(),
68316 isClosed = this.isClosed(),
68317 max$$1 = nodes.length - 1;
68319 if (index === undefined || index < 0 || index > max$$1) {
68320 throw new RangeError('index ' + index + ' out of range 0..' + max$$1);
68323 // If this is a closed way, remove all connector nodes except the first one
68324 // (there may be duplicates) and adjust index if necessary..
68326 var connector = this.first();
68328 // leading connectors..
68330 while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
68331 nodes.splice(i, 1);
68332 if (index > i) index--;
68335 // trailing connectors..
68336 i = nodes.length - 1;
68337 while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68338 nodes.splice(i, 1);
68339 if (index === i) index = 0; // update leading connector instead
68340 i = nodes.length - 1;
68344 nodes.splice(index, 1, id);
68345 nodes = nodes.filter(noRepeatNodes);
68347 // If the way was closed before, append a connector node to keep it closed..
68348 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68349 nodes.push(nodes[0]);
68352 return this.update({nodes: nodes});
68356 // Replaces each occurrence of node id needle with replacement.
68357 // Consecutive duplicates are eliminated including existing ones.
68358 // Circularity is preserved.
68359 replaceNode: function(needle, replacement) {
68360 var nodes = this.nodes.slice(),
68361 isClosed = this.isClosed();
68363 for (var i = 0; i < nodes.length; i++) {
68364 if (nodes[i] === needle) {
68365 nodes[i] = replacement;
68369 nodes = nodes.filter(noRepeatNodes);
68371 // If the way was closed before, append a connector node to keep it closed..
68372 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68373 nodes.push(nodes[0]);
68376 return this.update({nodes: nodes});
68380 // Removes each occurrence of node id needle with replacement.
68381 // Consecutive duplicates are eliminated including existing ones.
68382 // Circularity is preserved.
68383 removeNode: function(id) {
68384 var nodes = this.nodes.slice(),
68385 isClosed = this.isClosed();
68388 .filter(function(node) { return node !== id; })
68389 .filter(noRepeatNodes);
68391 // If the way was closed before, append a connector node to keep it closed..
68392 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68393 nodes.push(nodes[0]);
68396 return this.update({nodes: nodes});
68400 asJXON: function(changeset_id) {
68403 '@id': this.osmId(),
68404 '@version': this.version || 0,
68405 nd: lodash.map(this.nodes, function(id) {
68406 return { keyAttributes: { ref: osmEntity$$1.id.toOSM(id) } };
68408 tag: lodash.map(this.tags, function(v, k) {
68409 return { keyAttributes: { k: k, v: v } };
68413 if (changeset_id) {
68414 r.way['@changeset'] = changeset_id;
68420 asGeoJSON: function(resolver) {
68421 return resolver.transient(this, 'GeoJSON', function() {
68422 var coordinates = lodash.map(resolver.childNodes(this), 'loc');
68423 if (this.isArea() && this.isClosed()) {
68426 coordinates: [coordinates]
68430 type: 'LineString',
68431 coordinates: coordinates
68438 area: function(resolver) {
68439 return resolver.transient(this, 'area', function() {
68440 var nodes = resolver.childNodes(this);
68444 coordinates: [lodash.map(nodes, 'loc')]
68447 if (!this.isClosed() && nodes.length) {
68448 json$$1.coordinates[0].push(nodes[0].loc);
68451 var area$$1 = area(json$$1);
68453 // Heuristic for detecting counterclockwise winding order. Assumes
68454 // that OpenStreetMap polygons are not hemisphere-spanning.
68455 if (area$$1 > 2 * Math.PI) {
68456 json$$1.coordinates[0] = json$$1.coordinates[0].reverse();
68457 area$$1 = area(json$$1);
68460 return isNaN(area$$1) ? 0 : area$$1;
68466 // Filter function to eliminate consecutive duplicates.
68467 function noRepeatNodes(node, i, arr) {
68468 return i === 0 || node !== arr[i - 1];
68471 function osmTurn(turn) {
68472 if (!(this instanceof osmTurn))
68473 return new osmTurn(turn);
68474 lodash.extend(this, turn);
68478 function osmIntersection(graph, vertexId) {
68479 var vertex = graph.entity(vertexId),
68480 parentWays = graph.parentWays(vertex),
68484 function addHighway(way, adjacentNodeId) {
68485 if (highways[adjacentNodeId]) {
68486 coincident.push(adjacentNodeId);
68488 highways[adjacentNodeId] = way;
68492 // Pre-split ways that would need to be split in
68493 // order to add a restriction. The real split will
68494 // happen when the restriction is added.
68495 parentWays.forEach(function(way) {
68496 if (!way.tags.highway || way.isArea() || way.isDegenerate())
68499 var isFirst = (vertexId === way.first()),
68500 isLast = (vertexId === way.last()),
68501 isAffix = (isFirst || isLast),
68502 isClosingNode = (isFirst && isLast);
68504 if (isAffix && !isClosingNode) {
68505 var index = (isFirst ? 1 : way.nodes.length - 2);
68506 addHighway(way, way.nodes[index]);
68509 var splitIndex, wayA, wayB, indexA, indexB;
68510 if (isClosingNode) {
68511 splitIndex = Math.ceil(way.nodes.length / 2); // split at midpoint
68512 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
68513 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
68515 indexB = way.nodes.length - 2;
68517 splitIndex = lodash.indexOf(way.nodes, vertex.id, 1); // split at vertexid
68518 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
68519 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
68520 indexA = splitIndex - 1;
68521 indexB = splitIndex + 1;
68523 graph = graph.replace(wayA).replace(wayB);
68524 addHighway(wayA, way.nodes[indexA]);
68525 addHighway(wayB, way.nodes[indexB]);
68529 // remove any ways from this intersection that are coincident
68530 // (i.e. any adjacent node used by more than one intersecting way)
68531 coincident.forEach(function (n) {
68532 delete highways[n];
68536 var intersection = {
68537 highways: highways,
68538 ways: lodash.values(highways),
68543 intersection.adjacentNodeId = function(fromWayId) {
68544 return lodash.find(lodash.keys(highways), function(k) {
68545 return highways[k].id === fromWayId;
68550 intersection.turns = function(fromNodeId) {
68551 var start = highways[fromNodeId];
68555 if (start.first() === vertex.id && start.tags.oneway === 'yes')
68557 if (start.last() === vertex.id && start.tags.oneway === '-1')
68560 function withRestriction(turn) {
68561 graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
68562 if (relation.tags.type !== 'restriction')
68565 var f = relation.memberByRole('from'),
68566 t = relation.memberByRole('to'),
68567 v = relation.memberByRole('via');
68569 if (f && f.id === turn.from.way &&
68570 v && v.id === turn.via.node &&
68571 t && t.id === turn.to.way) {
68572 turn.restriction = relation.id;
68573 } else if (/^only_/.test(relation.tags.restriction) &&
68574 f && f.id === turn.from.way &&
68575 v && v.id === turn.via.node &&
68576 t && t.id !== turn.to.way) {
68577 turn.restriction = relation.id;
68578 turn.indirect_restriction = true;
68582 return osmTurn(turn);
68588 way: start.id.split(/-(a|b)/)[0]
68590 via = { node: vertex.id },
68593 lodash.each(highways, function(end, adjacentNodeId) {
68598 if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
68599 turns.push(withRestriction({
68603 node: adjacentNodeId,
68604 way: end.id.split(/-(a|b)/)[0]
68610 if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
68611 turns.push(withRestriction({
68615 node: adjacentNodeId,
68616 way: end.id.split(/-(a|b)/)[0]
68624 if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
68625 turns.push(withRestriction({
68636 return intersection;
68640 function osmInferRestriction(graph, from, via, to, projection) {
68641 var fromWay = graph.entity(from.way),
68642 fromNode = graph.entity(from.node),
68643 toWay = graph.entity(to.way),
68644 toNode = graph.entity(to.node),
68645 viaNode = graph.entity(via.node),
68646 fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
68647 (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
68648 toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
68649 (toWay.tags.oneway === '-1' && toWay.last() === via.node),
68650 angle = geoAngle(viaNode, fromNode, projection) -
68651 geoAngle(viaNode, toNode, projection);
68653 angle = angle * 180 / Math.PI;
68658 if (fromNode === toNode)
68659 return 'no_u_turn';
68660 if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
68661 return 'no_u_turn';
68663 return 'no_right_turn';
68665 return 'no_left_turn';
68667 return 'no_straight_on';
68670 function actionAddMember(relationId, member, memberIndex) {
68671 return function(graph) {
68672 var relation = graph.entity(relationId);
68674 if (isNaN(memberIndex) && member.type === 'way') {
68675 var members = relation.indexedMembers();
68676 members.push(member);
68678 var joined = osmJoinWays(members, graph);
68679 for (var i = 0; i < joined.length; i++) {
68680 var segment = joined[i];
68681 for (var j = 0; j < segment.length && segment.length >= 2; j++) {
68682 if (segment[j] !== member)
68686 memberIndex = segment[j + 1].index;
68687 } else if (j === segment.length - 1) {
68688 memberIndex = segment[j - 1].index + 1;
68690 memberIndex = Math.min(segment[j - 1].index + 1, segment[j + 1].index + 1);
68696 return graph.replace(relation.addMember(member, memberIndex));
68700 function actionAddMidpoint(midpoint, node) {
68701 return function(graph) {
68702 graph = graph.replace(node.move(midpoint.loc));
68704 var parents = lodash.intersection(
68705 graph.parentWays(graph.entity(midpoint.edge[0])),
68706 graph.parentWays(graph.entity(midpoint.edge[1])));
68708 parents.forEach(function(way) {
68709 for (var i = 0; i < way.nodes.length - 1; i++) {
68710 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
68711 graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
68713 // Add only one midpoint on doubled-back segments,
68714 // turning them into self-intersections.
68724 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
68725 function actionAddVertex(wayId, nodeId, index) {
68726 return function(graph) {
68727 return graph.replace(graph.entity(wayId).addNode(nodeId, index));
68731 function actionChangeMember(relationId, member, memberIndex) {
68732 return function(graph) {
68733 return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
68737 function actionChangePreset(entityId, oldPreset, newPreset) {
68738 return function(graph) {
68739 var entity = graph.entity(entityId),
68740 geometry = entity.geometry(graph),
68741 tags = entity.tags;
68743 if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
68744 if (newPreset) tags = newPreset.applyTags(tags, geometry);
68746 return graph.replace(entity.update({tags: tags}));
68750 function actionChangeTags(entityId, tags) {
68751 return function(graph) {
68752 var entity = graph.entity(entityId);
68753 return graph.replace(entity.update({tags: tags}));
68757 function actionCircularize(wayId, projection, maxAngle) {
68758 maxAngle = (maxAngle || 20) * Math.PI / 180;
68761 var action = function(graph, t) {
68762 if (t === null || !isFinite(t)) t = 1;
68763 t = Math.min(Math.max(+t, 0), 1);
68765 var way = graph.entity(wayId),
68768 graph.childNodes(way).forEach(function(node) {
68769 if (!origNodes[node.id]) origNodes[node.id] = node;
68772 if (!way.isConvex(graph)) {
68773 graph = action.makeConvex(graph);
68776 var nodes = lodash.uniq(graph.childNodes(way)),
68777 keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
68778 points = nodes.map(function(n) { return projection(n.loc); }),
68779 keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
68780 centroid = (points.length === 2) ? geoInterp(points[0], points[1], 0.5) : d3polygonCentroid(points),
68781 radius = median(points, function(p) { return geoEuclideanDistance(centroid, p); }),
68782 sign = d3polygonArea(points) > 0 ? 1 : -1,
68785 // we need atleast two key nodes for the algorithm to work
68786 if (!keyNodes.length) {
68787 keyNodes = [nodes[0]];
68788 keyPoints = [points[0]];
68791 if (keyNodes.length === 1) {
68792 var index = nodes.indexOf(keyNodes[0]),
68793 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
68795 keyNodes.push(nodes[oppositeIndex]);
68796 keyPoints.push(points[oppositeIndex]);
68799 // key points and nodes are those connected to the ways,
68800 // they are projected onto the circle, inbetween nodes are moved
68801 // to constant intervals between key nodes, extra inbetween nodes are
68802 // added if necessary.
68803 for (var i = 0; i < keyPoints.length; i++) {
68804 var nextKeyNodeIndex = (i + 1) % keyNodes.length,
68805 startNode = keyNodes[i],
68806 endNode = keyNodes[nextKeyNodeIndex],
68807 startNodeIndex = nodes.indexOf(startNode),
68808 endNodeIndex = nodes.indexOf(endNode),
68809 numberNewPoints = -1,
68810 indexRange = endNodeIndex - startNodeIndex,
68812 inBetweenNodes = [],
68813 startAngle, endAngle, totalAngle, eachAngle,
68814 angle, loc, node, origNode, j;
68816 if (indexRange < 0) {
68817 indexRange += nodes.length;
68820 // position this key node
68821 var distance = geoEuclideanDistance(centroid, keyPoints[i]);
68822 if (distance === 0) { distance = 1e-4; }
68824 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
68825 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius
68827 loc = projection.invert(keyPoints[i]);
68828 node = keyNodes[i];
68829 origNode = origNodes[node.id];
68830 node = node.move(geoInterp(origNode.loc, loc, t));
68831 graph = graph.replace(node);
68833 // figure out the between delta angle we want to match to
68834 startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
68835 endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
68836 totalAngle = endAngle - startAngle;
68838 // detects looping around -pi/pi
68839 if (totalAngle * sign > 0) {
68840 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
68845 eachAngle = totalAngle / (indexRange + numberNewPoints);
68846 } while (Math.abs(eachAngle) > maxAngle);
68849 // move existing nodes
68850 for (j = 1; j < indexRange; j++) {
68851 angle = startAngle + j * eachAngle;
68852 loc = projection.invert([
68853 centroid[0] + Math.cos(angle) * radius,
68854 centroid[1] + Math.sin(angle) * radius
68857 node = nodes[(j + startNodeIndex) % nodes.length];
68858 origNode = origNodes[node.id];
68859 nearNodes[node.id] = angle;
68861 node = node.move(geoInterp(origNode.loc, loc, t));
68862 graph = graph.replace(node);
68865 // add new inbetween nodes if necessary
68866 for (j = 0; j < numberNewPoints; j++) {
68867 angle = startAngle + (indexRange + j) * eachAngle;
68868 loc = projection.invert([
68869 centroid[0] + Math.cos(angle) * radius,
68870 centroid[1] + Math.sin(angle) * radius
68873 // choose a nearnode to use as the original
68874 var min$$1 = Infinity;
68875 for (var nodeId in nearNodes) {
68876 var nearAngle = nearNodes[nodeId],
68877 dist = Math.abs(nearAngle - angle);
68878 if (dist < min$$1) {
68880 origNode = origNodes[nodeId];
68884 node = osmNode({ loc: geoInterp(origNode.loc, loc, t) });
68885 graph = graph.replace(node);
68887 nodes.splice(endNodeIndex + j, 0, node);
68888 inBetweenNodes.push(node.id);
68891 // Check for other ways that share these keyNodes..
68892 // If keyNodes are adjacent in both ways,
68893 // we can add inBetween nodes to that shared way too..
68894 if (indexRange === 1 && inBetweenNodes.length) {
68895 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
68896 endIndex1 = way.nodes.lastIndexOf(endNode.id),
68897 wayDirection1 = (endIndex1 - startIndex1);
68898 if (wayDirection1 < -1) { wayDirection1 = 1; }
68900 /* eslint-disable no-loop-func */
68901 lodash.each(lodash.without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
68902 if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
68903 var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
68904 endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
68905 wayDirection2 = (endIndex2 - startIndex2),
68906 insertAt = endIndex2;
68907 if (wayDirection2 < -1) { wayDirection2 = 1; }
68909 if (wayDirection1 !== wayDirection2) {
68910 inBetweenNodes.reverse();
68911 insertAt = startIndex2;
68913 for (j = 0; j < inBetweenNodes.length; j++) {
68914 sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
68916 graph = graph.replace(sharedWay);
68919 /* eslint-enable no-loop-func */
68924 // update the way to have all the new nodes
68925 ids = nodes.map(function(n) { return n.id; });
68928 way = way.update({nodes: ids});
68929 graph = graph.replace(way);
68935 action.makeConvex = function(graph) {
68936 var way = graph.entity(wayId),
68937 nodes = lodash.uniq(graph.childNodes(way)),
68938 points = nodes.map(function(n) { return projection(n.loc); }),
68939 sign = d3polygonArea(points) > 0 ? 1 : -1,
68940 hull = d3polygonHull(points);
68942 // D3 convex hulls go counterclockwise..
68948 for (var i = 0; i < hull.length - 1; i++) {
68949 var startIndex = points.indexOf(hull[i]),
68950 endIndex = points.indexOf(hull[i+1]),
68951 indexRange = (endIndex - startIndex);
68953 if (indexRange < 0) {
68954 indexRange += nodes.length;
68957 // move interior nodes to the surface of the convex hull..
68958 for (var j = 1; j < indexRange; j++) {
68959 var point = geoInterp(hull[i], hull[i+1], j / indexRange),
68960 node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
68961 graph = graph.replace(node);
68968 action.disabled = function(graph) {
68969 if (!graph.entity(wayId).isClosed())
68970 return 'not_closed';
68974 action.transitionable = true;
68980 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
68981 function actionDeleteWay(wayId) {
68984 function canDeleteNode(node, graph) {
68985 return !graph.parentWays(node).length &&
68986 !graph.parentRelations(node).length &&
68987 !node.hasInterestingTags();
68991 var action = function(graph) {
68992 var way = graph.entity(wayId);
68994 graph.parentRelations(way)
68995 .forEach(function(parent) {
68996 parent = parent.removeMembersWithID(wayId);
68997 graph = graph.replace(parent);
68999 if (parent.isDegenerate()) {
69000 graph = actionDeleteRelation(parent.id)(graph);
69004 lodash.uniq(way.nodes).forEach(function(nodeId) {
69005 graph = graph.replace(way.removeNode(nodeId));
69007 var node = graph.entity(nodeId);
69008 if (canDeleteNode(node, graph)) {
69009 graph = graph.remove(node);
69013 return graph.remove(way);
69020 function actionDeleteMultiple(ids) {
69022 way: actionDeleteWay,
69023 node: actionDeleteNode,
69024 relation: actionDeleteRelation
69028 var action = function(graph) {
69029 ids.forEach(function(id) {
69030 if (graph.hasEntity(id)) { // It may have been deleted aready.
69031 graph = actions[graph.entity(id).type](id)(graph);
69042 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
69043 function actionDeleteRelation(relationId) {
69046 function canDeleteEntity(entity, graph) {
69047 return !graph.parentWays(entity).length &&
69048 !graph.parentRelations(entity).length &&
69049 !entity.hasInterestingTags();
69053 var action = function(graph) {
69054 var relation = graph.entity(relationId);
69056 graph.parentRelations(relation)
69057 .forEach(function(parent) {
69058 parent = parent.removeMembersWithID(relationId);
69059 graph = graph.replace(parent);
69061 if (parent.isDegenerate()) {
69062 graph = actionDeleteRelation(parent.id)(graph);
69066 lodash.uniq(lodash.map(relation.members, 'id')).forEach(function(memberId) {
69067 graph = graph.replace(relation.removeMembersWithID(memberId));
69069 var entity = graph.entity(memberId);
69070 if (canDeleteEntity(entity, graph)) {
69071 graph = actionDeleteMultiple([memberId])(graph);
69075 return graph.remove(relation);
69082 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
69083 function actionDeleteNode(nodeId) {
69084 var action = function(graph) {
69085 var node = graph.entity(nodeId);
69087 graph.parentWays(node)
69088 .forEach(function(parent) {
69089 parent = parent.removeNode(nodeId);
69090 graph = graph.replace(parent);
69092 if (parent.isDegenerate()) {
69093 graph = actionDeleteWay(parent.id)(graph);
69097 graph.parentRelations(node)
69098 .forEach(function(parent) {
69099 parent = parent.removeMembersWithID(nodeId);
69100 graph = graph.replace(parent);
69102 if (parent.isDegenerate()) {
69103 graph = actionDeleteRelation(parent.id)(graph);
69107 return graph.remove(node);
69114 // Connect the ways at the given nodes.
69116 // The last node will survive. All other nodes will be replaced with
69117 // the surviving node in parent ways, and then removed.
69119 // Tags and relation memberships of of non-surviving nodes are merged
69120 // to the survivor.
69122 // This is the inverse of `iD.actionDisconnect`.
69125 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
69126 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
69128 function actionConnect(nodeIds) {
69129 return function(graph) {
69130 var survivor = graph.entity(lodash.last(nodeIds));
69132 for (var i = 0; i < nodeIds.length - 1; i++) {
69133 var node = graph.entity(nodeIds[i]);
69135 /* eslint-disable no-loop-func */
69136 graph.parentWays(node).forEach(function(parent) {
69137 if (!parent.areAdjacent(node.id, survivor.id)) {
69138 graph = graph.replace(parent.replaceNode(node.id, survivor.id));
69142 graph.parentRelations(node).forEach(function(parent) {
69143 graph = graph.replace(parent.replaceMember(node, survivor));
69145 /* eslint-enable no-loop-func */
69147 survivor = survivor.mergeTags(node.tags);
69148 graph = actionDeleteNode(node.id)(graph);
69151 graph = graph.replace(survivor);
69157 function actionCopyEntities(ids, fromGraph) {
69161 var action = function(graph) {
69162 ids.forEach(function(id) {
69163 fromGraph.entity(id).copy(fromGraph, copies);
69166 for (var id in copies) {
69167 graph = graph.replace(copies[id]);
69174 action.copies = function() {
69182 function actionDeleteMember(relationId, memberIndex) {
69183 return function(graph) {
69184 var relation = graph.entity(relationId)
69185 .removeMember(memberIndex);
69187 graph = graph.replace(relation);
69189 if (relation.isDegenerate())
69190 graph = actionDeleteRelation(relation.id)(graph);
69196 function actionDeprecateTags(entityId) {
69198 return function(graph) {
69199 var entity = graph.entity(entityId),
69200 newtags = lodash.clone(entity.tags),
69204 // This handles dataDeprecated tags with a single condition
69205 for (var i = 0; i < dataDeprecated.length; i++) {
69207 rule = dataDeprecated[i];
69208 var match = lodash.toPairs(rule.old)[0],
69209 replacements = rule.replace ? lodash.toPairs(rule.replace) : null;
69211 if (entity.tags[match[0]] && match[1] === '*') {
69213 var value = entity.tags[match[0]];
69214 if (replacements && !newtags[replacements[0][0]]) {
69215 newtags[replacements[0][0]] = value;
69217 delete newtags[match[0]];
69220 } else if (entity.tags[match[0]] === match[1]) {
69221 newtags = lodash.assign({}, rule.replace || {}, lodash.omit(newtags, match[0]));
69227 return graph.replace(entity.update({tags: newtags}));
69234 function actionDiscardTags(difference) {
69236 return function(graph) {
69237 function discardTags(entity) {
69238 if (!lodash.isEmpty(entity.tags)) {
69240 lodash.each(entity.tags, function(v, k) {
69241 if (v) tags[k] = v;
69244 graph = graph.replace(entity.update({
69245 tags: lodash.omit(tags, dataDiscarded)
69250 difference.modified().forEach(discardTags);
69251 difference.created().forEach(discardTags);
69257 // Disconect the ways at the given node.
69259 // Optionally, disconnect only the given ways.
69261 // For testing convenience, accepts an ID to assign to the (first) new node.
69262 // Normally, this will be undefined and the way will automatically
69263 // be assigned a new ID.
69265 // This is the inverse of `iD.actionConnect`.
69268 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
69269 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
69271 function actionDisconnect(nodeId, newNodeId) {
69275 var action = function(graph) {
69276 var node = graph.entity(nodeId),
69277 connections = action.connections(graph);
69279 connections.forEach(function(connection) {
69280 var way = graph.entity(connection.wayID),
69281 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
69283 graph = graph.replace(newNode);
69284 if (connection.index === 0 && way.isArea()) {
69285 // replace shared node with shared node..
69286 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
69287 } else if (way.isClosed() && connection.index === way.nodes.length - 1) {
69288 // replace closing node with new new node..
69289 graph = graph.replace(way.unclose().addNode(newNode.id));
69291 // replace shared node with multiple new nodes..
69292 graph = graph.replace(way.updateNode(newNode.id, connection.index));
69300 action.connections = function(graph) {
69301 var candidates = [],
69303 parentWays = graph.parentWays(graph.entity(nodeId));
69305 parentWays.forEach(function(way) {
69306 if (wayIds && wayIds.indexOf(way.id) === -1) {
69310 if (way.isArea() && (way.nodes[0] === nodeId)) {
69311 candidates.push({ wayID: way.id, index: 0 });
69313 way.nodes.forEach(function(waynode, index) {
69314 if (waynode === nodeId) {
69315 candidates.push({ wayID: way.id, index: index });
69321 return keeping ? candidates : candidates.slice(1);
69325 action.disabled = function(graph) {
69326 var connections = action.connections(graph);
69327 if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
69328 return 'not_connected';
69330 var parentWays = graph.parentWays(graph.entity(nodeId)),
69331 seenRelationIds = {},
69334 parentWays.forEach(function(way) {
69335 if (wayIds && wayIds.indexOf(way.id) === -1)
69338 var relations = graph.parentRelations(way);
69339 relations.forEach(function(relation) {
69340 if (relation.id in seenRelationIds) {
69341 sharedRelation = relation;
69343 seenRelationIds[relation.id] = true;
69348 if (sharedRelation)
69353 action.limitWays = function(_) {
69354 if (!arguments.length) return wayIds;
69363 // Join ways at the end node they share.
69365 // This is the inverse of `iD.actionSplit`.
69368 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
69369 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
69371 function actionJoin(ids) {
69373 function groupEntitiesByGeometry(graph) {
69374 var entities = ids.map(function(id) { return graph.entity(id); });
69375 return lodash.extend({line: []}, lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
69379 var action = function(graph) {
69380 var ways = ids.map(graph.entity, graph),
69381 survivor = ways[0];
69383 // Prefer to keep an existing way.
69384 for (var i = 0; i < ways.length; i++) {
69385 if (!ways[i].isNew()) {
69386 survivor = ways[i];
69391 var joined = osmJoinWays(ways, graph)[0];
69393 survivor = survivor.update({nodes: lodash.map(joined.nodes, 'id')});
69394 graph = graph.replace(survivor);
69396 joined.forEach(function(way) {
69397 if (way.id === survivor.id)
69400 graph.parentRelations(way).forEach(function(parent) {
69401 graph = graph.replace(parent.replaceMember(way, survivor));
69404 survivor = survivor.mergeTags(way.tags);
69406 graph = graph.replace(survivor);
69407 graph = actionDeleteWay(way.id)(graph);
69414 action.disabled = function(graph) {
69415 var geometries = groupEntitiesByGeometry(graph);
69416 if (ids.length < 2 || ids.length !== geometries.line.length)
69417 return 'not_eligible';
69419 var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
69420 if (joined.length > 1)
69421 return 'not_adjacent';
69423 var nodeIds = lodash.map(joined[0].nodes, 'id').slice(1, -1),
69426 conflicting = false;
69428 joined[0].forEach(function(way) {
69429 var parents = graph.parentRelations(way);
69430 parents.forEach(function(parent) {
69431 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
69435 for (var k in way.tags) {
69436 if (!(k in tags)) {
69437 tags[k] = way.tags[k];
69438 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
69439 conflicting = true;
69445 return 'restriction';
69448 return 'conflicting_tags';
69455 function actionMerge(ids) {
69457 function groupEntitiesByGeometry(graph) {
69458 var entities = ids.map(function(id) { return graph.entity(id); });
69459 return lodash.extend({point: [], area: [], line: [], relation: []},
69460 lodash.groupBy(entities, function(entity) { return entity.geometry(graph); }));
69464 var action = function(graph) {
69465 var geometries = groupEntitiesByGeometry(graph),
69466 target = geometries.area[0] || geometries.line[0],
69467 points = geometries.point;
69469 points.forEach(function(point) {
69470 target = target.mergeTags(point.tags);
69471 graph = graph.replace(target);
69473 graph.parentRelations(point).forEach(function(parent) {
69474 graph = graph.replace(parent.replaceMember(point, target));
69477 var nodes = lodash.uniq(graph.childNodes(target)),
69478 removeNode = point;
69480 for (var i = 0; i < nodes.length; i++) {
69481 var node = nodes[i];
69482 if (graph.parentWays(node).length > 1 ||
69483 graph.parentRelations(node).length ||
69484 node.hasInterestingTags()) {
69488 // Found an uninteresting child node on the target way.
69489 // Move orig point into its place to preserve point's history. #3683
69490 graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
69491 target = target.replaceNode(node.id, point.id);
69492 graph = graph.replace(target);
69497 graph = graph.remove(removeNode);
69504 action.disabled = function(graph) {
69505 var geometries = groupEntitiesByGeometry(graph);
69506 if (geometries.point.length === 0 ||
69507 (geometries.area.length + geometries.line.length) !== 1 ||
69508 geometries.relation.length !== 0)
69509 return 'not_eligible';
69516 function actionMergePolygon(ids, newRelationId) {
69518 function groupEntities(graph) {
69519 var entities = ids.map(function (id) { return graph.entity(id); });
69520 return lodash.extend({
69524 }, lodash.groupBy(entities, function(entity) {
69525 if (entity.type === 'way' && entity.isClosed()) {
69526 return 'closedWay';
69527 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
69528 return 'multipolygon';
69536 var action = function(graph) {
69537 var entities = groupEntities(graph);
69539 // An array representing all the polygons that are part of the multipolygon.
69541 // Each element is itself an array of objects with an id property, and has a
69542 // locs property which is an array of the locations forming the polygon.
69543 var polygons = entities.multipolygon.reduce(function(polygons, m) {
69544 return polygons.concat(osmJoinWays(m.members, graph));
69545 }, []).concat(entities.closedWay.map(function(d) {
69546 var member = [{id: d.id}];
69547 member.nodes = graph.childNodes(d);
69551 // contained is an array of arrays of boolean values,
69552 // where contained[j][k] is true iff the jth way is
69553 // contained by the kth way.
69554 var contained = polygons.map(function(w, i) {
69555 return polygons.map(function(d, n) {
69556 if (i === n) return null;
69557 return geoPolygonContainsPolygon(
69558 lodash.map(d.nodes, 'loc'),
69559 lodash.map(w.nodes, 'loc'));
69563 // Sort all polygons as either outer or inner ways
69567 while (polygons.length) {
69568 extractUncontained(polygons);
69569 polygons = polygons.filter(isContained);
69570 contained = contained.filter(isContained).map(filterContained);
69573 function isContained(d, i) {
69574 return lodash.some(contained[i]);
69577 function filterContained(d) {
69578 return d.filter(isContained);
69581 function extractUncontained(polygons) {
69582 polygons.forEach(function(d, i) {
69583 if (!isContained(d, i)) {
69584 d.forEach(function(member) {
69588 role: outer ? 'outer' : 'inner'
69596 // Move all tags to one relation
69597 var relation = entities.multipolygon[0] ||
69598 osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
69600 entities.multipolygon.slice(1).forEach(function(m) {
69601 relation = relation.mergeTags(m.tags);
69602 graph = graph.remove(m);
69605 entities.closedWay.forEach(function(way) {
69606 function isThisOuter(m) {
69607 return m.id === way.id && m.role !== 'inner';
69609 if (members.some(isThisOuter)) {
69610 relation = relation.mergeTags(way.tags);
69611 graph = graph.replace(way.update({ tags: {} }));
69615 return graph.replace(relation.update({
69617 tags: lodash.omit(relation.tags, 'area')
69622 action.disabled = function(graph) {
69623 var entities = groupEntities(graph);
69624 if (entities.other.length > 0 ||
69625 entities.closedWay.length + entities.multipolygon.length < 2)
69626 return 'not_eligible';
69627 if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
69628 return 'incomplete_relation';
69635 // Copyright (c) 2006, 2008 Tony Garnock-Jones <tonyg@lshift.net>
69636 // Copyright (c) 2006, 2008 LShift Ltd. <query@lshift.net>
69638 // Permission is hereby granted, free of charge, to any person
69639 // obtaining a copy of this software and associated documentation files
69640 // (the "Software"), to deal in the Software without restriction,
69641 // including without limitation the rights to use, copy, modify, merge,
69642 // publish, distribute, sublicense, and/or sell copies of the Software,
69643 // and to permit persons to whom the Software is furnished to do so,
69644 // subject to the following conditions:
69646 // The above copyright notice and this permission notice shall be
69647 // included in all copies or substantial portions of the Software.
69649 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
69650 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
69651 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
69652 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
69653 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
69654 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
69655 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
69658 // source: https://bitbucket.org/lshift/synchrotron/src
69659 function longest_common_subsequence(file1, file2) {
69660 /* Text diff algorithm following Hunt and McIlroy 1976.
69661 * J. W. Hunt and M. D. McIlroy, An algorithm for differential file
69662 * comparison, Bell Telephone Laboratories CSTR #41 (1976)
69663 * http://www.cs.dartmouth.edu/~doug/
69665 * Expects two arrays of strings.
69667 var equivalenceClasses;
69672 var c, i, j, jX, r, s;
69674 equivalenceClasses = {};
69675 for (j = 0; j < file2.length; j++) {
69677 if (equivalenceClasses[line]) {
69678 equivalenceClasses[line].push(j);
69680 equivalenceClasses[line] = [j];
69684 candidates = [{file1index: -1,
69688 for (i = 0; i < file1.length; i++) {
69690 file2indices = equivalenceClasses[line] || [];
69695 for (jX = 0; jX < file2indices.length; jX++) {
69696 j = file2indices[jX];
69698 for (s = 0; s < candidates.length; s++) {
69699 if ((candidates[s].file2index < j) &&
69700 ((s === candidates.length - 1) ||
69701 (candidates[s + 1].file2index > j)))
69705 if (s < candidates.length) {
69706 newCandidate = {file1index: i,
69708 chain: candidates[s]};
69709 if (r === candidates.length) {
69710 candidates.push(c);
69716 if (r === candidates.length) {
69717 break; // no point in examining further (j)s
69725 // At this point, we know the LCS: it's in the reverse of the
69726 // linked-list through .chain of
69727 // candidates[candidates.length - 1].
69729 return candidates[candidates.length - 1];
69742 function diff_indices(file1, file2) {
69743 // We apply the LCS to give a simple representation of the
69744 // offsets and lengths of mismatched chunks in the input
69745 // files. This is used by diff3_merge_indices below.
69748 var tail1 = file1.length;
69749 var tail2 = file2.length;
69751 for (var candidate = longest_common_subsequence(file1, file2);
69752 candidate !== null;
69753 candidate = candidate.chain)
69755 var mismatchLength1 = tail1 - candidate.file1index - 1;
69756 var mismatchLength2 = tail2 - candidate.file2index - 1;
69757 tail1 = candidate.file1index;
69758 tail2 = candidate.file2index;
69760 if (mismatchLength1 || mismatchLength2) {
69761 result.push({file1: [tail1 + 1, mismatchLength1],
69762 file2: [tail2 + 1, mismatchLength2]});
69770 function diff3_merge_indices (a, o, b) {
69771 // Given three files, A, O, and B, where both A and B are
69772 // independently derived from O, returns a fairly complicated
69773 // internal representation of merge decisions it's taken. The
69774 // interested reader may wish to consult
69776 // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. "A
69777 // Formal Investigation of Diff3." In Arvind and Prasad,
69778 // editors, Foundations of Software Technology and Theoretical
69779 // Computer Science (FSTTCS), December 2007.
69781 // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
69784 var m1 = diff_indices(o, a);
69785 var m2 = diff_indices(o, b);
69788 function addHunk(h, side) {
69789 hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
69791 for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
69792 for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
69796 var commonOffset = 0;
69797 function copyCommon(targetOffset) {
69798 if (targetOffset > commonOffset) {
69799 result.push([1, commonOffset, targetOffset - commonOffset]);
69800 commonOffset = targetOffset;
69804 for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
69805 var firstHunkIndex = hunkIndex;
69806 var hunk = hunks[hunkIndex];
69807 var regionLhs = hunk[0];
69808 var regionRhs = regionLhs + hunk[2];
69809 while (hunkIndex < hunks.length - 1) {
69810 var maybeOverlapping = hunks[hunkIndex + 1];
69811 var maybeLhs = maybeOverlapping[0];
69812 if (maybeLhs > regionRhs) break;
69813 regionRhs = maybeLhs + maybeOverlapping[2];
69817 copyCommon(regionLhs);
69818 if (firstHunkIndex === hunkIndex) {
69819 // The "overlap" was only one hunk long, meaning that
69820 // there's no conflict here. Either a and o were the
69821 // same, or b and o were the same.
69823 result.push([hunk[1], hunk[3], hunk[4]]);
69826 // A proper conflict. Determine the extents of the
69827 // regions involved from a, o and b. Effectively merge
69828 // all the hunks on the left into one giant hunk, and
69829 // do the same for the right; then, correct for skew
69830 // in the regions of o that each side changed, and
69831 // report appropriate spans for the three sides.
69833 0: [a.length, -1, o.length, -1],
69834 2: [b.length, -1, o.length, -1]
69836 for (i = firstHunkIndex; i <= hunkIndex; i++) {
69838 var side = hunk[1];
69839 var r = regions[side];
69840 var oLhs = hunk[0];
69841 var oRhs = oLhs + hunk[2];
69842 var abLhs = hunk[3];
69843 var abRhs = abLhs + hunk[4];
69844 r[0] = Math.min(abLhs, r[0]);
69845 r[1] = Math.max(abRhs, r[1]);
69846 r[2] = Math.min(oLhs, r[2]);
69847 r[3] = Math.max(oRhs, r[3]);
69849 var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
69850 var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
69851 var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
69852 var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
69855 regionLhs, regionRhs - regionLhs,
69856 bLhs, bRhs - bLhs]);
69858 commonOffset = regionRhs;
69861 copyCommon(o.length);
69865 function diff3_merge (a, o, b, excludeFalseConflicts) {
69866 // Applies the output of Diff3.diff3_merge_indices to actually
69867 // construct the merged file; the returned result alternates
69868 // between "ok" and "conflict" blocks.
69871 var files = [a, o, b];
69872 var indices = diff3_merge_indices(a, o, b);
69875 function flushOk() {
69876 if (okLines.length) {
69877 result.push({ok: okLines});
69881 function pushOk(xs) {
69882 for (var j = 0; j < xs.length; j++) {
69883 okLines.push(xs[j]);
69887 function isTrueConflict(rec) {
69888 if (rec[2] !== rec[6]) return true;
69891 for (var j = 0; j < rec[2]; j++) {
69892 if (a[j + aoff] !== b[j + boff]) return true;
69897 for (var i = 0; i < indices.length; i++) {
69898 var x = indices[i];
69901 if (excludeFalseConflicts && !isTrueConflict(x)) {
69902 pushOk(files[0].slice(x[1], x[1] + x[2]));
69905 result.push({conflict: {a: a.slice(x[1], x[1] + x[2]),
69907 o: o.slice(x[3], x[3] + x[4]),
69909 b: b.slice(x[5], x[5] + x[6]),
69913 pushOk(files[side].slice(x[1], x[1] + x[2]));
69921 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
69922 var option = 'safe', // 'safe', 'force_local', 'force_remote'
69927 return lodash.isFunction(formatUser) ? formatUser(d) : d;
69931 function mergeLocation(remote, target) {
69932 function pointEqual(a, b) {
69933 var epsilon = 1e-6;
69934 return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
69937 if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
69940 if (option === 'force_remote') {
69941 return target.update({loc: remote.loc});
69944 conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
69949 function mergeNodes(base, remote, target) {
69950 if (option === 'force_local' || lodash.isEqual(target.nodes, remote.nodes)) {
69953 if (option === 'force_remote') {
69954 return target.update({nodes: remote.nodes});
69957 var ccount = conflicts.length,
69958 o = base.nodes || [],
69959 a = target.nodes || [],
69960 b = remote.nodes || [],
69962 hunks = diff3_merge(a, o, b, true);
69964 for (var i = 0; i < hunks.length; i++) {
69965 var hunk = hunks[i];
69967 nodes.push.apply(nodes, hunk.ok);
69969 // for all conflicts, we can assume c.a !== c.b
69970 // because `diff3_merge` called with `true` option to exclude false conflicts..
69971 var c = hunk.conflict;
69972 if (lodash.isEqual(c.o, c.a)) { // only changed remotely
69973 nodes.push.apply(nodes, c.b);
69974 } else if (lodash.isEqual(c.o, c.b)) { // only changed locally
69975 nodes.push.apply(nodes, c.a);
69976 } else { // changed both locally and remotely
69977 conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
69983 return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
69987 function mergeChildren(targetWay, children, updates, graph) {
69988 function isUsed(node, targetWay) {
69989 var parentWays = lodash.map(graph.parentWays(node), 'id');
69990 return node.hasInterestingTags() ||
69991 lodash.without(parentWays, targetWay.id).length > 0 ||
69992 graph.parentRelations(node).length > 0;
69995 var ccount = conflicts.length;
69997 for (var i = 0; i < children.length; i++) {
69998 var id = children[i],
69999 node = graph.hasEntity(id);
70001 // remove unused childNodes..
70002 if (targetWay.nodes.indexOf(id) === -1) {
70003 if (node && !isUsed(node, targetWay)) {
70004 updates.removeIds.push(id);
70009 // restore used childNodes..
70010 var local = localGraph.hasEntity(id),
70011 remote = remoteGraph.hasEntity(id),
70014 if (option === 'force_remote' && remote && remote.visible) {
70015 updates.replacements.push(remote);
70017 } else if (option === 'force_local' && local) {
70018 target = osmEntity$$1(local);
70020 target = target.update({ version: remote.version });
70022 updates.replacements.push(target);
70024 } else if (option === 'safe' && local && remote && local.version !== remote.version) {
70025 target = osmEntity$$1(local, { version: remote.version });
70026 if (remote.visible) {
70027 target = mergeLocation(remote, target);
70029 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
70032 if (conflicts.length !== ccount) break;
70033 updates.replacements.push(target);
70041 function updateChildren(updates, graph) {
70042 for (var i = 0; i < updates.replacements.length; i++) {
70043 graph = graph.replace(updates.replacements[i]);
70045 if (updates.removeIds.length) {
70046 graph = actionDeleteMultiple(updates.removeIds)(graph);
70052 function mergeMembers(remote, target) {
70053 if (option === 'force_local' || lodash.isEqual(target.members, remote.members)) {
70056 if (option === 'force_remote') {
70057 return target.update({members: remote.members});
70060 conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
70065 function mergeTags(base, remote, target) {
70066 function ignoreKey(k) {
70067 return lodash.includes(dataDiscarded, k);
70070 if (option === 'force_local' || lodash.isEqual(target.tags, remote.tags)) {
70073 if (option === 'force_remote') {
70074 return target.update({tags: remote.tags});
70077 var ccount = conflicts.length,
70078 o = base.tags || {},
70079 a = target.tags || {},
70080 b = remote.tags || {},
70081 keys = lodash.reject(lodash.union(lodash.keys(o), lodash.keys(a), lodash.keys(b)), ignoreKey),
70082 tags = lodash.clone(a),
70085 for (var i = 0; i < keys.length; i++) {
70088 if (o[k] !== b[k] && a[k] !== b[k]) { // changed remotely..
70089 if (o[k] !== a[k]) { // changed locally..
70090 conflicts.push(t('merge_remote_changes.conflict.tags',
70091 { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
70093 } else { // unchanged locally, accept remote change..
70094 if (b.hasOwnProperty(k)) {
70104 return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
70108 // `graph.base()` is the common ancestor of the two graphs.
70109 // `localGraph` contains user's edits up to saving
70110 // `remoteGraph` contains remote edits to modified nodes
70111 // `graph` must be a descendent of `localGraph` and may include
70112 // some conflict resolution actions performed on it.
70114 // --- ... --- `localGraph` -- ... -- `graph`
70116 // `graph.base()` --- ... --- `remoteGraph`
70118 var action = function(graph) {
70119 var updates = { replacements: [], removeIds: [] },
70120 base = graph.base().entities[id],
70121 local = localGraph.entity(id),
70122 remote = remoteGraph.entity(id),
70123 target = osmEntity$$1(local, { version: remote.version });
70126 if (!remote.visible) {
70127 if (option === 'force_remote') {
70128 return actionDeleteMultiple([id])(graph);
70130 } else if (option === 'force_local') {
70131 if (target.type === 'way') {
70132 target = mergeChildren(target, lodash.uniq(local.nodes), updates, graph);
70133 graph = updateChildren(updates, graph);
70135 return graph.replace(target);
70138 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
70139 return graph; // do nothing
70144 if (target.type === 'node') {
70145 target = mergeLocation(remote, target);
70147 } else if (target.type === 'way') {
70148 // pull in any child nodes that may not be present locally..
70149 graph.rebase(remoteGraph.childNodes(remote), [graph], false);
70150 target = mergeNodes(base, remote, target);
70151 target = mergeChildren(target, lodash.union(local.nodes, remote.nodes), updates, graph);
70153 } else if (target.type === 'relation') {
70154 target = mergeMembers(remote, target);
70157 target = mergeTags(base, remote, target);
70159 if (!conflicts.length) {
70160 graph = updateChildren(updates, graph).replace(target);
70167 action.withOption = function(opt) {
70173 action.conflicts = function() {
70181 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
70182 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
70183 function actionMove(moveIds, tryDelta, projection, cache) {
70184 var delta = tryDelta;
70186 function vecAdd(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
70187 function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
70189 function setupCache(graph) {
70190 function canMove(nodeId) {
70191 // Allow movement of any node that is in the selectedIDs list..
70192 if (moveIds.indexOf(nodeId) !== -1) return true;
70194 // Allow movement of a vertex where 2 ways meet..
70195 var parents = lodash.map(graph.parentWays(graph.entity(nodeId)), 'id');
70196 if (parents.length < 3) return true;
70198 // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
70199 var parentsMoving = lodash.every(parents, function(id) { return cache.moving[id]; });
70200 if (!parentsMoving) delete cache.moving[nodeId];
70202 return parentsMoving;
70205 function cacheEntities(ids) {
70206 ids.forEach(function(id) {
70207 if (cache.moving[id]) return;
70208 cache.moving[id] = true;
70210 var entity = graph.hasEntity(id);
70211 if (!entity) return;
70213 if (entity.type === 'node') {
70214 cache.nodes.push(id);
70215 cache.startLoc[id] = entity.loc;
70216 } else if (entity.type === 'way') {
70217 cache.ways.push(id);
70218 cacheEntities(entity.nodes);
70220 cacheEntities(entity.members.map(function(member) {
70227 function cacheIntersections(ids) {
70228 function isEndpoint(way, id) { return !way.isClosed() && !!way.affix(id); }
70230 ids.forEach(function(id) {
70231 // consider only intersections with 1 moved and 1 unmoved way.
70232 var childNodes = graph.childNodes(graph.entity(id));
70233 childNodes.forEach(function(node) {
70234 var parents = graph.parentWays(node);
70235 if (parents.length !== 2) return;
70237 var moved = graph.entity(id),
70238 unmoved = lodash.find(parents, function(way) { return !cache.moving[way.id]; });
70239 if (!unmoved) return;
70241 // exclude ways that are overly connected..
70242 if (lodash.intersection(moved.nodes, unmoved.nodes).length > 2) return;
70244 if (moved.isArea() || unmoved.isArea()) return;
70246 cache.intersection[node.id] = {
70249 unmovedId: unmoved.id,
70250 movedIsEP: isEndpoint(moved, node.id),
70251 unmovedIsEP: isEndpoint(unmoved, node.id)
70263 cache.intersection = {};
70264 cache.replacedVertex = {};
70265 cache.startLoc = {};
70269 cacheEntities(moveIds);
70270 cacheIntersections(cache.ways);
70271 cache.nodes = lodash.filter(cache.nodes, canMove);
70278 // Place a vertex where the moved vertex used to be, to preserve way shape..
70279 function replaceMovedVertex(nodeId, wayId, graph, delta) {
70280 var way = graph.entity(wayId),
70281 moved = graph.entity(nodeId),
70282 movedIndex = way.nodes.indexOf(nodeId),
70283 len, prevIndex, nextIndex;
70285 if (way.isClosed()) {
70286 len = way.nodes.length - 1;
70287 prevIndex = (movedIndex + len - 1) % len;
70288 nextIndex = (movedIndex + len + 1) % len;
70290 len = way.nodes.length;
70291 prevIndex = movedIndex - 1;
70292 nextIndex = movedIndex + 1;
70295 var prev = graph.hasEntity(way.nodes[prevIndex]),
70296 next = graph.hasEntity(way.nodes[nextIndex]);
70298 // Don't add orig vertex at endpoint..
70299 if (!prev || !next) return graph;
70301 var key = wayId + '_' + nodeId,
70302 orig = cache.replacedVertex[key];
70305 cache.replacedVertex[key] = orig;
70306 cache.startLoc[orig.id] = cache.startLoc[nodeId];
70311 start = projection(cache.startLoc[nodeId]);
70312 end = projection.invert(vecAdd(start, delta));
70314 end = cache.startLoc[nodeId];
70316 orig = orig.move(end);
70318 var angle = Math.abs(geoAngle(orig, prev, projection) -
70319 geoAngle(orig, next, projection)) * 180 / Math.PI;
70321 // Don't add orig vertex if it would just make a straight line..
70322 if (angle > 175 && angle < 185) return graph;
70324 // Don't add orig vertex if another point is already nearby (within 10m)
70325 if (geoSphericalDistance(prev.loc, orig.loc) < 10 ||
70326 geoSphericalDistance(orig.loc, next.loc) < 10) return graph;
70328 // moving forward or backward along way?
70329 var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
70330 p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
70331 d1 = geoPathLength(p1),
70332 d2 = geoPathLength(p2),
70333 insertAt = (d1 < d2) ? movedIndex : nextIndex;
70335 // moving around closed loop?
70336 if (way.isClosed() && insertAt === 0) insertAt = len;
70338 way = way.addNode(orig.id, insertAt);
70339 return graph.replace(orig).replace(way);
70343 // Reorder nodes around intersections that have moved..
70344 function unZorroIntersection(intersection, graph) {
70345 var vertex = graph.entity(intersection.nodeId),
70346 way1 = graph.entity(intersection.movedId),
70347 way2 = graph.entity(intersection.unmovedId),
70348 isEP1 = intersection.movedIsEP,
70349 isEP2 = intersection.unmovedIsEP;
70351 // don't move the vertex if it is the endpoint of both ways.
70352 if (isEP1 && isEP2) return graph;
70354 var nodes1 = lodash.without(graph.childNodes(way1), vertex),
70355 nodes2 = lodash.without(graph.childNodes(way2), vertex);
70357 if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
70358 if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
70360 var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection),
70361 edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection),
70364 // snap vertex to nearest edge (or some point between them)..
70365 if (!isEP1 && !isEP2) {
70366 var epsilon = 1e-4, maxIter = 10;
70367 for (var i = 0; i < maxIter; i++) {
70368 loc = geoInterp(edge1.loc, edge2.loc, 0.5);
70369 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
70370 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
70371 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
70373 } else if (!isEP1) {
70379 graph = graph.replace(vertex.move(loc));
70381 // if zorro happened, reorder nodes..
70382 if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
70383 way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
70384 graph = graph.replace(way1);
70386 if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
70387 way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
70388 graph = graph.replace(way2);
70395 function cleanupIntersections(graph) {
70396 lodash.each(cache.intersection, function(obj) {
70397 graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, delta);
70398 graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
70399 graph = unZorroIntersection(obj, graph);
70406 // check if moving way endpoint can cross an unmoved way, if so limit delta..
70407 function limitDelta(graph) {
70408 lodash.each(cache.intersection, function(obj) {
70409 // Don't limit movement if this is vertex joins 2 endpoints..
70410 if (obj.movedIsEP && obj.unmovedIsEP) return;
70411 // Don't limit movement if this vertex is not an endpoint anyway..
70412 if (!obj.movedIsEP) return;
70414 var node = graph.entity(obj.nodeId),
70415 start = projection(node.loc),
70416 end = vecAdd(start, delta),
70417 movedNodes = graph.childNodes(graph.entity(obj.movedId)),
70418 movedPath = lodash.map(lodash.map(movedNodes, 'loc'),
70419 function(loc) { return vecAdd(projection(loc), delta); }),
70420 unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)),
70421 unmovedPath = lodash.map(lodash.map(unmovedNodes, 'loc'), projection),
70422 hits = geoPathIntersections(movedPath, unmovedPath);
70424 for (var i = 0; i < hits.length; i++) {
70425 if (lodash.isEqual(hits[i], end)) continue;
70426 var edge = geoChooseEdge(unmovedNodes, end, projection);
70427 delta = vecSub(projection(edge.loc), start);
70433 var action = function(graph) {
70434 if (delta[0] === 0 && delta[1] === 0) return graph;
70438 if (!lodash.isEmpty(cache.intersection)) {
70442 lodash.each(cache.nodes, function(id) {
70443 var node = graph.entity(id),
70444 start = projection(node.loc),
70445 end = vecAdd(start, delta);
70446 graph = graph.replace(node.move(projection.invert(end)));
70449 if (!lodash.isEmpty(cache.intersection)) {
70450 graph = cleanupIntersections(graph);
70457 action.delta = function() {
70465 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
70466 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
70467 function actionMoveNode(nodeId, loc) {
70468 return function(graph) {
70469 return graph.replace(graph.entity(nodeId).move(loc));
70473 function actionNoop() {
70474 return function(graph) {
70480 * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
70482 function actionOrthogonalize(wayId, projection) {
70483 var threshold = 12, // degrees within right or straight to alter
70484 lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
70485 upperThreshold = Math.cos(threshold * Math.PI / 180);
70488 var action = function(graph, t) {
70489 if (t === null || !isFinite(t)) t = 1;
70490 t = Math.min(Math.max(+t, 0), 1);
70492 var way = graph.entity(wayId),
70493 nodes = graph.childNodes(way),
70494 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); }),
70495 corner = {i: 0, dotp: 1},
70497 node, loc, score, motions, i, j;
70499 if (points.length === 3) { // move only one vertex for right triangle
70500 for (i = 0; i < 1000; i++) {
70501 motions = points.map(calcMotion);
70502 points[corner.i] = addPoints(points[corner.i], motions[corner.i]);
70503 score = corner.dotp;
70504 if (score < epsilon) {
70509 node = graph.entity(nodes[corner.i].id);
70510 loc = projection.invert(points[corner.i]);
70511 graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
70515 originalPoints = lodash.clone(points);
70518 for (i = 0; i < 1000; i++) {
70519 motions = points.map(calcMotion);
70520 for (j = 0; j < motions.length; j++) {
70521 points[j] = addPoints(points[j],motions[j]);
70523 var newScore = squareness(points);
70524 if (newScore < score) {
70525 best = lodash.clone(points);
70528 if (score < epsilon) {
70535 for (i = 0; i < points.length; i++) {
70536 // only move the points that actually moved
70537 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
70538 loc = projection.invert(points[i]);
70539 node = graph.entity(nodes[i].id);
70540 graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
70544 // remove empty nodes on straight sections
70545 for (i = 0; t === 1 && i < points.length; i++) {
70546 node = graph.entity(nodes[i].id);
70548 if (graph.parentWays(node).length > 1 ||
70549 graph.parentRelations(node).length ||
70550 node.hasInterestingTags()) {
70554 var dotp = normalizedDotProduct(i, points);
70555 if (dotp < -1 + epsilon) {
70556 graph = actionDeleteNode(node.id)(graph);
70564 function calcMotion(b, i, array) {
70565 var a = array[(i - 1 + array.length) % array.length],
70566 c = array[(i + 1) % array.length],
70567 p = subtractPoints(a, b),
70568 q = subtractPoints(c, b),
70571 scale = 2 * Math.min(geoEuclideanDistance(p, [0, 0]), geoEuclideanDistance(q, [0, 0]));
70572 p = normalizePoint(p, 1.0);
70573 q = normalizePoint(q, 1.0);
70575 dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
70577 // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
70578 if (array.length > 3) {
70579 if (dotp < -0.707106781186547) {
70582 } else if (dotp && Math.abs(dotp) < corner.dotp) {
70584 corner.dotp = Math.abs(dotp);
70587 return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
70592 function squareness(points) {
70593 return points.reduce(function(sum, val, i, array) {
70594 var dotp = normalizedDotProduct(i, array);
70596 dotp = filterDotProduct(dotp);
70597 return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
70602 function normalizedDotProduct(i, points) {
70603 var a = points[(i - 1 + points.length) % points.length],
70605 c = points[(i + 1) % points.length],
70606 p = subtractPoints(a, b),
70607 q = subtractPoints(c, b);
70609 p = normalizePoint(p, 1.0);
70610 q = normalizePoint(q, 1.0);
70612 return p[0] * q[0] + p[1] * q[1];
70616 function subtractPoints(a, b) {
70617 return [a[0] - b[0], a[1] - b[1]];
70621 function addPoints(a, b) {
70622 return [a[0] + b[0], a[1] + b[1]];
70626 function normalizePoint(point, scale) {
70627 var vector = [0, 0];
70628 var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
70629 if (length !== 0) {
70630 vector[0] = point[0] / length;
70631 vector[1] = point[1] / length;
70634 vector[0] *= scale;
70635 vector[1] *= scale;
70641 function filterDotProduct(dotp) {
70642 if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
70650 action.disabled = function(graph) {
70651 var way = graph.entity(wayId),
70652 nodes = graph.childNodes(way),
70653 points = lodash.uniq(nodes).map(function(n) { return projection(n.loc); });
70655 if (squareness(points)) {
70659 return 'not_squarish';
70663 action.transitionable = true;
70669 // Split a way at the given node.
70671 // Optionally, split only the given ways, if multiple ways share
70674 // This is the inverse of `iD.actionJoin`.
70676 // For testing convenience, accepts an ID to assign to the new way.
70677 // Normally, this will be undefined and the way will automatically
70678 // be assigned a new ID.
70681 // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
70683 function actionSplit(nodeId, newWayIds) {
70686 // if the way is closed, we need to search for a partner node
70687 // to split the way at.
70689 // The following looks for a node that is both far away from
70690 // the initial node in terms of way segment length and nearby
70691 // in terms of beeline-distance. This assures that areas get
70692 // split on the most "natural" points (independent of the number
70694 // For example: bone-shaped areas get split across their waist
70695 // line, circles across the diameter.
70696 function splitArea(nodes, idxA, graph) {
70697 var lengths = new Array(nodes.length),
70703 function wrap(index) {
70704 return utilWrap(index, nodes.length);
70707 function dist(nA, nB) {
70708 return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
70711 // calculate lengths
70713 for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
70714 length += dist(nodes[i], nodes[wrap(i-1)]);
70715 lengths[i] = length;
70719 for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
70720 length += dist(nodes[i], nodes[wrap(i+1)]);
70721 if (length < lengths[i])
70722 lengths[i] = length;
70725 // determine best opposite node to split
70726 for (i = 0; i < nodes.length; i++) {
70727 var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
70738 function split(graph, wayA, newWayId) {
70739 var wayB = osmWay({id: newWayId, tags: wayA.tags}),
70742 isArea = wayA.isArea(),
70743 isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
70745 if (wayA.isClosed()) {
70746 var nodes = wayA.nodes.slice(0, -1),
70747 idxA = lodash.indexOf(nodes, nodeId),
70748 idxB = splitArea(nodes, idxA, graph);
70751 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
70752 nodesB = nodes.slice(idxB, idxA + 1);
70754 nodesA = nodes.slice(idxA, idxB + 1);
70755 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
70758 var idx = lodash.indexOf(wayA.nodes, nodeId, 1);
70759 nodesA = wayA.nodes.slice(0, idx + 1);
70760 nodesB = wayA.nodes.slice(idx);
70763 wayA = wayA.update({nodes: nodesA});
70764 wayB = wayB.update({nodes: nodesB});
70766 graph = graph.replace(wayA);
70767 graph = graph.replace(wayB);
70769 graph.parentRelations(wayA).forEach(function(relation) {
70770 if (relation.isRestriction()) {
70771 var via = relation.memberByRole('via');
70772 if (via && wayB.contains(via.id)) {
70773 relation = relation.updateMember({id: wayB.id}, relation.memberById(wayA.id).index);
70774 graph = graph.replace(relation);
70777 if (relation === isOuter) {
70778 graph = graph.replace(relation.mergeTags(wayA.tags));
70779 graph = graph.replace(wayA.update({tags: {}}));
70780 graph = graph.replace(wayB.update({tags: {}}));
70786 role: relation.memberById(wayA.id).role
70789 graph = actionAddMember(relation.id, member)(graph);
70793 if (!isOuter && isArea) {
70794 var multipolygon = osmRelation({
70795 tags: lodash.extend({}, wayA.tags, {type: 'multipolygon'}),
70797 {id: wayA.id, role: 'outer', type: 'way'},
70798 {id: wayB.id, role: 'outer', type: 'way'}
70801 graph = graph.replace(multipolygon);
70802 graph = graph.replace(wayA.update({tags: {}}));
70803 graph = graph.replace(wayB.update({tags: {}}));
70810 var action = function(graph) {
70811 var candidates = action.ways(graph);
70812 for (var i = 0; i < candidates.length; i++) {
70813 graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
70819 action.ways = function(graph) {
70820 var node = graph.entity(nodeId),
70821 parents = graph.parentWays(node),
70822 hasLines = lodash.some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
70824 return parents.filter(function(parent) {
70825 if (wayIds && wayIds.indexOf(parent.id) === -1)
70828 if (!wayIds && hasLines && parent.geometry(graph) !== 'line')
70831 if (parent.isClosed()) {
70835 for (var i = 1; i < parent.nodes.length - 1; i++) {
70836 if (parent.nodes[i] === nodeId) {
70846 action.disabled = function(graph) {
70847 var candidates = action.ways(graph);
70848 if (candidates.length === 0 || (wayIds && wayIds.length !== candidates.length))
70849 return 'not_eligible';
70853 action.limitWays = function(_) {
70854 if (!arguments.length) return wayIds;
70863 // Create a restriction relation for `turn`, which must have the following structure:
70866 // from: { node: <node ID>, way: <way ID> },
70867 // via: { node: <node ID> },
70868 // to: { node: <node ID>, way: <way ID> },
70869 // restriction: <'no_right_turn', 'no_left_turn', etc.>
70872 // This specifies a restriction of type `restriction` when traveling from
70873 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
70874 // (The action does not check that these entities form a valid intersection.)
70876 // If `restriction` is not provided, it is automatically determined by
70877 // osmInferRestriction.
70879 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
70880 // and `to.node` are used to determine which portion of the split ways become
70881 // members of the restriction.
70883 // For testing convenience, accepts an ID to assign to the new relation.
70884 // Normally, this will be undefined and the relation will automatically
70885 // be assigned a new ID.
70887 function actionRestrictTurn(turn, projection, restrictionId) {
70889 return function(graph) {
70890 var from = graph.entity(turn.from.way),
70891 via = graph.entity(turn.via.node),
70892 to = graph.entity(turn.to.way);
70894 function isClosingNode(way, nodeId) {
70895 return nodeId === way.first() && nodeId === way.last();
70898 function split(toOrFrom) {
70899 var newID = toOrFrom.newID || osmWay().id;
70900 graph = actionSplit(via.id, [newID])
70901 .limitWays([toOrFrom.way])(graph);
70903 var a = graph.entity(newID),
70904 b = graph.entity(toOrFrom.way);
70906 if (a.nodes.indexOf(toOrFrom.node) !== -1) {
70913 if (!from.affix(via.id) || isClosingNode(from, via.id)) {
70914 if (turn.from.node === turn.to.node) {
70916 from = to = split(turn.from)[0];
70917 } else if (turn.from.way === turn.to.way) {
70918 // Straight-on or circular
70919 var s = split(turn.from);
70924 from = split(turn.from)[0];
70928 if (!to.affix(via.id) || isClosingNode(to, via.id)) {
70929 to = split(turn.to)[0];
70932 return graph.replace(osmRelation({
70935 type: 'restriction',
70936 restriction: turn.restriction ||
70937 osmInferRestriction(
70945 {id: from.id, type: 'way', role: 'from'},
70946 {id: via.id, type: 'node', role: 'via'},
70947 {id: to.id, type: 'way', role: 'to'}
70953 function actionRevert(id) {
70954 var action = function(graph) {
70955 var entity = graph.hasEntity(id),
70956 base = graph.base().entities[id];
70958 if (entity && !base) { // entity will be removed..
70959 if (entity.type === 'node') {
70960 graph.parentWays(entity)
70961 .forEach(function(parent) {
70962 parent = parent.removeNode(id);
70963 graph = graph.replace(parent);
70965 if (parent.isDegenerate()) {
70966 graph = actionDeleteWay(parent.id)(graph);
70971 graph.parentRelations(entity)
70972 .forEach(function(parent) {
70973 parent = parent.removeMembersWithID(id);
70974 graph = graph.replace(parent);
70976 if (parent.isDegenerate()) {
70977 graph = actionDeleteRelation(parent.id)(graph);
70982 return graph.revert(id);
70988 function actionRotate(rotateIds, pivot, angle, projection) {
70990 var action = function(graph) {
70991 return graph.update(function(graph) {
70992 utilGetAllNodes(rotateIds, graph).forEach(function(node) {
70993 var point = geoRotate([projection(node.loc)], angle, pivot)[0];
70994 graph = graph.replace(node.move(projection.invert(point)));
71003 * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
71005 function actionStraighten(wayId, projection) {
71007 function positionAlongWay(n, s, e) {
71008 return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1])) /
71009 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
71013 var action = function(graph, t) {
71014 if (t === null || !isFinite(t)) t = 1;
71015 t = Math.min(Math.max(+t, 0), 1);
71017 var way = graph.entity(wayId),
71018 nodes = graph.childNodes(way),
71019 points = nodes.map(function(n) { return projection(n.loc); }),
71020 startPoint = points[0],
71021 endPoint = points[points.length-1],
71025 for (i = 1; i < points.length-1; i++) {
71026 var node = nodes[i],
71029 if (t < 1 || graph.parentWays(node).length > 1 ||
71030 graph.parentRelations(node).length ||
71031 node.hasInterestingTags()) {
71033 var u = positionAlongWay(point, startPoint, endPoint),
71035 startPoint[0] + u * (endPoint[0] - startPoint[0]),
71036 startPoint[1] + u * (endPoint[1] - startPoint[1])
71038 loc2 = projection.invert(p);
71040 graph = graph.replace(node.move(geoInterp(node.loc, loc2, t)));
71044 if (toDelete.indexOf(node) === -1) {
71045 toDelete.push(node);
71050 for (i = 0; i < toDelete.length; i++) {
71051 graph = actionDeleteNode(toDelete[i].id)(graph);
71058 action.disabled = function(graph) {
71059 // check way isn't too bendy
71060 var way = graph.entity(wayId),
71061 nodes = graph.childNodes(way),
71062 points = nodes.map(function(n) { return projection(n.loc); }),
71063 startPoint = points[0],
71064 endPoint = points[points.length-1],
71065 threshold = 0.2 * geoEuclideanDistance(startPoint, endPoint),
71068 if (threshold === 0) {
71069 return 'too_bendy';
71072 for (i = 1; i < points.length-1; i++) {
71073 var point = points[i],
71074 u = positionAlongWay(point, startPoint, endPoint),
71075 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
71076 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
71077 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
71079 // to bendy if point is off by 20% of total start/end distance in projected space
71080 if (isNaN(dist) || dist > threshold) {
71081 return 'too_bendy';
71087 action.transitionable = true;
71093 // Remove the effects of `turn.restriction` on `turn`, which must have the
71094 // following structure:
71097 // from: { node: <node ID>, way: <way ID> },
71098 // via: { node: <node ID> },
71099 // to: { node: <node ID>, way: <way ID> },
71100 // restriction: <relation ID>
71103 // In the simple case, `restriction` is a reference to a `no_*` restriction
71104 // on the turn itself. In this case, it is simply deleted.
71106 // The more complex case is where `restriction` references an `only_*`
71107 // restriction on a different turn in the same intersection. In that case,
71108 // that restriction is also deleted, but at the same time restrictions on
71109 // the turns other than the first two are created.
71111 function actionUnrestrictTurn(turn) {
71112 return function(graph) {
71113 return actionDeleteRelation(turn.restriction)(graph);
71117 /* Reflect the given area around its axis of symmetry */
71118 function actionReflect(reflectIds, projection) {
71119 var useLongAxis = true;
71122 // http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points
71123 // http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756
71124 function getSmallestSurroundingRectangle(graph, nodes) {
71125 var points = nodes.map(function(n) { return projection(n.loc); }),
71126 hull = d3polygonHull(points),
71127 centroid = d3polygonCentroid(hull),
71128 minArea = Infinity,
71133 for (var i = 0; i < hull.length - 1; i++) {
71134 var c2 = hull[i + 1],
71135 angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]),
71136 poly = geoRotate(hull, -angle, centroid),
71137 extent$$1 = poly.reduce(function(extent$$1, point) {
71138 return extent$$1.extend(geoExtent$$1(point));
71139 }, geoExtent$$1()),
71140 area$$1 = extent$$1.area();
71142 if (area$$1 < minArea) {
71144 ssrExtent = extent$$1;
71151 poly: geoRotate(ssrExtent.polygon(), ssrAngle, centroid),
71157 var action = function(graph, t) {
71158 if (t === null || !isFinite(t)) t = 1;
71159 t = Math.min(Math.max(+t, 0), 1);
71161 var nodes = utilGetAllNodes(reflectIds, graph),
71162 ssr = getSmallestSurroundingRectangle(graph, nodes);
71164 // Choose line pq = axis of symmetry.
71165 // The shape's surrounding rectangle has 2 axes of symmetry.
71166 // Reflect across the longer axis by default.
71167 var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ],
71168 q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ],
71169 p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ],
71170 q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ],
71173 var isLong = (geoEuclideanDistance(p1, q1) > geoEuclideanDistance(p2, q2));
71174 if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) {
71182 // reflect c across pq
71183 // http://math.stackexchange.com/questions/65503/point-reflection-over-a-line
71184 var dx = q[0] - p[0];
71185 var dy = q[1] - p[1];
71186 var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
71187 var b = 2 * dx * dy / (dx * dx + dy * dy);
71188 for (var i = 0; i < nodes.length; i++) {
71189 var node = nodes[i];
71190 var c = projection(node.loc);
71192 a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
71193 b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
71195 var loc2 = projection.invert(c2);
71196 node = node.move(geoInterp(node.loc, loc2, t));
71197 graph = graph.replace(node);
71204 action.useLongAxis = function(_) {
71205 if (!arguments.length) return useLongAxis;
71211 action.transitionable = true;
71219 var index$17 = Object.freeze({
71220 d3combobox: d3combobox,
71221 d3geoTile: d3geoTile,
71222 d3keybinding: d3keybinding
71225 /* export some legacy symbols: */
71226 var Connection = services.osm;
71232 var iD = Object.freeze({
71233 Connection: Connection,
71237 Context: coreContext,
71238 setAreaKeys: setAreaKeys,
71239 Difference: coreDifference,
71240 Graph: coreGraph$$1,
71241 History: coreHistory,
71243 Entity: osmEntity$$1,
71245 Relation: osmRelation,
71247 BackgroundSource: rendererBackgroundSource,
71248 Background: rendererBackground,
71249 Features: rendererFeatures,
71251 TileLayer: rendererTileLayer,
71252 Detect: utilDetect,
71253 actionAddEntity: actionAddEntity,
71254 actionAddMember: actionAddMember,
71255 actionAddMidpoint: actionAddMidpoint,
71256 actionAddVertex: actionAddVertex,
71257 actionChangeMember: actionChangeMember,
71258 actionChangePreset: actionChangePreset,
71259 actionChangeTags: actionChangeTags,
71260 actionCircularize: actionCircularize,
71261 actionConnect: actionConnect,
71262 actionCopyEntities: actionCopyEntities,
71263 actionDeleteMember: actionDeleteMember,
71264 actionDeleteMultiple: actionDeleteMultiple,
71265 actionDeleteNode: actionDeleteNode,
71266 actionDeleteRelation: actionDeleteRelation,
71267 actionDeleteWay: actionDeleteWay,
71268 actionDeprecateTags: actionDeprecateTags,
71269 actionDiscardTags: actionDiscardTags,
71270 actionDisconnect: actionDisconnect,
71271 actionJoin: actionJoin,
71272 actionMerge: actionMerge,
71273 actionMergePolygon: actionMergePolygon,
71274 actionMergeRemoteChanges: actionMergeRemoteChanges,
71275 actionMove: actionMove,
71276 actionMoveNode: actionMoveNode,
71277 actionNoop: actionNoop,
71278 actionOrthogonalize: actionOrthogonalize,
71279 actionRestrictTurn: actionRestrictTurn,
71280 actionReverse: actionReverse,
71281 actionRevert: actionRevert,
71282 actionRotate: actionRotate,
71283 actionSplit: actionSplit,
71284 actionStraighten: actionStraighten,
71285 actionUnrestrictTurn: actionUnrestrictTurn,
71286 actionReflect: actionReflect,
71287 behaviorAddWay: behaviorAddWay,
71288 behaviorBreathe: behaviorBreathe,
71289 behaviorCopy: behaviorCopy,
71290 behaviorDrag: behaviorDrag,
71291 behaviorDrawWay: behaviorDrawWay,
71292 behaviorDraw: behaviorDraw,
71293 behaviorEdit: behaviorEdit,
71294 behaviorHash: behaviorHash,
71295 behaviorHover: behaviorHover,
71296 behaviorLasso: behaviorLasso,
71297 behaviorOperation: behaviorOperation,
71298 behaviorPaste: behaviorPaste,
71299 behaviorSelect: behaviorSelect,
71300 behaviorTail: behaviorTail,
71301 coreContext: coreContext,
71302 coreDifference: coreDifference,
71303 coreGraph: coreGraph$$1,
71304 coreHistory: coreHistory,
71305 coreTree: coreTree,
71306 dataFeatureIcons: dataFeatureIcons,
71308 dataWikipedia: dataWikipedia,
71309 dataSuggestions: dataSuggestions,
71310 dataAddressFormats: dataAddressFormats,
71311 dataDeprecated: dataDeprecated,
71312 dataDiscarded: dataDiscarded,
71313 dataLocales: dataLocales,
71314 dataPhoneFormats: dataPhoneFormats,
71315 dataImperial: dataImperial,
71316 dataDriveLeft: dataDriveLeft,
71318 geoAngle: geoAngle,
71319 geoChooseEdge: geoChooseEdge,
71320 geoCross: geoCross,
71321 geoEdgeEqual: geoEdgeEqual,
71322 geoEuclideanDistance: geoEuclideanDistance,
71323 geoExtent: geoExtent$$1,
71324 geoInterp: geoInterp,
71325 geoRawMercator: geoRawMercator,
71326 geoRoundCoords: geoRoundCoords,
71327 geoRotate: geoRotate,
71328 geoLatToMeters: geoLatToMeters,
71329 geoLineIntersection: geoLineIntersection,
71330 geoLonToMeters: geoLonToMeters,
71331 geoMetersToLat: geoMetersToLat,
71332 geoMetersToLon: geoMetersToLon,
71333 geoMetersToOffset: geoMetersToOffset,
71334 geoOffsetToMeters: geoOffsetToMeters,
71335 geoPathIntersections: geoPathIntersections,
71336 geoPathLength: geoPathLength,
71337 geoPointInPolygon: geoPointInPolygon,
71338 geoPolygonContainsPolygon: geoPolygonContainsPolygon,
71339 geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
71340 geoSphericalDistance: geoSphericalDistance,
71341 modeAddArea: modeAddArea$$1,
71342 modeAddLine: modeAddLine$$1,
71343 modeAddPoint: modeAddPoint$$1,
71344 modeBrowse: modeBrowse,
71345 modeDragNode: modeDragNode$$1,
71346 modeDrawArea: modeDrawArea,
71347 modeDrawLine: modeDrawLine,
71348 modeMove: modeMove$$1,
71349 modeRotate: modeRotate$$1,
71350 modeSave: modeSave$$1,
71351 modeSelect: modeSelect,
71352 operationCircularize: operationCircularize,
71353 operationContinue: operationContinue,
71354 operationDelete: operationDelete,
71355 operationDisconnect: operationDisconnect,
71356 operationMerge: operationMerge,
71357 operationMove: operationMove,
71358 operationOrthogonalize: operationOrthogonalize,
71359 operationReflectShort: operationReflectShort,
71360 operationReflectLong: operationReflectLong,
71361 operationReverse: operationReverse,
71362 operationRotate: operationRotate,
71363 operationSplit: operationSplit,
71364 operationStraighten: operationStraighten,
71365 osmEntity: osmEntity$$1,
71367 osmRelation: osmRelation,
71369 osmIntersection: osmIntersection,
71371 osmInferRestriction: osmInferRestriction,
71372 osmLanes: osmLanes,
71373 osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
71374 osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
71375 osmJoinWays: osmJoinWays,
71376 osmOneWayTags: osmOneWayTags,
71377 osmPavedTags: osmPavedTags,
71378 osmIsInterestingTag: osmIsInterestingTag,
71379 presetCategory: presetCategory,
71380 presetCollection: presetCollection,
71381 presetField: presetField,
71382 presetPreset: presetPreset,
71383 presetIndex: presetIndex,
71384 rendererBackgroundSource: rendererBackgroundSource,
71385 rendererBackground: rendererBackground,
71386 rendererFeatures: rendererFeatures,
71387 rendererMap: rendererMap,
71388 rendererTileLayer: rendererTileLayer,
71389 services: services,
71390 svgAreas: svgAreas$$1,
71391 svgDebug: svgDebug,
71395 svgLabels: svgLabels,
71396 svgLayers: svgLayers,
71397 svgLines: svgLines$$1,
71398 svgMapillaryImages: svgMapillaryImages,
71399 svgMapillarySigns: svgMapillarySigns,
71400 svgMidpoints: svgMidpoints$$1,
71401 svgOneWaySegments: svgOneWaySegments,
71404 svgPointTransform: svgPointTransform,
71405 svgPoints: svgPoints$$1,
71406 svgRelationMemberTags: svgRelationMemberTags,
71407 svgTagClasses: svgTagClasses,
71408 svgTurns: svgTurns,
71409 svgVertices: svgVertices$$1,
71410 uiFields: uiFields,
71411 uiFieldDefaultcheck: uiFieldCheck,
71412 uiFieldCheck: uiFieldCheck,
71413 uiFieldTypeCombo: uiFieldCombo,
71414 uiFieldMultiCombo: uiFieldCombo,
71415 uiFieldNetworkCombo: uiFieldCombo,
71416 uiFieldCombo: uiFieldCombo,
71417 uiFieldUrl: uiFieldText,
71418 uiFieldNumber: uiFieldText,
71419 uiFieldTel: uiFieldText,
71420 uiFieldEmail: uiFieldText,
71421 uiFieldText: uiFieldText,
71422 uiFieldAccess: uiFieldAccess,
71423 uiFieldAddress: uiFieldAddress,
71424 uiFieldCycleway: uiFieldCycleway,
71425 uiFieldLanes: uiFieldLanes,
71426 uiFieldLocalized: uiFieldLocalized,
71427 uiFieldMaxspeed: uiFieldMaxspeed,
71428 uiFieldRadio: uiFieldRadio,
71429 uiFieldRestrictions: uiFieldRestrictions,
71430 uiFieldTextarea: uiFieldTextarea,
71431 uiFieldWikipedia: uiFieldWikipedia,
71434 uiAccount: uiAccount,
71435 uiAttribution: uiAttribution,
71436 uiBackground: uiBackground,
71438 uiCommit: uiCommit,
71439 uiConfirm: uiConfirm,
71440 uiConflicts: uiConflicts,
71441 uiContributors: uiContributors,
71442 uiDisclosure: uiDisclosure,
71443 uiEntityEditor: uiEntityEditor,
71444 uiFeatureInfo: uiFeatureInfo,
71445 uiFeatureList: uiFeatureList,
71447 uiFullScreen: uiFullScreen,
71448 uiGeolocate: uiGeolocate,
71451 uiInspector: uiInspector,
71453 uiLoading: uiLoading,
71454 uiMapData: uiMapData,
71455 uiMapInMap: uiMapInMap,
71458 uiNotice: uiNotice,
71459 uiPreset: uiPreset,
71460 uiPresetIcon: uiPresetIcon,
71461 uiPresetList: uiPresetList,
71462 uiRadialMenu: uiRadialMenu,
71463 uiRawMemberEditor: uiRawMemberEditor,
71464 uiRawMembershipEditor: uiRawMembershipEditor,
71465 uiRawTagEditor: uiRawTagEditor,
71466 uiRestore: uiRestore,
71469 uiSelectionList: uiSelectionList,
71470 uiSidebar: uiSidebar,
71471 uiSourceSwitch: uiSourceSwitch,
71472 uiSpinner: uiSpinner,
71473 uiSplash: uiSplash,
71474 uiStatus: uiStatus,
71475 uiSuccess: uiSuccess,
71476 uiTagReference: uiTagReference,
71477 uiToggle: uiToggle,
71478 uiTooltipHtml: uiTooltipHtml,
71479 uiUndoRedo: uiUndoRedo,
71480 uiViewOnOSM: uiViewOnOSM,
71482 utilAsyncMap: utilAsyncMap,
71483 utilDisplayName: utilDisplayName,
71484 utilDisplayNameForPath: utilDisplayNameForPath,
71485 utilDisplayType: utilDisplayType,
71486 utilEditDistance: utilEditDistance,
71487 utilEntitySelector: utilEntitySelector,
71488 utilEntityOrMemberSelector: utilEntityOrMemberSelector,
71489 utilFastMouse: utilFastMouse,
71490 utilFunctor: utilFunctor,
71491 utilGetAllNodes: utilGetAllNodes,
71492 utilGetPrototypeOf: utilGetPrototypeOf,
71493 utilGetSetValue: utilGetSetValue,
71494 utilNoAuto: utilNoAuto,
71495 utilPrefixCSSProperty: utilPrefixCSSProperty,
71496 utilPrefixDOMProperty: utilPrefixDOMProperty,
71497 utilQsString: utilQsString,
71498 utilRebind: utilRebind,
71499 utilSetTransform: utilSetTransform,
71500 utilSessionMutex: utilSessionMutex,
71501 utilStringQs: utilStringQs,
71502 utilSuggestNames: utilSuggestNames,
71503 utilTagText: utilTagText,
71504 utilTriggerEvent: utilTriggerEvent,
71505 utilWrap: utilWrap,
71506 d3combobox: d3combobox,
71507 d3geoTile: d3geoTile,
71508 d3keybinding: d3keybinding,
71509 validationDeprecatedTag: validationDeprecatedTag,
71510 validationDisconnectedHighway: validationDisconnectedHighway,
71511 validationManyDeletions: validationManyDeletions,
71512 validationMissingTag: validationMissingTag,
71513 validationTagSuggestsArea: validationTagSuggestsArea
71519 //# sourceMappingURL=iD.js.map